From 38928667ee07af0c22a165cfd679d2bad6114a6f Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 6 Mar 2018 13:53:46 +0000 Subject: [PATCH] Remove most of the code, statically link lib into converter program * The converter program will be able to open old captures, but is itself captureable in new renderdoc builds. This isn't a direct conversion but should allow a reasonable estimation and is better than nothing. * NOTE: The resulting converted file will have no thumbnail, and no callstacks (if they were present before). As well as more minor things like backbuffers no longer appearing identified as backbuffers, some markers losing their colours, etc. --- qrenderdoc/3rdparty/flowlayout/FlowLayout.cpp | 219 - qrenderdoc/3rdparty/flowlayout/FlowLayout.h | 81 - .../3rdparty/scintilla/.hg_archival.txt | 6 - qrenderdoc/3rdparty/scintilla/License.txt | 20 - qrenderdoc/3rdparty/scintilla/README | 88 - .../3rdparty/scintilla/include/ILexer.h | 100 - .../3rdparty/scintilla/include/Platform.h | 529 -- .../3rdparty/scintilla/include/SciLexer.h | 1812 ---- .../3rdparty/scintilla/include/Sci_Position.h | 21 - .../3rdparty/scintilla/include/Scintilla.h | 1208 --- .../scintilla/include/ScintillaWidget.h | 72 - .../scintilla/include/qt/ScintillaDocument.h | 109 - .../scintilla/include/qt/ScintillaEdit.h | 766 -- .../scintilla/include/qt/ScintillaEditBase.h | 156 - .../3rdparty/scintilla/lexers/LexCPP.cxx | 1640 ---- .../3rdparty/scintilla/lexers/LexDiff.cxx | 153 - .../scintilla/lexers/LexErrorList.cxx | 394 - .../3rdparty/scintilla/lexers/LexHTML.cxx | 2203 ----- .../3rdparty/scintilla/lexers/LexJSON.cxx | 499 - .../3rdparty/scintilla/lexers/LexNull.cxx | 40 - .../3rdparty/scintilla/lexers/LexPython.cxx | 746 -- .../3rdparty/scintilla/lexers/LexRust.cxx | 838 -- .../3rdparty/scintilla/lexlib/Accessor.cxx | 79 - .../3rdparty/scintilla/lexlib/Accessor.h | 35 - .../scintilla/lexlib/CharacterCategory.cxx | 3304 ------- .../scintilla/lexlib/CharacterCategory.h | 31 - .../scintilla/lexlib/CharacterSet.cxx | 61 - .../3rdparty/scintilla/lexlib/CharacterSet.h | 184 - .../3rdparty/scintilla/lexlib/LexAccessor.h | 204 - .../3rdparty/scintilla/lexlib/LexerBase.cxx | 92 - .../3rdparty/scintilla/lexlib/LexerBase.h | 41 - .../3rdparty/scintilla/lexlib/LexerModule.cxx | 111 - .../3rdparty/scintilla/lexlib/LexerModule.h | 82 - .../scintilla/lexlib/LexerNoExceptions.cxx | 68 - .../scintilla/lexlib/LexerNoExceptions.h | 32 - .../3rdparty/scintilla/lexlib/LexerSimple.cxx | 57 - .../3rdparty/scintilla/lexlib/LexerSimple.h | 30 - .../3rdparty/scintilla/lexlib/OptionSet.h | 142 - .../scintilla/lexlib/PropSetSimple.cxx | 156 - .../3rdparty/scintilla/lexlib/PropSetSimple.h | 32 - .../3rdparty/scintilla/lexlib/SparseState.h | 110 - .../3rdparty/scintilla/lexlib/StringCopy.h | 36 - .../scintilla/lexlib/StyleContext.cxx | 73 - .../3rdparty/scintilla/lexlib/StyleContext.h | 210 - .../3rdparty/scintilla/lexlib/SubStyles.h | 178 - .../3rdparty/scintilla/lexlib/WordList.cxx | 302 - .../3rdparty/scintilla/lexlib/WordList.h | 42 - qrenderdoc/3rdparty/scintilla/qt/README | 36 - .../qt/ScintillaEdit/ScintillaDocument.cpp | 305 - .../qt/ScintillaEdit/ScintillaDocument.h | 109 - .../qt/ScintillaEdit/ScintillaEdit.cpp | 2840 ------ .../qt/ScintillaEdit/ScintillaEdit.h | 766 -- .../scintilla/qt/ScintillaEditBase/PlatQt.cpp | 1339 --- .../scintilla/qt/ScintillaEditBase/PlatQt.h | 132 - .../ScintillaEditBase/ScintillaEditBase.cpp | 793 -- .../qt/ScintillaEditBase/ScintillaEditBase.h | 156 - .../qt/ScintillaEditBase/ScintillaQt.cpp | 766 -- .../qt/ScintillaEditBase/ScintillaQt.h | 172 - .../3rdparty/scintilla/src/AutoComplete.cxx | 296 - .../3rdparty/scintilla/src/AutoComplete.h | 95 - qrenderdoc/3rdparty/scintilla/src/CallTip.cxx | 336 - qrenderdoc/3rdparty/scintilla/src/CallTip.h | 93 - .../3rdparty/scintilla/src/CaseConvert.cxx | 644 -- .../3rdparty/scintilla/src/CaseConvert.h | 50 - .../3rdparty/scintilla/src/CaseFolder.cxx | 69 - .../3rdparty/scintilla/src/CaseFolder.h | 45 - .../3rdparty/scintilla/src/Catalogue.cxx | 95 - qrenderdoc/3rdparty/scintilla/src/Catalogue.h | 26 - .../3rdparty/scintilla/src/CellBuffer.cxx | 842 -- .../3rdparty/scintilla/src/CellBuffer.h | 216 - .../3rdparty/scintilla/src/CharClassify.cxx | 61 - .../3rdparty/scintilla/src/CharClassify.h | 35 - .../scintilla/src/ContractionState.cxx | 316 - .../3rdparty/scintilla/src/ContractionState.h | 77 - .../3rdparty/scintilla/src/Decoration.cxx | 198 - .../3rdparty/scintilla/src/Decoration.h | 64 - .../3rdparty/scintilla/src/Document.cxx | 3081 ------- qrenderdoc/3rdparty/scintilla/src/Document.h | 551 -- .../3rdparty/scintilla/src/EditModel.cxx | 79 - qrenderdoc/3rdparty/scintilla/src/EditModel.h | 71 - .../3rdparty/scintilla/src/EditView.cxx | 2311 ----- qrenderdoc/3rdparty/scintilla/src/EditView.h | 180 - qrenderdoc/3rdparty/scintilla/src/Editor.cxx | 8154 ----------------- qrenderdoc/3rdparty/scintilla/src/Editor.h | 642 -- .../3rdparty/scintilla/src/ExternalLexer.cxx | 192 - .../3rdparty/scintilla/src/ExternalLexer.h | 92 - .../3rdparty/scintilla/src/FontQuality.h | 31 - .../3rdparty/scintilla/src/Indicator.cxx | 194 - qrenderdoc/3rdparty/scintilla/src/Indicator.h | 60 - qrenderdoc/3rdparty/scintilla/src/KeyMap.cxx | 161 - qrenderdoc/3rdparty/scintilla/src/KeyMap.h | 67 - .../3rdparty/scintilla/src/LineMarker.cxx | 399 - .../3rdparty/scintilla/src/LineMarker.h | 86 - .../3rdparty/scintilla/src/MarginView.cxx | 474 - .../3rdparty/scintilla/src/MarginView.h | 50 - .../3rdparty/scintilla/src/Partitioning.h | 198 - qrenderdoc/3rdparty/scintilla/src/PerLine.cxx | 558 -- qrenderdoc/3rdparty/scintilla/src/PerLine.h | 136 - qrenderdoc/3rdparty/scintilla/src/Position.h | 29 - .../3rdparty/scintilla/src/PositionCache.cxx | 710 -- .../3rdparty/scintilla/src/PositionCache.h | 228 - .../3rdparty/scintilla/src/RESearch.cxx | 962 -- qrenderdoc/3rdparty/scintilla/src/RESearch.h | 73 - .../3rdparty/scintilla/src/RunStyles.cxx | 289 - qrenderdoc/3rdparty/scintilla/src/RunStyles.h | 54 - .../3rdparty/scintilla/src/ScintillaBase.cxx | 1088 --- .../3rdparty/scintilla/src/ScintillaBase.h | 106 - .../3rdparty/scintilla/src/Selection.cxx | 436 - qrenderdoc/3rdparty/scintilla/src/Selection.h | 196 - .../3rdparty/scintilla/src/SparseVector.h | 186 - .../3rdparty/scintilla/src/SplitVector.h | 296 - qrenderdoc/3rdparty/scintilla/src/Style.cxx | 169 - qrenderdoc/3rdparty/scintilla/src/Style.h | 91 - .../3rdparty/scintilla/src/UniConversion.cxx | 309 - .../3rdparty/scintilla/src/UniConversion.h | 72 - .../3rdparty/scintilla/src/UnicodeFromUTF8.h | 32 - .../3rdparty/scintilla/src/ViewStyle.cxx | 623 -- qrenderdoc/3rdparty/scintilla/src/ViewStyle.h | 219 - qrenderdoc/3rdparty/scintilla/src/XPM.cxx | 304 - qrenderdoc/3rdparty/scintilla/src/XPM.h | 94 - qrenderdoc/3rdparty/scintilla/version.txt | 1 - qrenderdoc/3rdparty/toolwindowmanager/LICENSE | 21 - .../3rdparty/toolwindowmanager/README.md | 36 - .../toolwindowmanager/ToolWindowManager.cpp | 1235 --- .../toolwindowmanager/ToolWindowManager.h | 350 - .../ToolWindowManagerArea.cpp | 338 - .../toolwindowmanager/ToolWindowManagerArea.h | 123 - .../ToolWindowManagerSplitter.cpp | 72 - .../ToolWindowManagerSplitter.h | 47 - .../ToolWindowManagerTabBar.cpp | 388 - .../ToolWindowManagerTabBar.h | 102 - .../ToolWindowManagerWrapper.cpp | 480 - .../ToolWindowManagerWrapper.h | 111 - qrenderdoc/CMakeLists.txt | 239 - qrenderdoc/Code/CaptureContext.cpp | 1008 -- qrenderdoc/Code/CaptureContext.h | 284 - qrenderdoc/Code/FormatElement.cpp | 938 -- .../Code/Interface/CommonPipelineState.cpp | 1351 --- .../Code/Interface/CommonPipelineState.h | 435 - .../Code/Interface/PersistantConfig.cpp | 340 - qrenderdoc/Code/Interface/PersistantConfig.h | 469 - qrenderdoc/Code/Interface/QRDInterface.cpp | 133 - qrenderdoc/Code/Interface/QRDInterface.h | 1430 --- qrenderdoc/Code/Interface/RemoteHost.cpp | 121 - qrenderdoc/Code/Interface/RemoteHost.h | 70 - qrenderdoc/Code/QRDUtils.cpp | 1087 --- qrenderdoc/Code/QRDUtils.h | 896 -- qrenderdoc/Code/ReplayManager.cpp | 482 - qrenderdoc/Code/ReplayManager.h | 128 - qrenderdoc/Code/Resources.cpp | 82 - qrenderdoc/Code/Resources.h | 145 - qrenderdoc/Code/ScintillaSyntax.cpp | 294 - qrenderdoc/Code/ScintillaSyntax.h | 34 - qrenderdoc/Code/precompiled.cpp | 25 - qrenderdoc/Code/precompiled.h | 29 - qrenderdoc/Code/pyrenderdoc/CMakeLists.txt | 95 - qrenderdoc/Code/pyrenderdoc/PythonContext.cpp | 861 -- qrenderdoc/Code/pyrenderdoc/PythonContext.h | 174 - qrenderdoc/Code/pyrenderdoc/document_check.h | 186 - qrenderdoc/Code/pyrenderdoc/pyconversion.h | 1043 --- qrenderdoc/Code/pyrenderdoc/pyconversion.i | 95 - .../pyrenderdoc/pyrenderdoc_module.vcxproj | 248 - .../pyrenderdoc_module.vcxproj.filters | 10 - .../Code/pyrenderdoc/pyrenderdoc_stub.cpp | 43 - qrenderdoc/Code/pyrenderdoc/qrenderdoc.i | 142 - .../pyrenderdoc/qrenderdoc_module.vcxproj | 263 - .../qrenderdoc_module.vcxproj.filters | 42 - .../Code/pyrenderdoc/qrenderdoc_stub.cpp | 54 - qrenderdoc/Code/pyrenderdoc/renderdoc.i | 166 - qrenderdoc/Code/qprocessinfo.cpp | 376 - qrenderdoc/Code/qprocessinfo.h | 36 - qrenderdoc/Code/qrenderdoc.cpp | 240 - qrenderdoc/FindPySide2.cmake | 27 - qrenderdoc/README.md | 10 - qrenderdoc/Resources/README.md | 14 - qrenderdoc/Resources/action.png | Bin 450 -> 0 bytes qrenderdoc/Resources/action@2x.png | Bin 675 -> 0 bytes qrenderdoc/Resources/action_hover.png | Bin 461 -> 0 bytes qrenderdoc/Resources/action_hover@2x.png | Bin 685 -> 0 bytes qrenderdoc/Resources/add.png | Bin 698 -> 0 bytes qrenderdoc/Resources/add@2x.png | Bin 1815 -> 0 bytes qrenderdoc/Resources/arrow_in.png | Bin 593 -> 0 bytes qrenderdoc/Resources/arrow_in@2x.png | Bin 1187 -> 0 bytes qrenderdoc/Resources/arrow_join.png | Bin 556 -> 0 bytes qrenderdoc/Resources/arrow_join@2x.png | Bin 1339 -> 0 bytes qrenderdoc/Resources/arrow_left.png | Bin 371 -> 0 bytes qrenderdoc/Resources/arrow_left@2x.png | Bin 570 -> 0 bytes qrenderdoc/Resources/arrow_out.png | Bin 632 -> 0 bytes qrenderdoc/Resources/arrow_out@2x.png | Bin 1147 -> 0 bytes qrenderdoc/Resources/arrow_right.png | Bin 363 -> 0 bytes qrenderdoc/Resources/arrow_right@2x.png | Bin 577 -> 0 bytes qrenderdoc/Resources/arrow_undo.png | Bin 673 -> 0 bytes qrenderdoc/Resources/arrow_undo@2x.png | Bin 1579 -> 0 bytes qrenderdoc/Resources/asterisk_orange.png | Bin 923 -> 0 bytes qrenderdoc/Resources/asterisk_orange@2x.png | Bin 2182 -> 0 bytes qrenderdoc/Resources/chart_curve.png | Bin 759 -> 0 bytes qrenderdoc/Resources/chart_curve@2x.png | Bin 2196 -> 0 bytes qrenderdoc/Resources/checkerboard.png | Bin 558 -> 0 bytes qrenderdoc/Resources/checkerboard@2x.png | Bin 1349 -> 0 bytes qrenderdoc/Resources/cog.png | Bin 777 -> 0 bytes qrenderdoc/Resources/cog@2x.png | Bin 2104 -> 0 bytes qrenderdoc/Resources/color_wheel.png | Bin 850 -> 0 bytes qrenderdoc/Resources/color_wheel@2x.png | Bin 2476 -> 0 bytes qrenderdoc/Resources/connect.png | Bin 621 -> 0 bytes qrenderdoc/Resources/connect@2x.png | Bin 1562 -> 0 bytes qrenderdoc/Resources/control_base_blue.png | Bin 713 -> 0 bytes qrenderdoc/Resources/control_base_blue@2x.png | Bin 2178 -> 0 bytes qrenderdoc/Resources/control_cursor_blue.png | Bin 1613 -> 0 bytes .../Resources/control_cursor_blue@2x.png | Bin 3160 -> 0 bytes qrenderdoc/Resources/control_end_blue.png | Bin 741 -> 0 bytes qrenderdoc/Resources/control_end_blue@2x.png | Bin 2146 -> 0 bytes qrenderdoc/Resources/control_nan_blue.png | Bin 694 -> 0 bytes qrenderdoc/Resources/control_nan_blue@2x.png | Bin 2361 -> 0 bytes qrenderdoc/Resources/control_play_blue.png | Bin 742 -> 0 bytes qrenderdoc/Resources/control_play_blue@2x.png | Bin 1971 -> 0 bytes qrenderdoc/Resources/control_reverse_blue.png | Bin 751 -> 0 bytes .../Resources/control_reverse_blue@2x.png | Bin 1952 -> 0 bytes qrenderdoc/Resources/control_sample_blue.png | Bin 710 -> 0 bytes .../Resources/control_sample_blue@2x.png | Bin 2177 -> 0 bytes qrenderdoc/Resources/control_start_blue.png | Bin 741 -> 0 bytes .../Resources/control_start_blue@2x.png | Bin 2148 -> 0 bytes qrenderdoc/Resources/cross.png | Bin 473 -> 0 bytes qrenderdoc/Resources/cross@2x.png | Bin 1049 -> 0 bytes qrenderdoc/Resources/del.png | Bin 695 -> 0 bytes qrenderdoc/Resources/del@2x.png | Bin 1886 -> 0 bytes qrenderdoc/Resources/disconnect.png | Bin 661 -> 0 bytes qrenderdoc/Resources/disconnect@2x.png | Bin 1275 -> 0 bytes qrenderdoc/Resources/find.png | Bin 720 -> 0 bytes qrenderdoc/Resources/find@2x.png | Bin 1390 -> 0 bytes qrenderdoc/Resources/flag_green.png | Bin 587 -> 0 bytes qrenderdoc/Resources/flag_green@2x.png | Bin 1165 -> 0 bytes qrenderdoc/Resources/flip_y.png | Bin 444 -> 0 bytes qrenderdoc/Resources/flip_y@2x.png | Bin 694 -> 0 bytes qrenderdoc/Resources/folder.png | Bin 632 -> 0 bytes qrenderdoc/Resources/folder@2x.png | Bin 1086 -> 0 bytes qrenderdoc/Resources/folder_page_white.png | Bin 722 -> 0 bytes qrenderdoc/Resources/folder_page_white@2x.png | Bin 1290 -> 0 bytes qrenderdoc/Resources/glsl.xml | 104 - qrenderdoc/Resources/hlsl.xml | 118 - qrenderdoc/Resources/hourglass.png | Bin 788 -> 0 bytes qrenderdoc/Resources/hourglass@2x.png | Bin 2012 -> 0 bytes qrenderdoc/Resources/house.png | Bin 727 -> 0 bytes qrenderdoc/Resources/house@2x.png | Bin 1722 -> 0 bytes qrenderdoc/Resources/information.png | Bin 764 -> 0 bytes qrenderdoc/Resources/information@2x.png | Bin 2112 -> 0 bytes qrenderdoc/Resources/logo.svg | 7 - qrenderdoc/Resources/page_white_code.png | Bin 662 -> 0 bytes qrenderdoc/Resources/page_white_code@2x.png | Bin 1149 -> 0 bytes qrenderdoc/Resources/page_white_database.png | Bin 606 -> 0 bytes .../Resources/page_white_database@2x.png | Bin 1256 -> 0 bytes qrenderdoc/Resources/page_white_delete.png | Bin 640 -> 0 bytes qrenderdoc/Resources/page_white_delete@2x.png | Bin 1255 -> 0 bytes qrenderdoc/Resources/page_white_edit.png | Bin 719 -> 0 bytes qrenderdoc/Resources/page_white_edit@2x.png | Bin 1292 -> 0 bytes qrenderdoc/Resources/page_white_link.png | Bin 732 -> 0 bytes qrenderdoc/Resources/page_white_link@2x.png | Bin 1359 -> 0 bytes qrenderdoc/Resources/plugin_add.png | Bin 758 -> 0 bytes qrenderdoc/Resources/plugin_add@2x.png | Bin 1919 -> 0 bytes qrenderdoc/Resources/qrenderdoc.rc | 129 - qrenderdoc/Resources/qt.conf | 2 - qrenderdoc/Resources/qtconf.qrc | 5 - qrenderdoc/Resources/resource.h | 20 - qrenderdoc/Resources/resources.qrc | 115 - qrenderdoc/Resources/save.png | Bin 730 -> 0 bytes qrenderdoc/Resources/save@2x.png | Bin 1555 -> 0 bytes qrenderdoc/Resources/tick.png | Bin 451 -> 0 bytes qrenderdoc/Resources/tick@2x.png | Bin 896 -> 0 bytes qrenderdoc/Resources/time.png | Bin 812 -> 0 bytes qrenderdoc/Resources/time@2x.png | Bin 2191 -> 0 bytes qrenderdoc/Resources/timeline_marker.png | Bin 503 -> 0 bytes qrenderdoc/Resources/timeline_marker@2x.png | Bin 812 -> 0 bytes .../Resources/topologies/topo_linelist.svg | 1 - .../topologies/topo_linelist_adj.svg | 1 - .../Resources/topologies/topo_linestrip.svg | 1 - .../topologies/topo_linestrip_adj.svg | 1 - .../Resources/topologies/topo_patch.svg | 1 - .../Resources/topologies/topo_pointlist.svg | 1 - .../Resources/topologies/topo_trilist.svg | 1 - .../Resources/topologies/topo_trilist_adj.svg | 1 - .../Resources/topologies/topo_tristrip.svg | 1 - .../topologies/topo_tristrip_adj.svg | 1 - qrenderdoc/Resources/upfolder.png | Bin 729 -> 0 bytes qrenderdoc/Resources/upfolder@2x.png | Bin 1496 -> 0 bytes qrenderdoc/Resources/wand.png | Bin 736 -> 0 bytes qrenderdoc/Resources/wand@2x.png | Bin 1396 -> 0 bytes qrenderdoc/Resources/wireframe_mesh.png | Bin 6012 -> 0 bytes qrenderdoc/Resources/wireframe_mesh@2x.png | Bin 11899 -> 0 bytes qrenderdoc/Resources/wrench.png | Bin 660 -> 0 bytes qrenderdoc/Resources/wrench@2x.png | Bin 1347 -> 0 bytes qrenderdoc/Resources/zoom.png | Bin 784 -> 0 bytes qrenderdoc/Resources/zoom@2x.png | Bin 1872 -> 0 bytes qrenderdoc/Styles/RDStyle/RDStyle.cpp | 1862 ---- qrenderdoc/Styles/RDStyle/RDStyle.h | 98 - .../RDTweakedNativeStyle.cpp | 302 - .../RDTweakedNativeStyle.h | 54 - qrenderdoc/Widgets/BufferFormatSpecifier.cpp | 91 - qrenderdoc/Widgets/BufferFormatSpecifier.h | 56 - qrenderdoc/Widgets/BufferFormatSpecifier.ui | 182 - qrenderdoc/Widgets/CustomPaintWidget.cpp | 116 - qrenderdoc/Widgets/CustomPaintWidget.h | 81 - .../Widgets/Extended/RDDoubleSpinBox.cpp | 39 - qrenderdoc/Widgets/Extended/RDDoubleSpinBox.h | 42 - qrenderdoc/Widgets/Extended/RDHeaderView.cpp | 942 -- qrenderdoc/Widgets/Extended/RDHeaderView.h | 135 - qrenderdoc/Widgets/Extended/RDLabel.cpp | 121 - qrenderdoc/Widgets/Extended/RDLabel.h | 59 - qrenderdoc/Widgets/Extended/RDLineEdit.cpp | 51 - qrenderdoc/Widgets/Extended/RDLineEdit.h | 47 - qrenderdoc/Widgets/Extended/RDListView.cpp | 47 - qrenderdoc/Widgets/Extended/RDListView.h | 45 - qrenderdoc/Widgets/Extended/RDListWidget.cpp | 75 - qrenderdoc/Widgets/Extended/RDListWidget.h | 52 - qrenderdoc/Widgets/Extended/RDSplitter.cpp | 203 - qrenderdoc/Widgets/Extended/RDSplitter.h | 78 - qrenderdoc/Widgets/Extended/RDTableView.cpp | 419 - qrenderdoc/Widgets/Extended/RDTableView.h | 70 - qrenderdoc/Widgets/Extended/RDTableWidget.cpp | 86 - qrenderdoc/Widgets/Extended/RDTableWidget.h | 42 - qrenderdoc/Widgets/Extended/RDTextEdit.cpp | 65 - qrenderdoc/Widgets/Extended/RDTextEdit.h | 47 - qrenderdoc/Widgets/Extended/RDToolButton.cpp | 55 - qrenderdoc/Widgets/Extended/RDToolButton.h | 47 - qrenderdoc/Widgets/Extended/RDTreeView.cpp | 309 - qrenderdoc/Widgets/Extended/RDTreeView.h | 105 - qrenderdoc/Widgets/Extended/RDTreeWidget.cpp | 824 -- qrenderdoc/Widgets/Extended/RDTreeWidget.h | 252 - qrenderdoc/Widgets/FindReplace.cpp | 194 - qrenderdoc/Widgets/FindReplace.h | 94 - qrenderdoc/Widgets/FindReplace.ui | 335 - qrenderdoc/Widgets/PipelineFlowChart.cpp | 314 - qrenderdoc/Widgets/PipelineFlowChart.h | 88 - qrenderdoc/Widgets/RangeHistogram.cpp | 337 - qrenderdoc/Widgets/RangeHistogram.h | 94 - qrenderdoc/Widgets/ResourcePreview.cpp | 125 - qrenderdoc/Widgets/ResourcePreview.h | 79 - qrenderdoc/Widgets/ResourcePreview.ui | 123 - qrenderdoc/Widgets/TextureGoto.cpp | 118 - qrenderdoc/Widgets/TextureGoto.h | 51 - qrenderdoc/Widgets/ThumbnailStrip.cpp | 175 - qrenderdoc/Widgets/ThumbnailStrip.h | 64 - qrenderdoc/Widgets/ThumbnailStrip.ui | 74 - qrenderdoc/Windows/APIInspector.cpp | 166 - qrenderdoc/Windows/APIInspector.h | 60 - qrenderdoc/Windows/APIInspector.ui | 98 - qrenderdoc/Windows/BufferViewer.cpp | 3344 ------- qrenderdoc/Windows/BufferViewer.h | 253 - qrenderdoc/Windows/BufferViewer.ui | 870 -- .../Windows/ConstantBufferPreviewer.cpp | 383 - qrenderdoc/Windows/ConstantBufferPreviewer.h | 93 - qrenderdoc/Windows/ConstantBufferPreviewer.ui | 229 - qrenderdoc/Windows/DebugMessageView.cpp | 387 - qrenderdoc/Windows/DebugMessageView.h | 81 - qrenderdoc/Windows/DebugMessageView.ui | 49 - qrenderdoc/Windows/Dialogs/AboutDialog.cpp | 64 - qrenderdoc/Windows/Dialogs/AboutDialog.h | 43 - qrenderdoc/Windows/Dialogs/AboutDialog.ui | 321 - qrenderdoc/Windows/Dialogs/CaptureDialog.cpp | 1058 --- qrenderdoc/Windows/Dialogs/CaptureDialog.h | 119 - qrenderdoc/Windows/Dialogs/CaptureDialog.ui | 792 -- .../Windows/Dialogs/EnvironmentEditor.cpp | 274 - .../Windows/Dialogs/EnvironmentEditor.h | 63 - .../Windows/Dialogs/EnvironmentEditor.ui | 219 - qrenderdoc/Windows/Dialogs/LiveCapture.cpp | 1155 --- qrenderdoc/Windows/Dialogs/LiveCapture.h | 177 - qrenderdoc/Windows/Dialogs/LiveCapture.ui | 419 - .../Windows/Dialogs/OrderedListEditor.cpp | 208 - .../Windows/Dialogs/OrderedListEditor.h | 69 - .../Windows/Dialogs/OrderedListEditor.ui | 102 - qrenderdoc/Windows/Dialogs/RemoteManager.cpp | 674 -- qrenderdoc/Windows/Dialogs/RemoteManager.h | 96 - qrenderdoc/Windows/Dialogs/RemoteManager.ui | 191 - qrenderdoc/Windows/Dialogs/SettingsDialog.cpp | 380 - qrenderdoc/Windows/Dialogs/SettingsDialog.h | 98 - qrenderdoc/Windows/Dialogs/SettingsDialog.ui | 941 -- .../Windows/Dialogs/SuggestRemoteDialog.cpp | 106 - .../Windows/Dialogs/SuggestRemoteDialog.h | 72 - .../Windows/Dialogs/SuggestRemoteDialog.ui | 148 - .../Windows/Dialogs/TextureSaveDialog.cpp | 648 -- .../Windows/Dialogs/TextureSaveDialog.h | 86 - .../Windows/Dialogs/TextureSaveDialog.ui | 385 - qrenderdoc/Windows/Dialogs/TipsDialog.cpp | 343 - qrenderdoc/Windows/Dialogs/TipsDialog.h | 72 - qrenderdoc/Windows/Dialogs/TipsDialog.ui | 271 - .../Windows/Dialogs/VirtualFileDialog.cpp | 828 -- .../Windows/Dialogs/VirtualFileDialog.h | 83 - .../Windows/Dialogs/VirtualFileDialog.ui | 269 - qrenderdoc/Windows/EventBrowser.cpp | 1221 --- qrenderdoc/Windows/EventBrowser.h | 145 - qrenderdoc/Windows/EventBrowser.ui | 517 -- qrenderdoc/Windows/MainWindow.cpp | 1821 ---- qrenderdoc/Windows/MainWindow.h | 194 - qrenderdoc/Windows/MainWindow.ui | 421 - .../D3D11PipelineStateViewer.cpp | 3133 ------- .../PipelineState/D3D11PipelineStateViewer.h | 122 - .../PipelineState/D3D11PipelineStateViewer.ui | 4312 --------- .../D3D12PipelineStateViewer.cpp | 3060 ------- .../PipelineState/D3D12PipelineStateViewer.h | 120 - .../PipelineState/D3D12PipelineStateViewer.ui | 4108 --------- .../PipelineState/GLPipelineStateViewer.cpp | 3320 ------- .../PipelineState/GLPipelineStateViewer.h | 118 - .../PipelineState/GLPipelineStateViewer.ui | 4553 --------- .../PipelineState/PipelineStateViewer.cpp | 913 -- .../PipelineState/PipelineStateViewer.h | 105 - .../PipelineState/PipelineStateViewer.ui | 36 - .../VulkanPipelineStateViewer.cpp | 3268 ------- .../PipelineState/VulkanPipelineStateViewer.h | 135 - .../VulkanPipelineStateViewer.ui | 3329 ------- qrenderdoc/Windows/PixelHistoryView.cpp | 785 -- qrenderdoc/Windows/PixelHistoryView.h | 78 - qrenderdoc/Windows/PixelHistoryView.ui | 109 - qrenderdoc/Windows/PythonShell.cpp | 682 -- qrenderdoc/Windows/PythonShell.h | 87 - qrenderdoc/Windows/PythonShell.ui | 315 - qrenderdoc/Windows/ShaderViewer.cpp | 2448 ----- qrenderdoc/Windows/ShaderViewer.h | 237 - qrenderdoc/Windows/ShaderViewer.ui | 521 -- qrenderdoc/Windows/StatisticsViewer.cpp | 835 -- qrenderdoc/Windows/StatisticsViewer.h | 73 - qrenderdoc/Windows/StatisticsViewer.ui | 43 - qrenderdoc/Windows/TextureViewer.cpp | 3816 -------- qrenderdoc/Windows/TextureViewer.h | 320 - qrenderdoc/Windows/TextureViewer.ui | 1305 --- qrenderdoc/Windows/TimelineBar.cpp | 971 -- qrenderdoc/Windows/TimelineBar.h | 115 - qrenderdoc/qrenderdoc.pro | 354 - qrenderdoc/qrenderdoc_local.vcxproj | 1636 ---- qrenderdoc/qrenderdoc_local.vcxproj.filters | 1443 --- .../share/application-x-renderdoc-capture.svg | 7 - qrenderdoc/share/magic | 7 - qrenderdoc/share/menu | 6 - qrenderdoc/share/renderdoc-capture.xml | 10 - qrenderdoc/share/renderdoc-icon-16x16.xpm | 63 - qrenderdoc/share/renderdoc-icon-32x32.xpm | 93 - qrenderdoc/share/renderdoc.desktop | 13 - qrenderdoc/share/renderdoc.thumbnailer | 4 - qrenderdoc/va_stdafx.h | 5 - renderdoc.sln | 115 +- renderdoc/CMakeLists.txt | 2 +- renderdoc/api/replay/basic_types.h | 6 - renderdoc/api/replay/renderdoc_replay.h | 17 +- renderdoc/core/core.cpp | 132 + renderdoc/core/core.h | 3 + renderdoc/core/crash_handler.h | 125 +- renderdoc/data/renderdoc.rc | 75 - renderdoc/data/resource.h | 78 +- renderdoc/driver/d3d11/d3d11_context.cpp | 3 +- renderdoc/driver/d3d11/d3d11_device.cpp | 6 + renderdoc/driver/d3d11/d3d11_replay.cpp | 26 +- renderdoc/driver/d3d12/d3d12_device.cpp | 6 + renderdoc/driver/gl/gl_driver.cpp | 6 + renderdoc/driver/gl/gl_replay.cpp | 4 +- renderdoc/driver/vulkan/vk_core.cpp | 8 + renderdoc/driver/vulkan/vk_replay.cpp | 6 +- renderdoc/os/posix/posix_libentry.cpp | 68 +- renderdoc/os/win32/win32_libentry.cpp | 60 +- renderdoc/renderdoc.vcxproj | 5 +- renderdoc/replay/entry_points.cpp | 10 - renderdoccmd/3rdparty/cmdline/cmdline.h | 829 -- renderdoccmd/CMakeLists.txt | 22 +- .../Resources => renderdoccmd}/icon.ico | Bin renderdoccmd/renderdoccmd.cpp | 912 +- renderdoccmd/renderdoccmd.h | 36 +- renderdoccmd/renderdoccmd.rc | Bin 10288 -> 14998 bytes renderdoccmd/renderdoccmd.vcxproj | 31 +- renderdoccmd/renderdoccmd.vcxproj.filters | 12 - renderdoccmd/renderdoccmd_linux.cpp | 426 +- renderdoccmd/renderdoccmd_win32.cpp | 857 +- renderdoccmd/resource.h | Bin 2324 -> 1832 bytes renderdocshim/renderdocshim.cpp | 177 - renderdocshim/renderdocshim.h | 41 - renderdocshim/renderdocshim.vcxproj | 203 - renderdocshim/renderdocshim.vcxproj.filters | 9 - renderdocui/3rdparty/ScintillaNET/License.txt | 21 - .../3rdparty/ScintillaNET/SciLexer.dll | Bin 648704 -> 0 bytes .../3rdparty/ScintillaNET/SciLexer64.dll | Bin 908800 -> 0 bytes .../3rdparty/ScintillaNET/ScintillaNET.dll | Bin 582144 -> 0 bytes .../3rdparty/ScintillaNET/ScintillaNET.pdb | Bin 1181184 -> 0 bytes .../3rdparty/ScintillaNET/ScintillaNET.xml | 4556 --------- .../WinFormsUI/Docking/AutoHideStripBase.cs | 540 -- .../WinFormsUI/Docking/DockAreasEditor.cs | 142 - .../WinFormsUI/Docking/DockContent.cs | 374 - .../Docking/DockContentCollection.cs | 175 - .../Docking/DockContentEventArgs.cs | 19 - .../WinFormsUI/Docking/DockContentHandler.cs | 1146 --- .../WinFormsUI/Docking/DockOutlineBase.cs | 161 - .../Docking/DockPane.SplitterControl.cs | 157 - .../3rdparty/WinFormsUI/Docking/DockPane.cs | 1317 --- .../WinFormsUI/Docking/DockPaneCaptionBase.cs | 100 - .../WinFormsUI/Docking/DockPaneCollection.cs | 47 - .../WinFormsUI/Docking/DockPaneStripBase.cs | 265 - .../Docking/DockPanel.Appearance.cs | 35 - .../Docking/DockPanel.AutoHideWindow.cs | 634 -- .../Docking/DockPanel.DockDragHandler.cs | 816 -- .../Docking/DockPanel.DragHandler.cs | 136 - .../Docking/DockPanel.FocusManager.cs | 595 -- .../Docking/DockPanel.MdiClientController.cs | 438 - .../WinFormsUI/Docking/DockPanel.Persistor.cs | 801 -- .../Docking/DockPanel.SplitterDragHandler.cs | 165 - .../3rdparty/WinFormsUI/Docking/DockPanel.bmp | Bin 822 -> 0 bytes .../3rdparty/WinFormsUI/Docking/DockPanel.cs | 1121 --- .../WinFormsUI/Docking/DockPanelExtender.cs | 225 - .../WinFormsUI/Docking/DockPanelSkin.cs | 371 - .../Docking/DockWindow.SplitterControl.cs | 28 - .../3rdparty/WinFormsUI/Docking/DockWindow.cs | 243 - .../Docking/DockWindowCollection.cs | 38 - .../3rdparty/WinFormsUI/Docking/DragForm.cs | 69 - .../WinFormsUI/Docking/DummyControl.cs | 13 - .../3rdparty/WinFormsUI/Docking/Enums.cs | 60 - .../WinFormsUI/Docking/FloatWindow.cs | 482 - .../Docking/FloatWindowCollection.cs | 42 - .../WinFormsUI/Docking/Helpers/DockHelper.cs | 105 - .../WinFormsUI/Docking/Helpers/DrawHelper.cs | 88 - .../Docking/Helpers/ResourceHelper.cs | 29 - .../WinFormsUI/Docking/Helpers/Win32Helper.cs | 23 - .../WinFormsUI/Docking/InertButtonBase.cs | 115 - .../3rdparty/WinFormsUI/Docking/Interfaces.cs | 47 - .../WinFormsUI/Docking/Localization.cs | 46 - .../3rdparty/WinFormsUI/Docking/Measures.cs | 14 - .../WinFormsUI/Docking/NestedDockingStatus.cs | 108 - .../Docking/NestedPaneCollection.cs | 171 - .../WinFormsUI/Docking/Resources.Designer.cs | 224 - .../WinFormsUI/Docking/Resources.resx | 190 - .../Resources/DockIndicator_PaneDiamond.bmp | Bin 23286 -> 0 bytes .../DockIndicator_PaneDiamond_Bottom.bmp | Bin 23286 -> 0 bytes .../DockIndicator_PaneDiamond_Hotspot.bmp | Bin 23286 -> 0 bytes ...DockIndicator_PaneDiamond_HotspotIndex.bmp | Bin 90 -> 0 bytes .../DockIndicator_PaneDiamond_Left.bmp | Bin 23286 -> 0 bytes .../DockIndicator_PaneDiamond_Right.bmp | Bin 23286 -> 0 bytes .../DockIndicator_PaneDiamond_Top.bmp | Bin 23286 -> 0 bytes .../Resources/DockIndicator_PanelBottom.bmp | Bin 2782 -> 0 bytes .../DockIndicator_PanelBottom_Active.bmp | Bin 2782 -> 0 bytes .../Resources/DockIndicator_PanelFill.bmp | Bin 3030 -> 0 bytes .../DockIndicator_PanelFill_Active.bmp | Bin 3030 -> 0 bytes .../Resources/DockIndicator_PanelLeft.bmp | Bin 2839 -> 0 bytes .../DockIndicator_PanelLeft_Active.bmp | Bin 2839 -> 0 bytes .../Resources/DockIndicator_PanelRight.bmp | Bin 2839 -> 0 bytes .../DockIndicator_PanelRight_Active.bmp | Bin 2839 -> 0 bytes .../Resources/DockIndicator_PanelTop.bmp | Bin 2870 -> 0 bytes .../DockIndicator_PanelTop_Active.bmp | Bin 2870 -> 0 bytes .../Docking/Resources/DockPane_AutoHide.bmp | Bin 774 -> 0 bytes .../Docking/Resources/DockPane_Close.bmp | Bin 774 -> 0 bytes .../Docking/Resources/DockPane_Dock.bmp | Bin 774 -> 0 bytes .../Docking/Resources/DockPane_Option.bmp | Bin 774 -> 0 bytes .../Resources/DockPane_OptionOverflow.bmp | Bin 774 -> 0 bytes .../Dockindicator_PaneDiamond_Fill.bmp | Bin 23286 -> 0 bytes .../Docking/Skins/DockPanelSkinBuilder.cs | 57 - .../WinFormsUI/Docking/Skins/Style.cs | 7 - .../WinFormsUI/Docking/SplitterBase.cs | 70 - .../WinFormsUI/Docking/Strings.Designer.cs | 819 -- .../3rdparty/WinFormsUI/Docking/Strings.resx | 372 - .../WinFormsUI/Docking/VS2005AutoHideStrip.cs | 529 -- .../Docking/VS2005DockPaneCaption.cs | 480 - .../WinFormsUI/Docking/VS2005DockPaneStrip.cs | 1498 --- .../Docking/VisibleNestedPaneCollection.cs | 168 - .../WinFormsUI/Docking/Win32/Enums.cs | 370 - .../WinFormsUI/Docking/Win32/NativeMethods.cs | 61 - .../WinFormsUI/Properties/AssemblyInfo.cs | 28 - .../3rdparty/WinFormsUI/WinFormsUI.csproj | 212 - .../3rdparty/WinFormsUI/dockpanelsuite.snk | Bin 596 -> 0 bytes renderdocui/3rdparty/WinFormsUI/license.txt | 9 - .../ironpython/IronPython.Modules.dll | Bin 732160 -> 0 bytes .../ironpython/IronPython.Modules.xml | 4510 --------- .../3rdparty/ironpython/IronPython.dll | Bin 1810944 -> 0 bytes .../3rdparty/ironpython/IronPython.xml | 7569 --------------- renderdocui/3rdparty/ironpython/LICENSE.md | 69 - .../3rdparty/ironpython/Microsoft.Dynamic.dll | Bin 1044480 -> 0 bytes .../3rdparty/ironpython/Microsoft.Dynamic.xml | 6534 ------------- .../ironpython/Microsoft.Scripting.dll | Bin 144384 -> 0 bytes .../ironpython/Microsoft.Scripting.xml | 3812 -------- renderdocui/3rdparty/ironpython/README.md | 5 - .../3rdparty/ironpython/compilelibs.sh | 12 - renderdocui/Code/AppMain.cs | 319 - renderdocui/Code/Cameras.cs | 329 - renderdocui/Code/CommonPipelineState.cs | 1514 --- renderdocui/Code/Core.cs | 947 -- renderdocui/Code/FormatElement.cs | 745 -- renderdocui/Code/Helpers.cs | 498 - renderdocui/Code/LogViewerForm.cs | 46 - renderdocui/Code/PersistantConfig.cs | 436 - renderdocui/Code/RenderManager.cs | 691 -- renderdocui/Code/Win32PInvoke.cs | 158 - .../BufferFormatSpecifier.Designer.cs | 156 - renderdocui/Controls/BufferFormatSpecifier.cs | 113 - .../Controls/BufferFormatSpecifier.resx | 132 - .../Controls/DoubleClickSplitter.Designer.cs | 37 - renderdocui/Controls/DoubleClickSplitter.cs | 235 - renderdocui/Controls/NoscrollPanel.cs | 98 - .../Controls/PipelineFlowchart.Designer.cs | 47 - renderdocui/Controls/PipelineFlowchart.cs | 388 - renderdocui/Controls/PipelineFlowchart.resx | 120 - .../Controls/RangeHistogram.Designer.cs | 72 - renderdocui/Controls/RangeHistogram.cs | 533 -- renderdocui/Controls/RangeHistogram.resx | 126 - .../Controls/ResourcePreview.Designer.cs | 131 - renderdocui/Controls/ResourcePreview.cs | 177 - renderdocui/Controls/ResourcePreview.resx | 120 - renderdocui/Controls/TablessControl.cs | 51 - renderdocui/Controls/TextureListBox.cs | 234 - .../Controls/ThumbnailStrip.Designer.cs | 106 - renderdocui/Controls/ThumbnailStrip.cs | 229 - renderdocui/Controls/ThumbnailStrip.resx | 123 - .../Controls/ToolStripSpringTextBox.cs | 115 - renderdocui/Controls/TreeListView/LICENSE.htm | 251 - renderdocui/Controls/TreeListView/README.txt | 7 - .../TreeListView/TreeListColumn.Design.cs | 184 - .../Controls/TreeListView/TreeListColumn.cs | 624 -- .../Controls/TreeListView/TreeListNode.cs | 1139 --- .../Controls/TreeListView/TreeListOptions.cs | 347 - .../Controls/TreeListView/TreeListPainter.cs | 446 - .../Controls/TreeListView/TreeListView.cs | 1560 ---- renderdocui/Interop/Camera.cs | 144 - renderdocui/Interop/CaptureOptions.cs | 84 - renderdocui/Interop/CustomMarshaling.cs | 631 -- renderdocui/Interop/D3D11PipelineState.cs | 357 - renderdocui/Interop/D3D12PipelineState.cs | 381 - renderdocui/Interop/Enums.cs | 1052 --- renderdocui/Interop/FetchInfo.cs | 913 -- renderdocui/Interop/Formatter.cs | 162 - renderdocui/Interop/GLPipelineState.cs | 408 - renderdocui/Interop/ReplayRenderer.cs | 1277 --- renderdocui/Interop/Shader.cs | 516 -- renderdocui/Interop/StaticExports.cs | 440 - renderdocui/Interop/VulkanPipelineState.cs | 443 - renderdocui/Plugins/PluginHelpers.cs | 92 - renderdocui/Plugins/ReplayManagerPlugin.cs | 39 - renderdocui/Properties/AssemblyInfo.cs | 67 - renderdocui/Properties/Resources.Designer.cs | 703 -- renderdocui/Properties/Resources.resx | 313 - renderdocui/Properties/Settings.Designer.cs | 26 - renderdocui/Properties/Settings.settings | 5 - renderdocui/Resources/128.png | Bin 25275 -> 0 bytes .../Resources/RightArrow_Gray_16x16.png | Bin 640 -> 0 bytes .../Resources/RightArrow_Green_16x16.png | Bin 686 -> 0 bytes renderdocui/Resources/accept.png | Bin 781 -> 0 bytes renderdocui/Resources/add.png | Bin 733 -> 0 bytes renderdocui/Resources/arrow_in.png | Bin 600 -> 0 bytes renderdocui/Resources/arrow_join.png | Bin 626 -> 0 bytes renderdocui/Resources/arrow_undo.png | Bin 631 -> 0 bytes renderdocui/Resources/asterisk_orange.png | Bin 760 -> 0 bytes renderdocui/Resources/back.png | Bin 687 -> 0 bytes renderdocui/Resources/chart_curve.png | Bin 710 -> 0 bytes renderdocui/Resources/cog.png | Bin 512 -> 0 bytes renderdocui/Resources/cog_go.png | Bin 859 -> 0 bytes renderdocui/Resources/color_wheel.png | Bin 892 -> 0 bytes renderdocui/Resources/connect.png | Bin 748 -> 0 bytes renderdocui/Resources/cross.png | Bin 655 -> 0 bytes renderdocui/Resources/crosshatch.png | Bin 225 -> 0 bytes renderdocui/Resources/delete.png | Bin 715 -> 0 bytes renderdocui/Resources/disconnect.png | Bin 796 -> 0 bytes renderdocui/Resources/down_arrow.png | Bin 444 -> 0 bytes renderdocui/Resources/find.png | Bin 659 -> 0 bytes renderdocui/Resources/fit_window.png | Bin 594 -> 0 bytes renderdocui/Resources/flag_green.png | Bin 672 -> 0 bytes renderdocui/Resources/flip_y.png | Bin 478 -> 0 bytes renderdocui/Resources/folder_page.png | Bin 688 -> 0 bytes renderdocui/Resources/forward.png | Bin 801 -> 0 bytes renderdocui/Resources/glsl.xml | 104 - renderdocui/Resources/hlsl.xml | 118 - renderdocui/Resources/hourglass.png | Bin 744 -> 0 bytes renderdocui/Resources/house.png | Bin 806 -> 0 bytes renderdocui/Resources/icon.ico | Bin 280470 -> 0 bytes renderdocui/Resources/information.png | Bin 778 -> 0 bytes renderdocui/Resources/new_window.png | Bin 619 -> 0 bytes renderdocui/Resources/page_white_code.png | Bin 603 -> 0 bytes renderdocui/Resources/page_white_database.png | Bin 579 -> 0 bytes renderdocui/Resources/page_white_delete.png | Bin 536 -> 0 bytes renderdocui/Resources/page_white_edit.png | Bin 618 -> 0 bytes renderdocui/Resources/page_white_link.png | Bin 614 -> 0 bytes renderdocui/Resources/plugin_add.png | Bin 691 -> 0 bytes renderdocui/Resources/red_x_16.png | Bin 1026 -> 0 bytes renderdocui/Resources/runback.png | Bin 345 -> 0 bytes renderdocui/Resources/runcursor.png | Bin 355 -> 0 bytes renderdocui/Resources/runfwd.png | Bin 349 -> 0 bytes renderdocui/Resources/runnaninf.png | Bin 457 -> 0 bytes renderdocui/Resources/runsample.png | Bin 426 -> 0 bytes renderdocui/Resources/save.png | Bin 595 -> 0 bytes renderdocui/Resources/stepnext.png | Bin 425 -> 0 bytes renderdocui/Resources/stepprev.png | Bin 425 -> 0 bytes renderdocui/Resources/tick.png | Bin 537 -> 0 bytes renderdocui/Resources/time.png | Bin 793 -> 0 bytes renderdocui/Resources/timeline_marker.png | Bin 327 -> 0 bytes .../Resources/topologies/topo_linelist.png | Bin 716 -> 0 bytes .../topologies/topo_linelist_adj.png | Bin 1164 -> 0 bytes .../Resources/topologies/topo_linestrip.png | Bin 930 -> 0 bytes .../topologies/topo_linestrip_adj.png | Bin 1287 -> 0 bytes .../Resources/topologies/topo_patch.png | Bin 3677 -> 0 bytes .../Resources/topologies/topo_pointlist.png | Bin 472 -> 0 bytes .../Resources/topologies/topo_trilist.png | Bin 1679 -> 0 bytes .../Resources/topologies/topo_trilist_adj.png | Bin 3942 -> 0 bytes .../Resources/topologies/topo_tristrip.png | Bin 2703 -> 0 bytes .../topologies/topo_tristrip_adj.png | Bin 6428 -> 0 bytes renderdocui/Resources/up_arrow.png | Bin 437 -> 0 bytes renderdocui/Resources/upfolder.png | Bin 1348 -> 0 bytes renderdocui/Resources/wand.png | Bin 570 -> 0 bytes renderdocui/Resources/wireframe_mesh.png | Bin 20147 -> 0 bytes renderdocui/Resources/wrench.png | Bin 610 -> 0 bytes renderdocui/Resources/zoom.png | Bin 692 -> 0 bytes renderdocui/Settings.cs | 54 - renderdocui/Windows/APIInspector.Designer.cs | 161 - renderdocui/Windows/APIInspector.cs | 278 - renderdocui/Windows/APIInspector.resx | 123 - renderdocui/Windows/BufferViewer.Designer.cs | 1169 --- renderdocui/Windows/BufferViewer.cs | 3651 -------- renderdocui/Windows/BufferViewer.resx | 169 - renderdocui/Windows/DebugMessages.Designer.cs | 253 - renderdocui/Windows/DebugMessages.cs | 334 - renderdocui/Windows/DebugMessages.resx | 160 - .../Windows/Dialogs/AboutDialog.Designer.cs | 136 - renderdocui/Windows/Dialogs/AboutDialog.cs | 60 - renderdocui/Windows/Dialogs/AboutDialog.resx | 120 - .../Windows/Dialogs/CaptureDialog.Designer.cs | 873 -- renderdocui/Windows/Dialogs/CaptureDialog.cs | 1017 -- .../Windows/Dialogs/CaptureDialog.resx | 156 - .../Dialogs/ColumnSelector.Designer.cs | 128 - renderdocui/Windows/Dialogs/ColumnSelector.cs | 76 - .../Windows/Dialogs/ColumnSelector.resx | 120 - .../ConstantBufferPreviewer.Designer.cs | 211 - .../Dialogs/ConstantBufferPreviewer.cs | 464 - .../Dialogs/ConstantBufferPreviewer.resx | 142 - .../Dialogs/EnvironmentEditor.Designer.cs | 340 - .../Windows/Dialogs/EnvironmentEditor.cs | 213 - .../Windows/Dialogs/EnvironmentEditor.resx | 141 - .../Windows/Dialogs/FindAllDialog.Designer.cs | 341 - renderdocui/Windows/Dialogs/FindAllDialog.cs | 107 - .../Windows/Dialogs/FindAllDialog.resx | 126 - .../Windows/Dialogs/LiveCapture.Designer.cs | 541 -- renderdocui/Windows/Dialogs/LiveCapture.cs | 1058 --- renderdocui/Windows/Dialogs/LiveCapture.resx | 196 - .../Dialogs/OrderedListEditor.Designer.cs | 199 - .../Windows/Dialogs/OrderedListEditor.cs | 245 - .../Windows/Dialogs/OrderedListEditor.resx | 141 - .../Windows/Dialogs/ProgressPopup.Designer.cs | 106 - renderdocui/Windows/Dialogs/ProgressPopup.cs | 99 - .../Windows/Dialogs/ProgressPopup.resx | 123 - .../Windows/Dialogs/PythonShell.Designer.cs | 382 - renderdocui/Windows/Dialogs/PythonShell.cs | 565 -- renderdocui/Windows/Dialogs/PythonShell.resx | 169 - .../Windows/Dialogs/RemoteManager.Designer.cs | 348 - renderdocui/Windows/Dialogs/RemoteManager.cs | 638 -- .../Windows/Dialogs/RemoteManager.resx | 141 - .../Dialogs/SettingsDialog.Designer.cs | 1500 --- renderdocui/Windows/Dialogs/SettingsDialog.cs | 446 - .../Windows/Dialogs/SettingsDialog.resx | 239 - .../Dialogs/SuggestRemoteDialog.Designer.cs | 199 - .../Windows/Dialogs/SuggestRemoteDialog.cs | 140 - .../Windows/Dialogs/SuggestRemoteDialog.resx | 132 - .../Windows/Dialogs/TextureGoto.Designer.cs | 144 - renderdocui/Windows/Dialogs/TextureGoto.cs | 117 - renderdocui/Windows/Dialogs/TextureGoto.resx | 126 - .../Dialogs/TextureSaveDialog.Designer.cs | 713 -- .../Windows/Dialogs/TextureSaveDialog.cs | 654 -- .../Windows/Dialogs/TextureSaveDialog.resx | 216 - .../Windows/Dialogs/TipsDialog.Designer.cs | 214 - renderdocui/Windows/Dialogs/TipsDialog.cs | 248 - renderdocui/Windows/Dialogs/TipsDialog.resx | 129 - .../Windows/Dialogs/UpdateDialog.Designer.cs | 182 - renderdocui/Windows/Dialogs/UpdateDialog.cs | 248 - renderdocui/Windows/Dialogs/UpdateDialog.resx | 120 - .../Dialogs/VirtualOpenFileDialog.Designer.cs | 321 - .../Windows/Dialogs/VirtualOpenFileDialog.cs | 722 -- .../Dialogs/VirtualOpenFileDialog.resx | 308 - renderdocui/Windows/EventBrowser.Designer.cs | 489 - renderdocui/Windows/EventBrowser.cs | 1405 --- renderdocui/Windows/EventBrowser.resx | 147 - renderdocui/Windows/MainWindow.Designer.cs | 945 -- renderdocui/Windows/MainWindow.cs | 2105 ----- renderdocui/Windows/MainWindow.resx | 135 - .../D3D11PipelineStateViewer.Designer.cs | 5148 ----------- .../PipelineState/D3D11PipelineStateViewer.cs | 3980 -------- .../D3D11PipelineStateViewer.resx | 476 - .../D3D12PipelineStateViewer.Designer.cs | 5356 ----------- .../PipelineState/D3D12PipelineStateViewer.cs | 3361 ------- .../D3D12PipelineStateViewer.resx | 363 - .../GLPipelineStateViewer.Designer.cs | 5427 ----------- .../PipelineState/GLPipelineStateViewer.cs | 3575 -------- .../PipelineState/GLPipelineStateViewer.resx | 457 - .../PipelineStateViewer.Designer.cs | 49 - .../PipelineState/PipelineStateViewer.cs | 199 - .../PipelineState/PipelineStateViewer.resx | 120 - .../VulkanPipelineStateViewer.Designer.cs | 3993 -------- .../VulkanPipelineStateViewer.cs | 3644 -------- .../VulkanPipelineStateViewer.resx | 327 - .../Windows/PixelHistoryView.Designer.cs | 186 - renderdocui/Windows/PixelHistoryView.cs | 605 -- renderdocui/Windows/PixelHistoryView.resx | 123 - renderdocui/Windows/ShaderViewer.Designer.cs | 834 -- renderdocui/Windows/ShaderViewer.cs | 2418 ----- renderdocui/Windows/ShaderViewer.resx | 166 - .../Windows/StatisticsViewer.Designer.cs | 63 - renderdocui/Windows/StatisticsViewer.cs | 785 -- renderdocui/Windows/StatisticsViewer.resx | 120 - renderdocui/Windows/TextureViewer.Designer.cs | 1499 --- renderdocui/Windows/TextureViewer.cs | 4004 -------- renderdocui/Windows/TextureViewer.resx | 268 - renderdocui/Windows/TimelineBar.Designer.cs | 101 - renderdocui/Windows/TimelineBar.cs | 1166 --- renderdocui/Windows/TimelineBar.resx | 120 - renderdocui/app.config | 24 - renderdocui/renderdocui.csproj | 641 -- scripts/LINUX_DIST_README | 78 - scripts/android.toolchain.cmake | 1693 ---- scripts/appveyor.yml | 71 - scripts/dist.sh | 128 - scripts/hash_version.sh | 14 - scripts/installer/Installer32.wxs | 301 - scripts/installer/Installer64.wxs | 326 - scripts/installer/LICENSE.rtf | Bin 7908 -> 0 bytes scripts/installer/bannrbmp.bmp | Bin 2302 -> 0 bytes scripts/installer/chm.ico | Bin 4846 -> 0 bytes scripts/installer/customtext.wxl | 40 - scripts/installer/dlgbmp.bmp | Bin 7220 -> 0 bytes scripts/set_plist_version.sh | 12 - scripts/travis/android_compile.sh | 6 - scripts/travis/android_setup.sh | 22 - scripts/travis/compile.sh | 48 - scripts/travis/docs_compile.sh | 5 - scripts/travis/docs_setup.sh | 5 - scripts/travis/linux_compile.sh | 23 - scripts/travis/linux_setup.sh | 32 - scripts/travis/osx_compile.sh | 7 - scripts/travis/osx_setup.sh | 6 - scripts/travis/setup.sh | 48 - scripts/valgrind.supp | 275 - 823 files changed, 368 insertions(+), 298785 deletions(-) delete mode 100644 qrenderdoc/3rdparty/flowlayout/FlowLayout.cpp delete mode 100644 qrenderdoc/3rdparty/flowlayout/FlowLayout.h delete mode 100644 qrenderdoc/3rdparty/scintilla/.hg_archival.txt delete mode 100644 qrenderdoc/3rdparty/scintilla/License.txt delete mode 100644 qrenderdoc/3rdparty/scintilla/README delete mode 100644 qrenderdoc/3rdparty/scintilla/include/ILexer.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/Platform.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/SciLexer.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/Sci_Position.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/Scintilla.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/ScintillaWidget.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/qt/ScintillaDocument.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEdit.h delete mode 100644 qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEditBase.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexCPP.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexDiff.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexErrorList.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexHTML.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexJSON.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexNull.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexPython.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexers/LexRust.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/Accessor.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/Accessor.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexAccessor.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/OptionSet.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/SparseState.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/StringCopy.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/StyleContext.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/StyleContext.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/SubStyles.h delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/WordList.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/lexlib/WordList.h delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/README delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.cpp delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.h delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.cpp delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.h delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.h delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.cpp delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.h delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.cpp delete mode 100644 qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/AutoComplete.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/AutoComplete.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CallTip.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CallTip.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CaseConvert.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CaseConvert.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CaseFolder.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CaseFolder.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Catalogue.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Catalogue.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CellBuffer.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CellBuffer.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CharClassify.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/CharClassify.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ContractionState.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ContractionState.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Decoration.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Decoration.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Document.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Document.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/EditModel.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/EditModel.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/EditView.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/EditView.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Editor.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Editor.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ExternalLexer.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ExternalLexer.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/FontQuality.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Indicator.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Indicator.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/KeyMap.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/KeyMap.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/LineMarker.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/LineMarker.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/MarginView.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/MarginView.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Partitioning.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/PerLine.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/PerLine.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Position.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/PositionCache.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/PositionCache.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/RESearch.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/RESearch.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/RunStyles.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/RunStyles.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ScintillaBase.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ScintillaBase.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Selection.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Selection.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/SparseVector.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/SplitVector.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Style.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/Style.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/UniConversion.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/UniConversion.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/UnicodeFromUTF8.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ViewStyle.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/ViewStyle.h delete mode 100644 qrenderdoc/3rdparty/scintilla/src/XPM.cxx delete mode 100644 qrenderdoc/3rdparty/scintilla/src/XPM.h delete mode 100644 qrenderdoc/3rdparty/scintilla/version.txt delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/LICENSE delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/README.md delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManager.cpp delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManager.h delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerArea.cpp delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerArea.h delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerSplitter.cpp delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerSplitter.h delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerTabBar.cpp delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerTabBar.h delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerWrapper.cpp delete mode 100644 qrenderdoc/3rdparty/toolwindowmanager/ToolWindowManagerWrapper.h delete mode 100644 qrenderdoc/CMakeLists.txt delete mode 100644 qrenderdoc/Code/CaptureContext.cpp delete mode 100644 qrenderdoc/Code/CaptureContext.h delete mode 100644 qrenderdoc/Code/FormatElement.cpp delete mode 100644 qrenderdoc/Code/Interface/CommonPipelineState.cpp delete mode 100644 qrenderdoc/Code/Interface/CommonPipelineState.h delete mode 100644 qrenderdoc/Code/Interface/PersistantConfig.cpp delete mode 100644 qrenderdoc/Code/Interface/PersistantConfig.h delete mode 100644 qrenderdoc/Code/Interface/QRDInterface.cpp delete mode 100644 qrenderdoc/Code/Interface/QRDInterface.h delete mode 100644 qrenderdoc/Code/Interface/RemoteHost.cpp delete mode 100644 qrenderdoc/Code/Interface/RemoteHost.h delete mode 100644 qrenderdoc/Code/QRDUtils.cpp delete mode 100644 qrenderdoc/Code/QRDUtils.h delete mode 100644 qrenderdoc/Code/ReplayManager.cpp delete mode 100644 qrenderdoc/Code/ReplayManager.h delete mode 100644 qrenderdoc/Code/Resources.cpp delete mode 100644 qrenderdoc/Code/Resources.h delete mode 100644 qrenderdoc/Code/ScintillaSyntax.cpp delete mode 100644 qrenderdoc/Code/ScintillaSyntax.h delete mode 100644 qrenderdoc/Code/precompiled.cpp delete mode 100644 qrenderdoc/Code/precompiled.h delete mode 100644 qrenderdoc/Code/pyrenderdoc/CMakeLists.txt delete mode 100644 qrenderdoc/Code/pyrenderdoc/PythonContext.cpp delete mode 100644 qrenderdoc/Code/pyrenderdoc/PythonContext.h delete mode 100644 qrenderdoc/Code/pyrenderdoc/document_check.h delete mode 100644 qrenderdoc/Code/pyrenderdoc/pyconversion.h delete mode 100644 qrenderdoc/Code/pyrenderdoc/pyconversion.i delete mode 100644 qrenderdoc/Code/pyrenderdoc/pyrenderdoc_module.vcxproj delete mode 100644 qrenderdoc/Code/pyrenderdoc/pyrenderdoc_module.vcxproj.filters delete mode 100644 qrenderdoc/Code/pyrenderdoc/pyrenderdoc_stub.cpp delete mode 100644 qrenderdoc/Code/pyrenderdoc/qrenderdoc.i delete mode 100644 qrenderdoc/Code/pyrenderdoc/qrenderdoc_module.vcxproj delete mode 100644 qrenderdoc/Code/pyrenderdoc/qrenderdoc_module.vcxproj.filters delete mode 100644 qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp delete mode 100644 qrenderdoc/Code/pyrenderdoc/renderdoc.i delete mode 100644 qrenderdoc/Code/qprocessinfo.cpp delete mode 100644 qrenderdoc/Code/qprocessinfo.h delete mode 100644 qrenderdoc/Code/qrenderdoc.cpp delete mode 100644 qrenderdoc/FindPySide2.cmake delete mode 100644 qrenderdoc/README.md delete mode 100644 qrenderdoc/Resources/README.md delete mode 100644 qrenderdoc/Resources/action.png delete mode 100644 qrenderdoc/Resources/action@2x.png delete mode 100644 qrenderdoc/Resources/action_hover.png delete mode 100644 qrenderdoc/Resources/action_hover@2x.png delete mode 100644 qrenderdoc/Resources/add.png delete mode 100644 qrenderdoc/Resources/add@2x.png delete mode 100644 qrenderdoc/Resources/arrow_in.png delete mode 100644 qrenderdoc/Resources/arrow_in@2x.png delete mode 100644 qrenderdoc/Resources/arrow_join.png delete mode 100644 qrenderdoc/Resources/arrow_join@2x.png delete mode 100644 qrenderdoc/Resources/arrow_left.png delete mode 100644 qrenderdoc/Resources/arrow_left@2x.png delete mode 100644 qrenderdoc/Resources/arrow_out.png delete mode 100644 qrenderdoc/Resources/arrow_out@2x.png delete mode 100644 qrenderdoc/Resources/arrow_right.png delete mode 100644 qrenderdoc/Resources/arrow_right@2x.png delete mode 100644 qrenderdoc/Resources/arrow_undo.png delete mode 100644 qrenderdoc/Resources/arrow_undo@2x.png delete mode 100644 qrenderdoc/Resources/asterisk_orange.png delete mode 100644 qrenderdoc/Resources/asterisk_orange@2x.png delete mode 100644 qrenderdoc/Resources/chart_curve.png delete mode 100644 qrenderdoc/Resources/chart_curve@2x.png delete mode 100644 qrenderdoc/Resources/checkerboard.png delete mode 100644 qrenderdoc/Resources/checkerboard@2x.png delete mode 100644 qrenderdoc/Resources/cog.png delete mode 100644 qrenderdoc/Resources/cog@2x.png delete mode 100644 qrenderdoc/Resources/color_wheel.png delete mode 100644 qrenderdoc/Resources/color_wheel@2x.png delete mode 100644 qrenderdoc/Resources/connect.png delete mode 100644 qrenderdoc/Resources/connect@2x.png delete mode 100644 qrenderdoc/Resources/control_base_blue.png delete mode 100644 qrenderdoc/Resources/control_base_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_cursor_blue.png delete mode 100644 qrenderdoc/Resources/control_cursor_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_end_blue.png delete mode 100644 qrenderdoc/Resources/control_end_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_nan_blue.png delete mode 100644 qrenderdoc/Resources/control_nan_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_play_blue.png delete mode 100644 qrenderdoc/Resources/control_play_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_reverse_blue.png delete mode 100644 qrenderdoc/Resources/control_reverse_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_sample_blue.png delete mode 100644 qrenderdoc/Resources/control_sample_blue@2x.png delete mode 100644 qrenderdoc/Resources/control_start_blue.png delete mode 100644 qrenderdoc/Resources/control_start_blue@2x.png delete mode 100644 qrenderdoc/Resources/cross.png delete mode 100644 qrenderdoc/Resources/cross@2x.png delete mode 100644 qrenderdoc/Resources/del.png delete mode 100644 qrenderdoc/Resources/del@2x.png delete mode 100644 qrenderdoc/Resources/disconnect.png delete mode 100644 qrenderdoc/Resources/disconnect@2x.png delete mode 100644 qrenderdoc/Resources/find.png delete mode 100644 qrenderdoc/Resources/find@2x.png delete mode 100644 qrenderdoc/Resources/flag_green.png delete mode 100644 qrenderdoc/Resources/flag_green@2x.png delete mode 100644 qrenderdoc/Resources/flip_y.png delete mode 100644 qrenderdoc/Resources/flip_y@2x.png delete mode 100644 qrenderdoc/Resources/folder.png delete mode 100644 qrenderdoc/Resources/folder@2x.png delete mode 100644 qrenderdoc/Resources/folder_page_white.png delete mode 100644 qrenderdoc/Resources/folder_page_white@2x.png delete mode 100644 qrenderdoc/Resources/glsl.xml delete mode 100644 qrenderdoc/Resources/hlsl.xml delete mode 100644 qrenderdoc/Resources/hourglass.png delete mode 100644 qrenderdoc/Resources/hourglass@2x.png delete mode 100644 qrenderdoc/Resources/house.png delete mode 100644 qrenderdoc/Resources/house@2x.png delete mode 100644 qrenderdoc/Resources/information.png delete mode 100644 qrenderdoc/Resources/information@2x.png delete mode 100644 qrenderdoc/Resources/logo.svg delete mode 100644 qrenderdoc/Resources/page_white_code.png delete mode 100644 qrenderdoc/Resources/page_white_code@2x.png delete mode 100644 qrenderdoc/Resources/page_white_database.png delete mode 100644 qrenderdoc/Resources/page_white_database@2x.png delete mode 100644 qrenderdoc/Resources/page_white_delete.png delete mode 100644 qrenderdoc/Resources/page_white_delete@2x.png delete mode 100644 qrenderdoc/Resources/page_white_edit.png delete mode 100644 qrenderdoc/Resources/page_white_edit@2x.png delete mode 100644 qrenderdoc/Resources/page_white_link.png delete mode 100644 qrenderdoc/Resources/page_white_link@2x.png delete mode 100644 qrenderdoc/Resources/plugin_add.png delete mode 100644 qrenderdoc/Resources/plugin_add@2x.png delete mode 100644 qrenderdoc/Resources/qrenderdoc.rc delete mode 100644 qrenderdoc/Resources/qt.conf delete mode 100644 qrenderdoc/Resources/qtconf.qrc delete mode 100644 qrenderdoc/Resources/resource.h delete mode 100644 qrenderdoc/Resources/resources.qrc delete mode 100644 qrenderdoc/Resources/save.png delete mode 100644 qrenderdoc/Resources/save@2x.png delete mode 100644 qrenderdoc/Resources/tick.png delete mode 100644 qrenderdoc/Resources/tick@2x.png delete mode 100644 qrenderdoc/Resources/time.png delete mode 100644 qrenderdoc/Resources/time@2x.png delete mode 100644 qrenderdoc/Resources/timeline_marker.png delete mode 100644 qrenderdoc/Resources/timeline_marker@2x.png delete mode 100644 qrenderdoc/Resources/topologies/topo_linelist.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_linelist_adj.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_linestrip.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_linestrip_adj.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_patch.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_pointlist.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_trilist.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_trilist_adj.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_tristrip.svg delete mode 100644 qrenderdoc/Resources/topologies/topo_tristrip_adj.svg delete mode 100644 qrenderdoc/Resources/upfolder.png delete mode 100644 qrenderdoc/Resources/upfolder@2x.png delete mode 100644 qrenderdoc/Resources/wand.png delete mode 100644 qrenderdoc/Resources/wand@2x.png delete mode 100644 qrenderdoc/Resources/wireframe_mesh.png delete mode 100644 qrenderdoc/Resources/wireframe_mesh@2x.png delete mode 100644 qrenderdoc/Resources/wrench.png delete mode 100644 qrenderdoc/Resources/wrench@2x.png delete mode 100644 qrenderdoc/Resources/zoom.png delete mode 100644 qrenderdoc/Resources/zoom@2x.png delete mode 100644 qrenderdoc/Styles/RDStyle/RDStyle.cpp delete mode 100644 qrenderdoc/Styles/RDStyle/RDStyle.h delete mode 100644 qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.cpp delete mode 100644 qrenderdoc/Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.h delete mode 100644 qrenderdoc/Widgets/BufferFormatSpecifier.cpp delete mode 100644 qrenderdoc/Widgets/BufferFormatSpecifier.h delete mode 100644 qrenderdoc/Widgets/BufferFormatSpecifier.ui delete mode 100644 qrenderdoc/Widgets/CustomPaintWidget.cpp delete mode 100644 qrenderdoc/Widgets/CustomPaintWidget.h delete mode 100644 qrenderdoc/Widgets/Extended/RDDoubleSpinBox.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDDoubleSpinBox.h delete mode 100644 qrenderdoc/Widgets/Extended/RDHeaderView.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDHeaderView.h delete mode 100644 qrenderdoc/Widgets/Extended/RDLabel.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDLabel.h delete mode 100644 qrenderdoc/Widgets/Extended/RDLineEdit.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDLineEdit.h delete mode 100644 qrenderdoc/Widgets/Extended/RDListView.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDListView.h delete mode 100644 qrenderdoc/Widgets/Extended/RDListWidget.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDListWidget.h delete mode 100644 qrenderdoc/Widgets/Extended/RDSplitter.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDSplitter.h delete mode 100644 qrenderdoc/Widgets/Extended/RDTableView.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDTableView.h delete mode 100644 qrenderdoc/Widgets/Extended/RDTableWidget.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDTableWidget.h delete mode 100644 qrenderdoc/Widgets/Extended/RDTextEdit.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDTextEdit.h delete mode 100644 qrenderdoc/Widgets/Extended/RDToolButton.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDToolButton.h delete mode 100644 qrenderdoc/Widgets/Extended/RDTreeView.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDTreeView.h delete mode 100644 qrenderdoc/Widgets/Extended/RDTreeWidget.cpp delete mode 100644 qrenderdoc/Widgets/Extended/RDTreeWidget.h delete mode 100644 qrenderdoc/Widgets/FindReplace.cpp delete mode 100644 qrenderdoc/Widgets/FindReplace.h delete mode 100644 qrenderdoc/Widgets/FindReplace.ui delete mode 100644 qrenderdoc/Widgets/PipelineFlowChart.cpp delete mode 100644 qrenderdoc/Widgets/PipelineFlowChart.h delete mode 100644 qrenderdoc/Widgets/RangeHistogram.cpp delete mode 100644 qrenderdoc/Widgets/RangeHistogram.h delete mode 100644 qrenderdoc/Widgets/ResourcePreview.cpp delete mode 100644 qrenderdoc/Widgets/ResourcePreview.h delete mode 100644 qrenderdoc/Widgets/ResourcePreview.ui delete mode 100644 qrenderdoc/Widgets/TextureGoto.cpp delete mode 100644 qrenderdoc/Widgets/TextureGoto.h delete mode 100644 qrenderdoc/Widgets/ThumbnailStrip.cpp delete mode 100644 qrenderdoc/Widgets/ThumbnailStrip.h delete mode 100644 qrenderdoc/Widgets/ThumbnailStrip.ui delete mode 100644 qrenderdoc/Windows/APIInspector.cpp delete mode 100644 qrenderdoc/Windows/APIInspector.h delete mode 100644 qrenderdoc/Windows/APIInspector.ui delete mode 100644 qrenderdoc/Windows/BufferViewer.cpp delete mode 100644 qrenderdoc/Windows/BufferViewer.h delete mode 100644 qrenderdoc/Windows/BufferViewer.ui delete mode 100644 qrenderdoc/Windows/ConstantBufferPreviewer.cpp delete mode 100644 qrenderdoc/Windows/ConstantBufferPreviewer.h delete mode 100644 qrenderdoc/Windows/ConstantBufferPreviewer.ui delete mode 100644 qrenderdoc/Windows/DebugMessageView.cpp delete mode 100644 qrenderdoc/Windows/DebugMessageView.h delete mode 100644 qrenderdoc/Windows/DebugMessageView.ui delete mode 100644 qrenderdoc/Windows/Dialogs/AboutDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/AboutDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/AboutDialog.ui delete mode 100644 qrenderdoc/Windows/Dialogs/CaptureDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/CaptureDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/CaptureDialog.ui delete mode 100644 qrenderdoc/Windows/Dialogs/EnvironmentEditor.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/EnvironmentEditor.h delete mode 100644 qrenderdoc/Windows/Dialogs/EnvironmentEditor.ui delete mode 100644 qrenderdoc/Windows/Dialogs/LiveCapture.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/LiveCapture.h delete mode 100644 qrenderdoc/Windows/Dialogs/LiveCapture.ui delete mode 100644 qrenderdoc/Windows/Dialogs/OrderedListEditor.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/OrderedListEditor.h delete mode 100644 qrenderdoc/Windows/Dialogs/OrderedListEditor.ui delete mode 100644 qrenderdoc/Windows/Dialogs/RemoteManager.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/RemoteManager.h delete mode 100644 qrenderdoc/Windows/Dialogs/RemoteManager.ui delete mode 100644 qrenderdoc/Windows/Dialogs/SettingsDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/SettingsDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/SettingsDialog.ui delete mode 100644 qrenderdoc/Windows/Dialogs/SuggestRemoteDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/SuggestRemoteDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/SuggestRemoteDialog.ui delete mode 100644 qrenderdoc/Windows/Dialogs/TextureSaveDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/TextureSaveDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/TextureSaveDialog.ui delete mode 100644 qrenderdoc/Windows/Dialogs/TipsDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/TipsDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/TipsDialog.ui delete mode 100644 qrenderdoc/Windows/Dialogs/VirtualFileDialog.cpp delete mode 100644 qrenderdoc/Windows/Dialogs/VirtualFileDialog.h delete mode 100644 qrenderdoc/Windows/Dialogs/VirtualFileDialog.ui delete mode 100644 qrenderdoc/Windows/EventBrowser.cpp delete mode 100644 qrenderdoc/Windows/EventBrowser.h delete mode 100644 qrenderdoc/Windows/EventBrowser.ui delete mode 100644 qrenderdoc/Windows/MainWindow.cpp delete mode 100644 qrenderdoc/Windows/MainWindow.h delete mode 100644 qrenderdoc/Windows/MainWindow.ui delete mode 100644 qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp delete mode 100644 qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.h delete mode 100644 qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.ui delete mode 100644 qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp delete mode 100644 qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.h delete mode 100644 qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui delete mode 100644 qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp delete mode 100644 qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.h delete mode 100644 qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.ui delete mode 100644 qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp delete mode 100644 qrenderdoc/Windows/PipelineState/PipelineStateViewer.h delete mode 100644 qrenderdoc/Windows/PipelineState/PipelineStateViewer.ui delete mode 100644 qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp delete mode 100644 qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h delete mode 100644 qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui delete mode 100644 qrenderdoc/Windows/PixelHistoryView.cpp delete mode 100644 qrenderdoc/Windows/PixelHistoryView.h delete mode 100644 qrenderdoc/Windows/PixelHistoryView.ui delete mode 100644 qrenderdoc/Windows/PythonShell.cpp delete mode 100644 qrenderdoc/Windows/PythonShell.h delete mode 100644 qrenderdoc/Windows/PythonShell.ui delete mode 100644 qrenderdoc/Windows/ShaderViewer.cpp delete mode 100644 qrenderdoc/Windows/ShaderViewer.h delete mode 100644 qrenderdoc/Windows/ShaderViewer.ui delete mode 100644 qrenderdoc/Windows/StatisticsViewer.cpp delete mode 100644 qrenderdoc/Windows/StatisticsViewer.h delete mode 100644 qrenderdoc/Windows/StatisticsViewer.ui delete mode 100644 qrenderdoc/Windows/TextureViewer.cpp delete mode 100644 qrenderdoc/Windows/TextureViewer.h delete mode 100644 qrenderdoc/Windows/TextureViewer.ui delete mode 100644 qrenderdoc/Windows/TimelineBar.cpp delete mode 100644 qrenderdoc/Windows/TimelineBar.h delete mode 100644 qrenderdoc/qrenderdoc.pro delete mode 100644 qrenderdoc/qrenderdoc_local.vcxproj delete mode 100644 qrenderdoc/qrenderdoc_local.vcxproj.filters delete mode 100644 qrenderdoc/share/application-x-renderdoc-capture.svg delete mode 100644 qrenderdoc/share/magic delete mode 100644 qrenderdoc/share/menu delete mode 100644 qrenderdoc/share/renderdoc-capture.xml delete mode 100644 qrenderdoc/share/renderdoc-icon-16x16.xpm delete mode 100644 qrenderdoc/share/renderdoc-icon-32x32.xpm delete mode 100644 qrenderdoc/share/renderdoc.desktop delete mode 100644 qrenderdoc/share/renderdoc.thumbnailer delete mode 100644 qrenderdoc/va_stdafx.h delete mode 100644 renderdoccmd/3rdparty/cmdline/cmdline.h rename {qrenderdoc/Resources => renderdoccmd}/icon.ico (100%) delete mode 100644 renderdocshim/renderdocshim.cpp delete mode 100644 renderdocshim/renderdocshim.h delete mode 100644 renderdocshim/renderdocshim.vcxproj delete mode 100644 renderdocshim/renderdocshim.vcxproj.filters delete mode 100644 renderdocui/3rdparty/ScintillaNET/License.txt delete mode 100644 renderdocui/3rdparty/ScintillaNET/SciLexer.dll delete mode 100644 renderdocui/3rdparty/ScintillaNET/SciLexer64.dll delete mode 100644 renderdocui/3rdparty/ScintillaNET/ScintillaNET.dll delete mode 100644 renderdocui/3rdparty/ScintillaNET/ScintillaNET.pdb delete mode 100644 renderdocui/3rdparty/ScintillaNET/ScintillaNET.xml delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/AutoHideStripBase.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockAreasEditor.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockContent.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockContentCollection.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockContentEventArgs.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockContentHandler.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockOutlineBase.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPane.SplitterControl.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPane.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPaneCaptionBase.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPaneCollection.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPaneStripBase.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.Appearance.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.AutoHideWindow.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.DockDragHandler.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.DragHandler.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.FocusManager.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.MdiClientController.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.Persistor.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.SplitterDragHandler.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanel.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanelExtender.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockPanelSkin.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockWindow.SplitterControl.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockWindow.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DockWindowCollection.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DragForm.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/DummyControl.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Enums.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/FloatWindow.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/FloatWindowCollection.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Helpers/DockHelper.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Helpers/DrawHelper.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Helpers/ResourceHelper.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Helpers/Win32Helper.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/InertButtonBase.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Interfaces.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Localization.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Measures.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/NestedDockingStatus.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/NestedPaneCollection.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources.Designer.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources.resx delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond_Bottom.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond_Hotspot.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond_HotspotIndex.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond_Left.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond_Right.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PaneDiamond_Top.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelBottom.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelBottom_Active.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelFill.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelFill_Active.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelLeft.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelLeft_Active.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelRight.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelRight_Active.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelTop.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockIndicator_PanelTop_Active.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockPane_AutoHide.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockPane_Close.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockPane_Dock.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockPane_Option.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/DockPane_OptionOverflow.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Resources/Dockindicator_PaneDiamond_Fill.bmp delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Skins/DockPanelSkinBuilder.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Skins/Style.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/SplitterBase.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Strings.Designer.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Strings.resx delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/VS2005AutoHideStrip.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/VS2005DockPaneCaption.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/VS2005DockPaneStrip.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/VisibleNestedPaneCollection.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Win32/Enums.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Docking/Win32/NativeMethods.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/Properties/AssemblyInfo.cs delete mode 100644 renderdocui/3rdparty/WinFormsUI/WinFormsUI.csproj delete mode 100644 renderdocui/3rdparty/WinFormsUI/dockpanelsuite.snk delete mode 100644 renderdocui/3rdparty/WinFormsUI/license.txt delete mode 100644 renderdocui/3rdparty/ironpython/IronPython.Modules.dll delete mode 100644 renderdocui/3rdparty/ironpython/IronPython.Modules.xml delete mode 100644 renderdocui/3rdparty/ironpython/IronPython.dll delete mode 100644 renderdocui/3rdparty/ironpython/IronPython.xml delete mode 100644 renderdocui/3rdparty/ironpython/LICENSE.md delete mode 100644 renderdocui/3rdparty/ironpython/Microsoft.Dynamic.dll delete mode 100644 renderdocui/3rdparty/ironpython/Microsoft.Dynamic.xml delete mode 100644 renderdocui/3rdparty/ironpython/Microsoft.Scripting.dll delete mode 100644 renderdocui/3rdparty/ironpython/Microsoft.Scripting.xml delete mode 100644 renderdocui/3rdparty/ironpython/README.md delete mode 100644 renderdocui/3rdparty/ironpython/compilelibs.sh delete mode 100644 renderdocui/Code/AppMain.cs delete mode 100644 renderdocui/Code/Cameras.cs delete mode 100644 renderdocui/Code/CommonPipelineState.cs delete mode 100644 renderdocui/Code/Core.cs delete mode 100644 renderdocui/Code/FormatElement.cs delete mode 100644 renderdocui/Code/Helpers.cs delete mode 100644 renderdocui/Code/LogViewerForm.cs delete mode 100644 renderdocui/Code/PersistantConfig.cs delete mode 100644 renderdocui/Code/RenderManager.cs delete mode 100644 renderdocui/Code/Win32PInvoke.cs delete mode 100644 renderdocui/Controls/BufferFormatSpecifier.Designer.cs delete mode 100644 renderdocui/Controls/BufferFormatSpecifier.cs delete mode 100644 renderdocui/Controls/BufferFormatSpecifier.resx delete mode 100644 renderdocui/Controls/DoubleClickSplitter.Designer.cs delete mode 100644 renderdocui/Controls/DoubleClickSplitter.cs delete mode 100644 renderdocui/Controls/NoscrollPanel.cs delete mode 100644 renderdocui/Controls/PipelineFlowchart.Designer.cs delete mode 100644 renderdocui/Controls/PipelineFlowchart.cs delete mode 100644 renderdocui/Controls/PipelineFlowchart.resx delete mode 100644 renderdocui/Controls/RangeHistogram.Designer.cs delete mode 100644 renderdocui/Controls/RangeHistogram.cs delete mode 100644 renderdocui/Controls/RangeHistogram.resx delete mode 100644 renderdocui/Controls/ResourcePreview.Designer.cs delete mode 100644 renderdocui/Controls/ResourcePreview.cs delete mode 100644 renderdocui/Controls/ResourcePreview.resx delete mode 100644 renderdocui/Controls/TablessControl.cs delete mode 100644 renderdocui/Controls/TextureListBox.cs delete mode 100644 renderdocui/Controls/ThumbnailStrip.Designer.cs delete mode 100644 renderdocui/Controls/ThumbnailStrip.cs delete mode 100644 renderdocui/Controls/ThumbnailStrip.resx delete mode 100644 renderdocui/Controls/ToolStripSpringTextBox.cs delete mode 100644 renderdocui/Controls/TreeListView/LICENSE.htm delete mode 100644 renderdocui/Controls/TreeListView/README.txt delete mode 100644 renderdocui/Controls/TreeListView/TreeListColumn.Design.cs delete mode 100644 renderdocui/Controls/TreeListView/TreeListColumn.cs delete mode 100644 renderdocui/Controls/TreeListView/TreeListNode.cs delete mode 100644 renderdocui/Controls/TreeListView/TreeListOptions.cs delete mode 100644 renderdocui/Controls/TreeListView/TreeListPainter.cs delete mode 100644 renderdocui/Controls/TreeListView/TreeListView.cs delete mode 100644 renderdocui/Interop/Camera.cs delete mode 100644 renderdocui/Interop/CaptureOptions.cs delete mode 100644 renderdocui/Interop/CustomMarshaling.cs delete mode 100644 renderdocui/Interop/D3D11PipelineState.cs delete mode 100644 renderdocui/Interop/D3D12PipelineState.cs delete mode 100644 renderdocui/Interop/Enums.cs delete mode 100644 renderdocui/Interop/FetchInfo.cs delete mode 100644 renderdocui/Interop/Formatter.cs delete mode 100644 renderdocui/Interop/GLPipelineState.cs delete mode 100644 renderdocui/Interop/ReplayRenderer.cs delete mode 100644 renderdocui/Interop/Shader.cs delete mode 100644 renderdocui/Interop/StaticExports.cs delete mode 100644 renderdocui/Interop/VulkanPipelineState.cs delete mode 100644 renderdocui/Plugins/PluginHelpers.cs delete mode 100644 renderdocui/Plugins/ReplayManagerPlugin.cs delete mode 100644 renderdocui/Properties/AssemblyInfo.cs delete mode 100644 renderdocui/Properties/Resources.Designer.cs delete mode 100644 renderdocui/Properties/Resources.resx delete mode 100644 renderdocui/Properties/Settings.Designer.cs delete mode 100644 renderdocui/Properties/Settings.settings delete mode 100644 renderdocui/Resources/128.png delete mode 100644 renderdocui/Resources/RightArrow_Gray_16x16.png delete mode 100644 renderdocui/Resources/RightArrow_Green_16x16.png delete mode 100644 renderdocui/Resources/accept.png delete mode 100644 renderdocui/Resources/add.png delete mode 100644 renderdocui/Resources/arrow_in.png delete mode 100644 renderdocui/Resources/arrow_join.png delete mode 100644 renderdocui/Resources/arrow_undo.png delete mode 100644 renderdocui/Resources/asterisk_orange.png delete mode 100644 renderdocui/Resources/back.png delete mode 100644 renderdocui/Resources/chart_curve.png delete mode 100644 renderdocui/Resources/cog.png delete mode 100644 renderdocui/Resources/cog_go.png delete mode 100644 renderdocui/Resources/color_wheel.png delete mode 100644 renderdocui/Resources/connect.png delete mode 100644 renderdocui/Resources/cross.png delete mode 100644 renderdocui/Resources/crosshatch.png delete mode 100644 renderdocui/Resources/delete.png delete mode 100644 renderdocui/Resources/disconnect.png delete mode 100644 renderdocui/Resources/down_arrow.png delete mode 100644 renderdocui/Resources/find.png delete mode 100644 renderdocui/Resources/fit_window.png delete mode 100644 renderdocui/Resources/flag_green.png delete mode 100644 renderdocui/Resources/flip_y.png delete mode 100644 renderdocui/Resources/folder_page.png delete mode 100644 renderdocui/Resources/forward.png delete mode 100644 renderdocui/Resources/glsl.xml delete mode 100644 renderdocui/Resources/hlsl.xml delete mode 100644 renderdocui/Resources/hourglass.png delete mode 100644 renderdocui/Resources/house.png delete mode 100644 renderdocui/Resources/icon.ico delete mode 100644 renderdocui/Resources/information.png delete mode 100644 renderdocui/Resources/new_window.png delete mode 100644 renderdocui/Resources/page_white_code.png delete mode 100644 renderdocui/Resources/page_white_database.png delete mode 100644 renderdocui/Resources/page_white_delete.png delete mode 100644 renderdocui/Resources/page_white_edit.png delete mode 100644 renderdocui/Resources/page_white_link.png delete mode 100644 renderdocui/Resources/plugin_add.png delete mode 100644 renderdocui/Resources/red_x_16.png delete mode 100644 renderdocui/Resources/runback.png delete mode 100644 renderdocui/Resources/runcursor.png delete mode 100644 renderdocui/Resources/runfwd.png delete mode 100644 renderdocui/Resources/runnaninf.png delete mode 100644 renderdocui/Resources/runsample.png delete mode 100644 renderdocui/Resources/save.png delete mode 100644 renderdocui/Resources/stepnext.png delete mode 100644 renderdocui/Resources/stepprev.png delete mode 100644 renderdocui/Resources/tick.png delete mode 100644 renderdocui/Resources/time.png delete mode 100644 renderdocui/Resources/timeline_marker.png delete mode 100644 renderdocui/Resources/topologies/topo_linelist.png delete mode 100644 renderdocui/Resources/topologies/topo_linelist_adj.png delete mode 100644 renderdocui/Resources/topologies/topo_linestrip.png delete mode 100644 renderdocui/Resources/topologies/topo_linestrip_adj.png delete mode 100644 renderdocui/Resources/topologies/topo_patch.png delete mode 100644 renderdocui/Resources/topologies/topo_pointlist.png delete mode 100644 renderdocui/Resources/topologies/topo_trilist.png delete mode 100644 renderdocui/Resources/topologies/topo_trilist_adj.png delete mode 100644 renderdocui/Resources/topologies/topo_tristrip.png delete mode 100644 renderdocui/Resources/topologies/topo_tristrip_adj.png delete mode 100644 renderdocui/Resources/up_arrow.png delete mode 100644 renderdocui/Resources/upfolder.png delete mode 100644 renderdocui/Resources/wand.png delete mode 100644 renderdocui/Resources/wireframe_mesh.png delete mode 100644 renderdocui/Resources/wrench.png delete mode 100644 renderdocui/Resources/zoom.png delete mode 100644 renderdocui/Settings.cs delete mode 100644 renderdocui/Windows/APIInspector.Designer.cs delete mode 100644 renderdocui/Windows/APIInspector.cs delete mode 100644 renderdocui/Windows/APIInspector.resx delete mode 100644 renderdocui/Windows/BufferViewer.Designer.cs delete mode 100644 renderdocui/Windows/BufferViewer.cs delete mode 100644 renderdocui/Windows/BufferViewer.resx delete mode 100644 renderdocui/Windows/DebugMessages.Designer.cs delete mode 100644 renderdocui/Windows/DebugMessages.cs delete mode 100644 renderdocui/Windows/DebugMessages.resx delete mode 100644 renderdocui/Windows/Dialogs/AboutDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/AboutDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/AboutDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/CaptureDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/CaptureDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/CaptureDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/ColumnSelector.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/ColumnSelector.cs delete mode 100644 renderdocui/Windows/Dialogs/ColumnSelector.resx delete mode 100644 renderdocui/Windows/Dialogs/ConstantBufferPreviewer.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/ConstantBufferPreviewer.cs delete mode 100644 renderdocui/Windows/Dialogs/ConstantBufferPreviewer.resx delete mode 100644 renderdocui/Windows/Dialogs/EnvironmentEditor.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/EnvironmentEditor.cs delete mode 100644 renderdocui/Windows/Dialogs/EnvironmentEditor.resx delete mode 100644 renderdocui/Windows/Dialogs/FindAllDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/FindAllDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/FindAllDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/LiveCapture.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/LiveCapture.cs delete mode 100644 renderdocui/Windows/Dialogs/LiveCapture.resx delete mode 100644 renderdocui/Windows/Dialogs/OrderedListEditor.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/OrderedListEditor.cs delete mode 100644 renderdocui/Windows/Dialogs/OrderedListEditor.resx delete mode 100644 renderdocui/Windows/Dialogs/ProgressPopup.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/ProgressPopup.cs delete mode 100644 renderdocui/Windows/Dialogs/ProgressPopup.resx delete mode 100644 renderdocui/Windows/Dialogs/PythonShell.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/PythonShell.cs delete mode 100644 renderdocui/Windows/Dialogs/PythonShell.resx delete mode 100644 renderdocui/Windows/Dialogs/RemoteManager.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/RemoteManager.cs delete mode 100644 renderdocui/Windows/Dialogs/RemoteManager.resx delete mode 100644 renderdocui/Windows/Dialogs/SettingsDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/SettingsDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/SettingsDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/SuggestRemoteDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/SuggestRemoteDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/SuggestRemoteDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/TextureGoto.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/TextureGoto.cs delete mode 100644 renderdocui/Windows/Dialogs/TextureGoto.resx delete mode 100644 renderdocui/Windows/Dialogs/TextureSaveDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/TextureSaveDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/TextureSaveDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/TipsDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/TipsDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/TipsDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/UpdateDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/UpdateDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/UpdateDialog.resx delete mode 100644 renderdocui/Windows/Dialogs/VirtualOpenFileDialog.Designer.cs delete mode 100644 renderdocui/Windows/Dialogs/VirtualOpenFileDialog.cs delete mode 100644 renderdocui/Windows/Dialogs/VirtualOpenFileDialog.resx delete mode 100644 renderdocui/Windows/EventBrowser.Designer.cs delete mode 100644 renderdocui/Windows/EventBrowser.cs delete mode 100644 renderdocui/Windows/EventBrowser.resx delete mode 100644 renderdocui/Windows/MainWindow.Designer.cs delete mode 100644 renderdocui/Windows/MainWindow.cs delete mode 100644 renderdocui/Windows/MainWindow.resx delete mode 100644 renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.Designer.cs delete mode 100644 renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.cs delete mode 100644 renderdocui/Windows/PipelineState/D3D11PipelineStateViewer.resx delete mode 100644 renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.Designer.cs delete mode 100644 renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.cs delete mode 100644 renderdocui/Windows/PipelineState/D3D12PipelineStateViewer.resx delete mode 100644 renderdocui/Windows/PipelineState/GLPipelineStateViewer.Designer.cs delete mode 100644 renderdocui/Windows/PipelineState/GLPipelineStateViewer.cs delete mode 100644 renderdocui/Windows/PipelineState/GLPipelineStateViewer.resx delete mode 100644 renderdocui/Windows/PipelineState/PipelineStateViewer.Designer.cs delete mode 100644 renderdocui/Windows/PipelineState/PipelineStateViewer.cs delete mode 100644 renderdocui/Windows/PipelineState/PipelineStateViewer.resx delete mode 100644 renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.Designer.cs delete mode 100644 renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.cs delete mode 100644 renderdocui/Windows/PipelineState/VulkanPipelineStateViewer.resx delete mode 100644 renderdocui/Windows/PixelHistoryView.Designer.cs delete mode 100644 renderdocui/Windows/PixelHistoryView.cs delete mode 100644 renderdocui/Windows/PixelHistoryView.resx delete mode 100644 renderdocui/Windows/ShaderViewer.Designer.cs delete mode 100644 renderdocui/Windows/ShaderViewer.cs delete mode 100644 renderdocui/Windows/ShaderViewer.resx delete mode 100644 renderdocui/Windows/StatisticsViewer.Designer.cs delete mode 100644 renderdocui/Windows/StatisticsViewer.cs delete mode 100644 renderdocui/Windows/StatisticsViewer.resx delete mode 100644 renderdocui/Windows/TextureViewer.Designer.cs delete mode 100644 renderdocui/Windows/TextureViewer.cs delete mode 100644 renderdocui/Windows/TextureViewer.resx delete mode 100644 renderdocui/Windows/TimelineBar.Designer.cs delete mode 100644 renderdocui/Windows/TimelineBar.cs delete mode 100644 renderdocui/Windows/TimelineBar.resx delete mode 100644 renderdocui/app.config delete mode 100644 renderdocui/renderdocui.csproj delete mode 100644 scripts/LINUX_DIST_README delete mode 100644 scripts/android.toolchain.cmake delete mode 100644 scripts/appveyor.yml delete mode 100644 scripts/dist.sh delete mode 100644 scripts/hash_version.sh delete mode 100644 scripts/installer/Installer32.wxs delete mode 100644 scripts/installer/Installer64.wxs delete mode 100644 scripts/installer/LICENSE.rtf delete mode 100644 scripts/installer/bannrbmp.bmp delete mode 100644 scripts/installer/chm.ico delete mode 100644 scripts/installer/customtext.wxl delete mode 100644 scripts/installer/dlgbmp.bmp delete mode 100755 scripts/set_plist_version.sh delete mode 100644 scripts/travis/android_compile.sh delete mode 100644 scripts/travis/android_setup.sh delete mode 100644 scripts/travis/compile.sh delete mode 100644 scripts/travis/docs_compile.sh delete mode 100644 scripts/travis/docs_setup.sh delete mode 100644 scripts/travis/linux_compile.sh delete mode 100644 scripts/travis/linux_setup.sh delete mode 100644 scripts/travis/osx_compile.sh delete mode 100644 scripts/travis/osx_setup.sh delete mode 100644 scripts/travis/setup.sh delete mode 100644 scripts/valgrind.supp diff --git a/qrenderdoc/3rdparty/flowlayout/FlowLayout.cpp b/qrenderdoc/3rdparty/flowlayout/FlowLayout.cpp deleted file mode 100644 index 938585334..000000000 --- a/qrenderdoc/3rdparty/flowlayout/FlowLayout.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include "FlowLayout.h" - -FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing) - : QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing), m_fixedGrid(false) -{ - setContentsMargins(margin, margin, margin, margin); -} - -FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing) - : m_hSpace(hSpacing), m_vSpace(vSpacing), m_fixedGrid(false) -{ - setContentsMargins(margin, margin, margin, margin); -} - -FlowLayout::~FlowLayout() -{ - QLayoutItem *item; - while ((item = takeAt(0))) - delete item; -} - -void FlowLayout::addItem(QLayoutItem *item) -{ - itemList.append(item); -} - -int FlowLayout::horizontalSpacing() const -{ - if (m_hSpace >= 0) { - return m_hSpace; - } else { - return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); - } -} - -int FlowLayout::verticalSpacing() const -{ - if (m_vSpace >= 0) { - return m_vSpace; - } else { - return smartSpacing(QStyle::PM_LayoutVerticalSpacing); - } -} - -bool FlowLayout::fixedGrid() const -{ - return m_fixedGrid; -} - -void FlowLayout::setFixedGrid(bool fixedgrid) -{ - m_fixedGrid = fixedgrid; -} - -int FlowLayout::count() const -{ - return itemList.size(); -} - -QLayoutItem *FlowLayout::itemAt(int index) const -{ - return itemList.value(index); -} - -QLayoutItem *FlowLayout::takeAt(int index) -{ - if (index >= 0 && index < itemList.size()) - return itemList.takeAt(index); - else - return 0; -} - -Qt::Orientations FlowLayout::expandingDirections() const -{ - return 0; -} - -bool FlowLayout::hasHeightForWidth() const -{ - return true; -} - -int FlowLayout::heightForWidth(int width) const -{ - int height = doLayout(QRect(0, 0, width, 0), true); - return height; -} - -void FlowLayout::setGeometry(const QRect &rect) -{ - bool needUpdate = (rect != m_prevRect); - - QLayout::setGeometry(rect); - doLayout(rect, false); - - if(needUpdate) - update(); - - m_prevRect = rect; -} - -QSize FlowLayout::sizeHint() const -{ - QSize size = geometry().size(); - size.setHeight(doLayout(geometry().adjusted(0, 0, -10, 0), true)); - return size; -} - -QSize FlowLayout::minimumSize() const -{ - QSize size; - QLayoutItem *item; - foreach (item, itemList) - size = size.expandedTo(item->minimumSize()); - - size += QSize(2*margin(), 2*margin()); - return size; -} - -int FlowLayout::doLayout(const QRect &rect, bool testOnly) const -{ - int left, top, right, bottom; - getContentsMargins(&left, &top, &right, &bottom); - QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); - int x = effectiveRect.x(); - int y = effectiveRect.y(); - int lineHeight = 0; - QSize fixedSize; - - QLayoutItem *item; - if(m_fixedGrid) { - foreach (item, itemList) { - fixedSize = fixedSize.expandedTo(item->sizeHint()); - } - } - - foreach (item, itemList) { - QWidget *wid = item->widget(); - - QSize size = m_fixedGrid ? fixedSize : item->sizeHint(); - - int spaceX = horizontalSpacing(); - if (spaceX == -1) - spaceX = wid->style()->layoutSpacing( - QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); - int spaceY = verticalSpacing(); - if (spaceY == -1) - spaceY = wid->style()->layoutSpacing( - QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical); - int nextX = x + size.width() + spaceX; - if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { - x = effectiveRect.x(); - y = y + lineHeight + spaceY; - nextX = x + size.width() + spaceX; - lineHeight = 0; - } - - if (!testOnly) - item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); - - x = nextX; - lineHeight = qMax(lineHeight, size.height()); - } - return y + lineHeight - rect.y() + bottom; -} -int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const -{ - QObject *parent = this->parent(); - if (!parent) { - return -1; - } else if (parent->isWidgetType()) { - QWidget *pw = static_cast(parent); - return pw->style()->pixelMetric(pm, 0, pw); - } else { - return static_cast(parent)->spacing(); - } -} diff --git a/qrenderdoc/3rdparty/flowlayout/FlowLayout.h b/qrenderdoc/3rdparty/flowlayout/FlowLayout.h deleted file mode 100644 index 3e822b35f..000000000 --- a/qrenderdoc/3rdparty/flowlayout/FlowLayout.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FLOWLAYOUT_H -#define FLOWLAYOUT_H - -#include -#include -#include -class FlowLayout : public QLayout -{ -public: - explicit FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); - explicit FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); - ~FlowLayout(); - - void addItem(QLayoutItem *item) Q_DECL_OVERRIDE; - int horizontalSpacing() const; - int verticalSpacing() const; - Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE; - bool hasHeightForWidth() const Q_DECL_OVERRIDE; - int heightForWidth(int) const Q_DECL_OVERRIDE; - int count() const Q_DECL_OVERRIDE; - QLayoutItem *itemAt(int index) const Q_DECL_OVERRIDE; - QSize minimumSize() const Q_DECL_OVERRIDE; - void setGeometry(const QRect &rect) Q_DECL_OVERRIDE; - QSize sizeHint() const Q_DECL_OVERRIDE; - QLayoutItem *takeAt(int index) Q_DECL_OVERRIDE; - - bool fixedGrid() const; - void setFixedGrid(bool fixedgrid); - -private: - int doLayout(const QRect &rect, bool testOnly) const; - int smartSpacing(QStyle::PixelMetric pm) const; - - QList itemList; - QRect m_prevRect; - bool m_fixedGrid; - int m_hSpace; - int m_vSpace; -}; - -#endif // FLOWLAYOUT_H diff --git a/qrenderdoc/3rdparty/scintilla/.hg_archival.txt b/qrenderdoc/3rdparty/scintilla/.hg_archival.txt deleted file mode 100644 index 77e5d50f0..000000000 --- a/qrenderdoc/3rdparty/scintilla/.hg_archival.txt +++ /dev/null @@ -1,6 +0,0 @@ -repo: bdf8c3ef2fb01ea24578e726337888e706d10b92 -node: cec95d2eeb9e7bf6a9bad56d7b9ee8d33f1bdd0d -branch: default -latesttag: rel-3-7-2 -latesttagdistance: 1 -changessincelatesttag: 1 diff --git a/qrenderdoc/3rdparty/scintilla/License.txt b/qrenderdoc/3rdparty/scintilla/License.txt deleted file mode 100644 index cbe25b2fc..000000000 --- a/qrenderdoc/3rdparty/scintilla/License.txt +++ /dev/null @@ -1,20 +0,0 @@ -License for Scintilla and SciTE - -Copyright 1998-2003 by Neil Hodgson - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation. - -NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY -SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE -OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/qrenderdoc/3rdparty/scintilla/README b/qrenderdoc/3rdparty/scintilla/README deleted file mode 100644 index ca2f2c059..000000000 --- a/qrenderdoc/3rdparty/scintilla/README +++ /dev/null @@ -1,88 +0,0 @@ -README for building of Scintilla and SciTE - -Scintilla can be built by itself. -To build SciTE, Scintilla must first be built. - - -*** GTK+/Linux version *** - -You must first have GTK+ 2.18 or later and GCC (4.8 or better) installed. -Clang may be used by adding CLANG=1 to the make command line. -Other C++ compilers may work but may require tweaking the make file. -Either GTK+ 2.x or 3.x may be used with 2.x the default and 3.x -chosen with the make argument GTK3=1. - -To build Scintilla, use the makefile located in the scintilla/gtk directory - cd scintilla/gtk - make - cd ../.. - -To build and install SciTE, use the makefile located in the scite/gtk directory - cd scite/gtk - make - sudo make install - -This installs SciTE into $prefix/bin. The value of $prefix is determined from -the location of Gnome if it is installed. This is usually /usr if installed -with Linux or /usr/local if built from source. If Gnome is not installed -/usr/bin is used as the prefix. The prefix can be overridden on the command -line like "make prefix=/opt" but the same value should be used for both make -and make install as this location is compiled into the executable. The global -properties file is installed at $prefix/share/scite/SciTEGlobal.properties. -The language specific properties files are also installed into this directory. - -To remove SciTE - sudo make uninstall - -To clean the object files which may be needed to change $prefix - make clean - -The current make file only supports static linking between SciTE and Scintilla. - - -*** Windows version *** - -A C++ compiler is required, with C++11 required for building SciTE. -Visual Studio 2015 is the development system used for most development -although Mingw32 4.8 is also supported. - -Older compilers may not have a working std::regex so this can be disabled -with the make argument NO_CXX11_REGEX=1. - -To build Scintilla, make in the scintilla/win32 directory - cd scintilla\win32 -GCC: mingw32-make -Visual C++: nmake -f scintilla.mak - cd ..\.. - -To build SciTE, use the makefiles located in the scite/win32 directory - cd scite\win32 -GCC: mingw32-make -Visual C++: nmake -f scite.mak - -An executable SciTE will now be in scite/bin. - -*** GTK+/Windows version *** - -Mingw32 is known to work. Other compilers will probably not work. - -Only Scintilla will build with GTK+ on Windows. SciTE will not work. - -To build Scintilla, make in the scintilla/gtk directory - cd scintilla\gtk - mingw32-make - -*** macOS Cocoa version *** - -Xcode 7 or 8 may be used to build Scintilla on macOS. - -There is no open source version of SciTE for macOS but there is a commercial -version available through the App Store. - -To build Scintilla, run xcodebuild in the scintilla/cocoa/ScintillaFramework directory - cd cocoa/ScintillaFramework - xcodebuild - -*** Qt version *** - -See the qt/README file to build Scintilla with Qt. diff --git a/qrenderdoc/3rdparty/scintilla/include/ILexer.h b/qrenderdoc/3rdparty/scintilla/include/ILexer.h deleted file mode 100644 index f01029178..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/ILexer.h +++ /dev/null @@ -1,100 +0,0 @@ -// Scintilla source code edit control -/** @file ILexer.h - ** Interface between Scintilla and lexers. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef ILEXER_H -#define ILEXER_H - -#include "Sci_Position.h" - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#ifdef _WIN32 - #define SCI_METHOD __stdcall -#else - #define SCI_METHOD -#endif - -enum { dvOriginal=0, dvLineEnd=1 }; - -class IDocument { -public: - virtual int SCI_METHOD Version() const = 0; - virtual void SCI_METHOD SetErrorStatus(int status) = 0; - virtual Sci_Position SCI_METHOD Length() const = 0; - virtual void SCI_METHOD GetCharRange(char *buffer, Sci_Position position, Sci_Position lengthRetrieve) const = 0; - virtual char SCI_METHOD StyleAt(Sci_Position position) const = 0; - virtual Sci_Position SCI_METHOD LineFromPosition(Sci_Position position) const = 0; - virtual Sci_Position SCI_METHOD LineStart(Sci_Position line) const = 0; - virtual int SCI_METHOD GetLevel(Sci_Position line) const = 0; - virtual int SCI_METHOD SetLevel(Sci_Position line, int level) = 0; - virtual int SCI_METHOD GetLineState(Sci_Position line) const = 0; - virtual int SCI_METHOD SetLineState(Sci_Position line, int state) = 0; - virtual void SCI_METHOD StartStyling(Sci_Position position, char mask) = 0; - virtual bool SCI_METHOD SetStyleFor(Sci_Position length, char style) = 0; - virtual bool SCI_METHOD SetStyles(Sci_Position length, const char *styles) = 0; - virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0; - virtual void SCI_METHOD DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) = 0; - virtual void SCI_METHOD ChangeLexerState(Sci_Position start, Sci_Position end) = 0; - virtual int SCI_METHOD CodePage() const = 0; - virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0; - virtual const char * SCI_METHOD BufferPointer() = 0; - virtual int SCI_METHOD GetLineIndentation(Sci_Position line) = 0; -}; - -class IDocumentWithLineEnd : public IDocument { -public: - virtual Sci_Position SCI_METHOD LineEnd(Sci_Position line) const = 0; - virtual Sci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const = 0; - virtual int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const = 0; -}; - -enum { lvOriginal=0, lvSubStyles=1 }; - -class ILexer { -public: - virtual int SCI_METHOD Version() const = 0; - virtual void SCI_METHOD Release() = 0; - virtual const char * SCI_METHOD PropertyNames() = 0; - virtual int SCI_METHOD PropertyType(const char *name) = 0; - virtual const char * SCI_METHOD DescribeProperty(const char *name) = 0; - virtual Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) = 0; - virtual const char * SCI_METHOD DescribeWordListSets() = 0; - virtual Sci_Position SCI_METHOD WordListSet(int n, const char *wl) = 0; - virtual void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) = 0; - virtual void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) = 0; - virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0; -}; - -class ILexerWithSubStyles : public ILexer { -public: - virtual int SCI_METHOD LineEndTypesSupported() = 0; - virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0; - virtual int SCI_METHOD SubStylesStart(int styleBase) = 0; - virtual int SCI_METHOD SubStylesLength(int styleBase) = 0; - virtual int SCI_METHOD StyleFromSubStyle(int subStyle) = 0; - virtual int SCI_METHOD PrimaryStyleFromStyle(int style) = 0; - virtual void SCI_METHOD FreeSubStyles() = 0; - virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0; - virtual int SCI_METHOD DistanceToSecondaryStyles() = 0; - virtual const char * SCI_METHOD GetSubStyleBases() = 0; -}; - -class ILoader { -public: - virtual int SCI_METHOD Release() = 0; - // Returns a status code from SC_STATUS_* - virtual int SCI_METHOD AddData(char *data, Sci_Position length) = 0; - virtual void * SCI_METHOD ConvertToDocument() = 0; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/include/Platform.h b/qrenderdoc/3rdparty/scintilla/include/Platform.h deleted file mode 100644 index 1ff48ecb1..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/Platform.h +++ /dev/null @@ -1,529 +0,0 @@ -// Scintilla source code edit control -/** @file Platform.h - ** Interface to platform facilities. Also includes some basic utilities. - ** Implemented in PlatGTK.cxx for GTK+/Linux, PlatWin.cxx for Windows, and PlatWX.cxx for wxWindows. - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef PLATFORM_H -#define PLATFORM_H - -// PLAT_GTK = GTK+ on Linux or Win32 -// PLAT_GTK_WIN32 is defined additionally when running PLAT_GTK under Win32 -// PLAT_WIN = Win32 API on Win32 OS -// PLAT_WX is wxWindows on any supported platform -// PLAT_TK = Tcl/TK on Linux or Win32 - -#define PLAT_GTK 0 -#define PLAT_GTK_WIN32 0 -#define PLAT_GTK_MACOSX 0 -#define PLAT_MACOSX 0 -#define PLAT_WIN 0 -#define PLAT_WX 0 -#define PLAT_QT 0 -#define PLAT_FOX 0 -#define PLAT_CURSES 0 -#define PLAT_TK 0 - -#if defined(FOX) -#undef PLAT_FOX -#define PLAT_FOX 1 - -#elif defined(__WX__) -#undef PLAT_WX -#define PLAT_WX 1 - -#elif defined(CURSES) -#undef PLAT_CURSES -#define PLAT_CURSES 1 - -#elif defined(SCINTILLA_QT) -#undef PLAT_QT -#define PLAT_QT 1 - -#elif defined(TK) -#undef PLAT_TK -#define PLAT_TK 1 - -#elif defined(GTK) -#undef PLAT_GTK -#define PLAT_GTK 1 - -#if defined(__WIN32__) || defined(_MSC_VER) -#undef PLAT_GTK_WIN32 -#define PLAT_GTK_WIN32 1 -#endif - -#if defined(__APPLE__) -#undef PLAT_GTK_MACOSX -#define PLAT_GTK_MACOSX 1 -#endif - -#elif defined(__APPLE__) - -#undef PLAT_MACOSX -#define PLAT_MACOSX 1 - -#else -#undef PLAT_WIN -#define PLAT_WIN 1 - -#endif - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -typedef float XYPOSITION; -typedef double XYACCUMULATOR; -inline int RoundXYPosition(XYPOSITION xyPos) { - return int(xyPos + 0.5); -} - -// Underlying the implementation of the platform classes are platform specific types. -// Sometimes these need to be passed around by client code so they are defined here - -typedef void *FontID; -typedef void *SurfaceID; -typedef void *WindowID; -typedef void *MenuID; -typedef void *TickerID; -typedef void *Function; -typedef void *IdlerID; - -/** - * A geometric point class. - * Point is similar to the Win32 POINT and GTK+ GdkPoint types. - */ -class Point { -public: - XYPOSITION x; - XYPOSITION y; - - explicit Point(XYPOSITION x_=0, XYPOSITION y_=0) : x(x_), y(y_) { - } - - static Point FromInts(int x_, int y_) { - return Point(static_cast(x_), static_cast(y_)); - } - - // Other automatically defined methods (assignment, copy constructor, destructor) are fine - - static Point FromLong(long lpoint); -}; - -/** - * A geometric rectangle class. - * PRectangle is similar to the Win32 RECT. - * PRectangles contain their top and left sides, but not their right and bottom sides. - */ -class PRectangle { -public: - XYPOSITION left; - XYPOSITION top; - XYPOSITION right; - XYPOSITION bottom; - - explicit PRectangle(XYPOSITION left_=0, XYPOSITION top_=0, XYPOSITION right_=0, XYPOSITION bottom_ = 0) : - left(left_), top(top_), right(right_), bottom(bottom_) { - } - - static PRectangle FromInts(int left_, int top_, int right_, int bottom_) { - return PRectangle(static_cast(left_), static_cast(top_), - static_cast(right_), static_cast(bottom_)); - } - - // Other automatically defined methods (assignment, copy constructor, destructor) are fine - - bool operator==(PRectangle &rc) const { - return (rc.left == left) && (rc.right == right) && - (rc.top == top) && (rc.bottom == bottom); - } - bool Contains(Point pt) const { - return (pt.x >= left) && (pt.x <= right) && - (pt.y >= top) && (pt.y <= bottom); - } - bool ContainsWholePixel(Point pt) const { - // Does the rectangle contain all of the pixel to left/below the point - return (pt.x >= left) && ((pt.x+1) <= right) && - (pt.y >= top) && ((pt.y+1) <= bottom); - } - bool Contains(PRectangle rc) const { - return (rc.left >= left) && (rc.right <= right) && - (rc.top >= top) && (rc.bottom <= bottom); - } - bool Intersects(PRectangle other) const { - return (right > other.left) && (left < other.right) && - (bottom > other.top) && (top < other.bottom); - } - void Move(XYPOSITION xDelta, XYPOSITION yDelta) { - left += xDelta; - top += yDelta; - right += xDelta; - bottom += yDelta; - } - XYPOSITION Width() const { return right - left; } - XYPOSITION Height() const { return bottom - top; } - bool Empty() const { - return (Height() <= 0) || (Width() <= 0); - } -}; - -/** - * Holds a desired RGB colour. - */ -class ColourDesired { - long co; -public: - ColourDesired(long lcol=0) { - co = lcol; - } - - ColourDesired(unsigned int red, unsigned int green, unsigned int blue) { - Set(red, green, blue); - } - - bool operator==(const ColourDesired &other) const { - return co == other.co; - } - - void Set(long lcol) { - co = lcol; - } - - void Set(unsigned int red, unsigned int green, unsigned int blue) { - co = red | (green << 8) | (blue << 16); - } - - static inline unsigned int ValueOfHex(const char ch) { - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else - return 0; - } - - void Set(const char *val) { - if (*val == '#') { - val++; - } - unsigned int r = ValueOfHex(val[0]) * 16 + ValueOfHex(val[1]); - unsigned int g = ValueOfHex(val[2]) * 16 + ValueOfHex(val[3]); - unsigned int b = ValueOfHex(val[4]) * 16 + ValueOfHex(val[5]); - Set(r, g, b); - } - - long AsLong() const { - return co; - } - - unsigned int GetRed() const { - return co & 0xff; - } - - unsigned int GetGreen() const { - return (co >> 8) & 0xff; - } - - unsigned int GetBlue() const { - return (co >> 16) & 0xff; - } -}; - -/** - * Font management. - */ - -struct FontParameters { - const char *faceName; - float size; - int weight; - bool italic; - int extraFontFlag; - int technology; - int characterSet; - - FontParameters( - const char *faceName_, - float size_=10, - int weight_=400, - bool italic_=false, - int extraFontFlag_=0, - int technology_=0, - int characterSet_=0) : - - faceName(faceName_), - size(size_), - weight(weight_), - italic(italic_), - extraFontFlag(extraFontFlag_), - technology(technology_), - characterSet(characterSet_) - { - } - -}; - -class Font { -protected: - FontID fid; - // Private so Font objects can not be copied - Font(const Font &); - Font &operator=(const Font &); -public: - Font(); - virtual ~Font(); - - virtual void Create(const FontParameters &fp); - virtual void Release(); - - FontID GetID() { return fid; } - // Alias another font - caller guarantees not to Release - void SetID(FontID fid_) { fid = fid_; } - friend class Surface; - friend class SurfaceImpl; -}; - -/** - * A surface abstracts a place to draw. - */ -class Surface { -private: - // Private so Surface objects can not be copied - Surface(const Surface &) {} - Surface &operator=(const Surface &) { return *this; } -public: - Surface() {} - virtual ~Surface() {} - static Surface *Allocate(int technology); - - virtual void Init(WindowID wid)=0; - virtual void Init(SurfaceID sid, WindowID wid)=0; - virtual void InitPixMap(int width, int height, Surface *surface_, WindowID wid)=0; - - virtual void Release()=0; - virtual bool Initialised()=0; - virtual void PenColour(ColourDesired fore)=0; - virtual int LogPixelsY()=0; - virtual int DeviceHeightFont(int points)=0; - virtual void MoveTo(int x_, int y_)=0; - virtual void LineTo(int x_, int y_)=0; - virtual void Polygon(Point *pts, int npts, ColourDesired fore, ColourDesired back)=0; - virtual void RectangleDraw(PRectangle rc, ColourDesired fore, ColourDesired back)=0; - virtual void FillRectangle(PRectangle rc, ColourDesired back)=0; - virtual void FillRectangle(PRectangle rc, Surface &surfacePattern)=0; - virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, ColourDesired back)=0; - virtual void AlphaRectangle(PRectangle rc, int cornerSize, ColourDesired fill, int alphaFill, - ColourDesired outline, int alphaOutline, int flags)=0; - virtual void DrawRGBAImage(PRectangle rc, int width, int height, const unsigned char *pixelsImage) = 0; - virtual void Ellipse(PRectangle rc, ColourDesired fore, ColourDesired back)=0; - virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource)=0; - - virtual void DrawTextNoClip(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; - virtual void DrawTextClipped(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore, ColourDesired back)=0; - virtual void DrawTextTransparent(PRectangle rc, Font &font_, XYPOSITION ybase, const char *s, int len, ColourDesired fore)=0; - virtual void MeasureWidths(Font &font_, const char *s, int len, XYPOSITION *positions)=0; - virtual XYPOSITION WidthText(Font &font_, const char *s, int len)=0; - virtual XYPOSITION WidthChar(Font &font_, char ch)=0; - virtual XYPOSITION Ascent(Font &font_)=0; - virtual XYPOSITION Descent(Font &font_)=0; - virtual XYPOSITION InternalLeading(Font &font_)=0; - virtual XYPOSITION ExternalLeading(Font &font_)=0; - virtual XYPOSITION Height(Font &font_)=0; - virtual XYPOSITION AverageCharWidth(Font &font_)=0; - - virtual void SetClip(PRectangle rc)=0; - virtual void FlushCachedState()=0; - - virtual void SetUnicodeMode(bool unicodeMode_)=0; - virtual void SetDBCSMode(int codePage)=0; -}; - -/** - * A simple callback action passing one piece of untyped user data. - */ -typedef void (*CallBackAction)(void*); - -/** - * Class to hide the details of window manipulation. - * Does not own the window which will normally have a longer life than this object. - */ -class Window { -protected: - WindowID wid; -public: - Window() : wid(0), cursorLast(cursorInvalid) { - } - Window(const Window &source) : wid(source.wid), cursorLast(cursorInvalid) { - } - virtual ~Window(); - Window &operator=(WindowID wid_) { - wid = wid_; - return *this; - } - WindowID GetID() const { return wid; } - bool Created() const { return wid != 0; } - void Destroy(); - bool HasFocus(); - PRectangle GetPosition(); - void SetPosition(PRectangle rc); - void SetPositionRelative(PRectangle rc, Window relativeTo); - PRectangle GetClientPosition(); - void Show(bool show=true); - void InvalidateAll(); - void InvalidateRectangle(PRectangle rc); - virtual void SetFont(Font &font); - enum Cursor { cursorInvalid, cursorText, cursorArrow, cursorUp, cursorWait, cursorHoriz, cursorVert, cursorReverseArrow, cursorHand }; - void SetCursor(Cursor curs); - void SetTitle(const char *s); - PRectangle GetMonitorRect(Point pt); -private: - Cursor cursorLast; -}; - -/** - * Listbox management. - */ - -class ListBox : public Window { -public: - ListBox(); - virtual ~ListBox(); - static ListBox *Allocate(); - - virtual void SetFont(Font &font)=0; - virtual void Create(Window &parent, int ctrlID, Point location, int lineHeight_, bool unicodeMode_, int technology_)=0; - virtual void SetAverageCharWidth(int width)=0; - virtual void SetVisibleRows(int rows)=0; - virtual int GetVisibleRows() const=0; - virtual PRectangle GetDesiredRect()=0; - virtual int CaretFromEdge()=0; - virtual void Clear()=0; - virtual void Append(char *s, int type = -1)=0; - virtual int Length()=0; - virtual void Select(int n)=0; - virtual int GetSelection()=0; - virtual int Find(const char *prefix)=0; - virtual void GetValue(int n, char *value, int len)=0; - virtual void RegisterImage(int type, const char *xpm_data)=0; - virtual void RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) = 0; - virtual void ClearRegisteredImages()=0; - virtual void SetDoubleClickAction(CallBackAction, void *)=0; - virtual void SetList(const char* list, char separator, char typesep)=0; -}; - -/** - * Menu management. - */ -class Menu { - MenuID mid; -public: - Menu(); - MenuID GetID() { return mid; } - void CreatePopUp(); - void Destroy(); - void Show(Point pt, Window &w); -}; - -class ElapsedTime { - long bigBit; - long littleBit; -public: - ElapsedTime(); - double Duration(bool reset=false); -}; - -/** - * Dynamic Library (DLL/SO/...) loading - */ -class DynamicLibrary { -public: - virtual ~DynamicLibrary() {} - - /// @return Pointer to function "name", or NULL on failure. - virtual Function FindFunction(const char *name) = 0; - - /// @return true if the library was loaded successfully. - virtual bool IsValid() = 0; - - /// @return An instance of a DynamicLibrary subclass with "modulePath" loaded. - static DynamicLibrary *Load(const char *modulePath); -}; - -#if defined(__clang__) -# if __has_feature(attribute_analyzer_noreturn) -# define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) -# else -# define CLANG_ANALYZER_NORETURN -# endif -#else -# define CLANG_ANALYZER_NORETURN -#endif - -/** - * Platform class used to retrieve system wide parameters such as double click speed - * and chrome colour. Not a creatable object, more of a module with several functions. - */ -class Platform { - // Private so Platform objects can not be copied - Platform(const Platform &) {} - Platform &operator=(const Platform &) { return *this; } -public: - // Should be private because no new Platforms are ever created - // but gcc warns about this - Platform() {} - ~Platform() {} - static ColourDesired Chrome(); - static ColourDesired ChromeHighlight(); - static const char *DefaultFont(); - static int DefaultFontSize(); - static unsigned int DoubleClickTime(); - static bool MouseButtonBounce(); - static void DebugDisplay(const char *s); - static bool IsKeyDown(int key); - static long SendScintilla( - WindowID w, unsigned int msg, unsigned long wParam=0, long lParam=0); - static long SendScintillaPointer( - WindowID w, unsigned int msg, unsigned long wParam=0, void *lParam=0); - static bool IsDBCSLeadByte(int codePage, char ch); - static int DBCSCharLength(int codePage, const char *s); - static int DBCSCharMaxLength(); - - // These are utility functions not really tied to a platform - static int Minimum(int a, int b); - static int Maximum(int a, int b); - // Next three assume 16 bit shorts and 32 bit longs - static long LongFromTwoShorts(short a,short b) { - return (a) | ((b) << 16); - } - static short HighShortFromLong(long x) { - return static_cast(x >> 16); - } - static short LowShortFromLong(long x) { - return static_cast(x & 0xffff); - } - static void DebugPrintf(const char *format, ...); - static bool ShowAssertionPopUps(bool assertionPopUps_); - static void Assert(const char *c, const char *file, int line) CLANG_ANALYZER_NORETURN; - static int Clamp(int val, int minVal, int maxVal); -}; - -#ifdef NDEBUG -#define PLATFORM_ASSERT(c) ((void)0) -#else -#ifdef SCI_NAMESPACE -#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Scintilla::Platform::Assert(#c, __FILE__, __LINE__)) -#else -#define PLATFORM_ASSERT(c) ((c) ? (void)(0) : Platform::Assert(#c, __FILE__, __LINE__)) -#endif -#endif - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/include/SciLexer.h b/qrenderdoc/3rdparty/scintilla/include/SciLexer.h deleted file mode 100644 index 44c02a84a..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/SciLexer.h +++ /dev/null @@ -1,1812 +0,0 @@ -/* Scintilla source code edit control */ -/** @file SciLexer.h - ** Interface to the added lexer functions in the SciLexer version of the edit control. - **/ -/* Copyright 1998-2002 by Neil Hodgson - * The License.txt file describes the conditions under which this software may be distributed. */ - -/* Most of this file is automatically generated from the Scintilla.iface interface definition - * file which contains any comments about the definitions. HFacer.py does the generation. */ - -#ifndef SCILEXER_H -#define SCILEXER_H - -/* SciLexer features - not in standard Scintilla */ - -/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ -#define SCLEX_CONTAINER 0 -#define SCLEX_NULL 1 -#define SCLEX_PYTHON 2 -#define SCLEX_CPP 3 -#define SCLEX_HTML 4 -#define SCLEX_XML 5 -#define SCLEX_PERL 6 -#define SCLEX_SQL 7 -#define SCLEX_VB 8 -#define SCLEX_PROPERTIES 9 -#define SCLEX_ERRORLIST 10 -#define SCLEX_MAKEFILE 11 -#define SCLEX_BATCH 12 -#define SCLEX_XCODE 13 -#define SCLEX_LATEX 14 -#define SCLEX_LUA 15 -#define SCLEX_DIFF 16 -#define SCLEX_CONF 17 -#define SCLEX_PASCAL 18 -#define SCLEX_AVE 19 -#define SCLEX_ADA 20 -#define SCLEX_LISP 21 -#define SCLEX_RUBY 22 -#define SCLEX_EIFFEL 23 -#define SCLEX_EIFFELKW 24 -#define SCLEX_TCL 25 -#define SCLEX_NNCRONTAB 26 -#define SCLEX_BULLANT 27 -#define SCLEX_VBSCRIPT 28 -#define SCLEX_BAAN 31 -#define SCLEX_MATLAB 32 -#define SCLEX_SCRIPTOL 33 -#define SCLEX_ASM 34 -#define SCLEX_CPPNOCASE 35 -#define SCLEX_FORTRAN 36 -#define SCLEX_F77 37 -#define SCLEX_CSS 38 -#define SCLEX_POV 39 -#define SCLEX_LOUT 40 -#define SCLEX_ESCRIPT 41 -#define SCLEX_PS 42 -#define SCLEX_NSIS 43 -#define SCLEX_MMIXAL 44 -#define SCLEX_CLW 45 -#define SCLEX_CLWNOCASE 46 -#define SCLEX_LOT 47 -#define SCLEX_YAML 48 -#define SCLEX_TEX 49 -#define SCLEX_METAPOST 50 -#define SCLEX_POWERBASIC 51 -#define SCLEX_FORTH 52 -#define SCLEX_ERLANG 53 -#define SCLEX_OCTAVE 54 -#define SCLEX_MSSQL 55 -#define SCLEX_VERILOG 56 -#define SCLEX_KIX 57 -#define SCLEX_GUI4CLI 58 -#define SCLEX_SPECMAN 59 -#define SCLEX_AU3 60 -#define SCLEX_APDL 61 -#define SCLEX_BASH 62 -#define SCLEX_ASN1 63 -#define SCLEX_VHDL 64 -#define SCLEX_CAML 65 -#define SCLEX_BLITZBASIC 66 -#define SCLEX_PUREBASIC 67 -#define SCLEX_HASKELL 68 -#define SCLEX_PHPSCRIPT 69 -#define SCLEX_TADS3 70 -#define SCLEX_REBOL 71 -#define SCLEX_SMALLTALK 72 -#define SCLEX_FLAGSHIP 73 -#define SCLEX_CSOUND 74 -#define SCLEX_FREEBASIC 75 -#define SCLEX_INNOSETUP 76 -#define SCLEX_OPAL 77 -#define SCLEX_SPICE 78 -#define SCLEX_D 79 -#define SCLEX_CMAKE 80 -#define SCLEX_GAP 81 -#define SCLEX_PLM 82 -#define SCLEX_PROGRESS 83 -#define SCLEX_ABAQUS 84 -#define SCLEX_ASYMPTOTE 85 -#define SCLEX_R 86 -#define SCLEX_MAGIK 87 -#define SCLEX_POWERSHELL 88 -#define SCLEX_MYSQL 89 -#define SCLEX_PO 90 -#define SCLEX_TAL 91 -#define SCLEX_COBOL 92 -#define SCLEX_TACL 93 -#define SCLEX_SORCUS 94 -#define SCLEX_POWERPRO 95 -#define SCLEX_NIMROD 96 -#define SCLEX_SML 97 -#define SCLEX_MARKDOWN 98 -#define SCLEX_TXT2TAGS 99 -#define SCLEX_A68K 100 -#define SCLEX_MODULA 101 -#define SCLEX_COFFEESCRIPT 102 -#define SCLEX_TCMD 103 -#define SCLEX_AVS 104 -#define SCLEX_ECL 105 -#define SCLEX_OSCRIPT 106 -#define SCLEX_VISUALPROLOG 107 -#define SCLEX_LITERATEHASKELL 108 -#define SCLEX_STTXT 109 -#define SCLEX_KVIRC 110 -#define SCLEX_RUST 111 -#define SCLEX_DMAP 112 -#define SCLEX_AS 113 -#define SCLEX_DMIS 114 -#define SCLEX_REGISTRY 115 -#define SCLEX_BIBTEX 116 -#define SCLEX_SREC 117 -#define SCLEX_IHEX 118 -#define SCLEX_TEHEX 119 -#define SCLEX_JSON 120 -#define SCLEX_EDIFACT 121 -#define SCLEX_AUTOMATIC 1000 -#define SCE_P_DEFAULT 0 -#define SCE_P_COMMENTLINE 1 -#define SCE_P_NUMBER 2 -#define SCE_P_STRING 3 -#define SCE_P_CHARACTER 4 -#define SCE_P_WORD 5 -#define SCE_P_TRIPLE 6 -#define SCE_P_TRIPLEDOUBLE 7 -#define SCE_P_CLASSNAME 8 -#define SCE_P_DEFNAME 9 -#define SCE_P_OPERATOR 10 -#define SCE_P_IDENTIFIER 11 -#define SCE_P_COMMENTBLOCK 12 -#define SCE_P_STRINGEOL 13 -#define SCE_P_WORD2 14 -#define SCE_P_DECORATOR 15 -#define SCE_C_DEFAULT 0 -#define SCE_C_COMMENT 1 -#define SCE_C_COMMENTLINE 2 -#define SCE_C_COMMENTDOC 3 -#define SCE_C_NUMBER 4 -#define SCE_C_WORD 5 -#define SCE_C_STRING 6 -#define SCE_C_CHARACTER 7 -#define SCE_C_UUID 8 -#define SCE_C_PREPROCESSOR 9 -#define SCE_C_OPERATOR 10 -#define SCE_C_IDENTIFIER 11 -#define SCE_C_STRINGEOL 12 -#define SCE_C_VERBATIM 13 -#define SCE_C_REGEX 14 -#define SCE_C_COMMENTLINEDOC 15 -#define SCE_C_WORD2 16 -#define SCE_C_COMMENTDOCKEYWORD 17 -#define SCE_C_COMMENTDOCKEYWORDERROR 18 -#define SCE_C_GLOBALCLASS 19 -#define SCE_C_STRINGRAW 20 -#define SCE_C_TRIPLEVERBATIM 21 -#define SCE_C_HASHQUOTEDSTRING 22 -#define SCE_C_PREPROCESSORCOMMENT 23 -#define SCE_C_PREPROCESSORCOMMENTDOC 24 -#define SCE_C_USERLITERAL 25 -#define SCE_C_TASKMARKER 26 -#define SCE_C_ESCAPESEQUENCE 27 -#define SCE_D_DEFAULT 0 -#define SCE_D_COMMENT 1 -#define SCE_D_COMMENTLINE 2 -#define SCE_D_COMMENTDOC 3 -#define SCE_D_COMMENTNESTED 4 -#define SCE_D_NUMBER 5 -#define SCE_D_WORD 6 -#define SCE_D_WORD2 7 -#define SCE_D_WORD3 8 -#define SCE_D_TYPEDEF 9 -#define SCE_D_STRING 10 -#define SCE_D_STRINGEOL 11 -#define SCE_D_CHARACTER 12 -#define SCE_D_OPERATOR 13 -#define SCE_D_IDENTIFIER 14 -#define SCE_D_COMMENTLINEDOC 15 -#define SCE_D_COMMENTDOCKEYWORD 16 -#define SCE_D_COMMENTDOCKEYWORDERROR 17 -#define SCE_D_STRINGB 18 -#define SCE_D_STRINGR 19 -#define SCE_D_WORD5 20 -#define SCE_D_WORD6 21 -#define SCE_D_WORD7 22 -#define SCE_TCL_DEFAULT 0 -#define SCE_TCL_COMMENT 1 -#define SCE_TCL_COMMENTLINE 2 -#define SCE_TCL_NUMBER 3 -#define SCE_TCL_WORD_IN_QUOTE 4 -#define SCE_TCL_IN_QUOTE 5 -#define SCE_TCL_OPERATOR 6 -#define SCE_TCL_IDENTIFIER 7 -#define SCE_TCL_SUBSTITUTION 8 -#define SCE_TCL_SUB_BRACE 9 -#define SCE_TCL_MODIFIER 10 -#define SCE_TCL_EXPAND 11 -#define SCE_TCL_WORD 12 -#define SCE_TCL_WORD2 13 -#define SCE_TCL_WORD3 14 -#define SCE_TCL_WORD4 15 -#define SCE_TCL_WORD5 16 -#define SCE_TCL_WORD6 17 -#define SCE_TCL_WORD7 18 -#define SCE_TCL_WORD8 19 -#define SCE_TCL_COMMENT_BOX 20 -#define SCE_TCL_BLOCK_COMMENT 21 -#define SCE_H_DEFAULT 0 -#define SCE_H_TAG 1 -#define SCE_H_TAGUNKNOWN 2 -#define SCE_H_ATTRIBUTE 3 -#define SCE_H_ATTRIBUTEUNKNOWN 4 -#define SCE_H_NUMBER 5 -#define SCE_H_DOUBLESTRING 6 -#define SCE_H_SINGLESTRING 7 -#define SCE_H_OTHER 8 -#define SCE_H_COMMENT 9 -#define SCE_H_ENTITY 10 -#define SCE_H_TAGEND 11 -#define SCE_H_XMLSTART 12 -#define SCE_H_XMLEND 13 -#define SCE_H_SCRIPT 14 -#define SCE_H_ASP 15 -#define SCE_H_ASPAT 16 -#define SCE_H_CDATA 17 -#define SCE_H_QUESTION 18 -#define SCE_H_VALUE 19 -#define SCE_H_XCCOMMENT 20 -#define SCE_H_SGML_DEFAULT 21 -#define SCE_H_SGML_COMMAND 22 -#define SCE_H_SGML_1ST_PARAM 23 -#define SCE_H_SGML_DOUBLESTRING 24 -#define SCE_H_SGML_SIMPLESTRING 25 -#define SCE_H_SGML_ERROR 26 -#define SCE_H_SGML_SPECIAL 27 -#define SCE_H_SGML_ENTITY 28 -#define SCE_H_SGML_COMMENT 29 -#define SCE_H_SGML_1ST_PARAM_COMMENT 30 -#define SCE_H_SGML_BLOCK_DEFAULT 31 -#define SCE_HJ_START 40 -#define SCE_HJ_DEFAULT 41 -#define SCE_HJ_COMMENT 42 -#define SCE_HJ_COMMENTLINE 43 -#define SCE_HJ_COMMENTDOC 44 -#define SCE_HJ_NUMBER 45 -#define SCE_HJ_WORD 46 -#define SCE_HJ_KEYWORD 47 -#define SCE_HJ_DOUBLESTRING 48 -#define SCE_HJ_SINGLESTRING 49 -#define SCE_HJ_SYMBOLS 50 -#define SCE_HJ_STRINGEOL 51 -#define SCE_HJ_REGEX 52 -#define SCE_HJA_START 55 -#define SCE_HJA_DEFAULT 56 -#define SCE_HJA_COMMENT 57 -#define SCE_HJA_COMMENTLINE 58 -#define SCE_HJA_COMMENTDOC 59 -#define SCE_HJA_NUMBER 60 -#define SCE_HJA_WORD 61 -#define SCE_HJA_KEYWORD 62 -#define SCE_HJA_DOUBLESTRING 63 -#define SCE_HJA_SINGLESTRING 64 -#define SCE_HJA_SYMBOLS 65 -#define SCE_HJA_STRINGEOL 66 -#define SCE_HJA_REGEX 67 -#define SCE_HB_START 70 -#define SCE_HB_DEFAULT 71 -#define SCE_HB_COMMENTLINE 72 -#define SCE_HB_NUMBER 73 -#define SCE_HB_WORD 74 -#define SCE_HB_STRING 75 -#define SCE_HB_IDENTIFIER 76 -#define SCE_HB_STRINGEOL 77 -#define SCE_HBA_START 80 -#define SCE_HBA_DEFAULT 81 -#define SCE_HBA_COMMENTLINE 82 -#define SCE_HBA_NUMBER 83 -#define SCE_HBA_WORD 84 -#define SCE_HBA_STRING 85 -#define SCE_HBA_IDENTIFIER 86 -#define SCE_HBA_STRINGEOL 87 -#define SCE_HP_START 90 -#define SCE_HP_DEFAULT 91 -#define SCE_HP_COMMENTLINE 92 -#define SCE_HP_NUMBER 93 -#define SCE_HP_STRING 94 -#define SCE_HP_CHARACTER 95 -#define SCE_HP_WORD 96 -#define SCE_HP_TRIPLE 97 -#define SCE_HP_TRIPLEDOUBLE 98 -#define SCE_HP_CLASSNAME 99 -#define SCE_HP_DEFNAME 100 -#define SCE_HP_OPERATOR 101 -#define SCE_HP_IDENTIFIER 102 -#define SCE_HPHP_COMPLEX_VARIABLE 104 -#define SCE_HPA_START 105 -#define SCE_HPA_DEFAULT 106 -#define SCE_HPA_COMMENTLINE 107 -#define SCE_HPA_NUMBER 108 -#define SCE_HPA_STRING 109 -#define SCE_HPA_CHARACTER 110 -#define SCE_HPA_WORD 111 -#define SCE_HPA_TRIPLE 112 -#define SCE_HPA_TRIPLEDOUBLE 113 -#define SCE_HPA_CLASSNAME 114 -#define SCE_HPA_DEFNAME 115 -#define SCE_HPA_OPERATOR 116 -#define SCE_HPA_IDENTIFIER 117 -#define SCE_HPHP_DEFAULT 118 -#define SCE_HPHP_HSTRING 119 -#define SCE_HPHP_SIMPLESTRING 120 -#define SCE_HPHP_WORD 121 -#define SCE_HPHP_NUMBER 122 -#define SCE_HPHP_VARIABLE 123 -#define SCE_HPHP_COMMENT 124 -#define SCE_HPHP_COMMENTLINE 125 -#define SCE_HPHP_HSTRING_VARIABLE 126 -#define SCE_HPHP_OPERATOR 127 -#define SCE_PL_DEFAULT 0 -#define SCE_PL_ERROR 1 -#define SCE_PL_COMMENTLINE 2 -#define SCE_PL_POD 3 -#define SCE_PL_NUMBER 4 -#define SCE_PL_WORD 5 -#define SCE_PL_STRING 6 -#define SCE_PL_CHARACTER 7 -#define SCE_PL_PUNCTUATION 8 -#define SCE_PL_PREPROCESSOR 9 -#define SCE_PL_OPERATOR 10 -#define SCE_PL_IDENTIFIER 11 -#define SCE_PL_SCALAR 12 -#define SCE_PL_ARRAY 13 -#define SCE_PL_HASH 14 -#define SCE_PL_SYMBOLTABLE 15 -#define SCE_PL_VARIABLE_INDEXER 16 -#define SCE_PL_REGEX 17 -#define SCE_PL_REGSUBST 18 -#define SCE_PL_LONGQUOTE 19 -#define SCE_PL_BACKTICKS 20 -#define SCE_PL_DATASECTION 21 -#define SCE_PL_HERE_DELIM 22 -#define SCE_PL_HERE_Q 23 -#define SCE_PL_HERE_QQ 24 -#define SCE_PL_HERE_QX 25 -#define SCE_PL_STRING_Q 26 -#define SCE_PL_STRING_QQ 27 -#define SCE_PL_STRING_QX 28 -#define SCE_PL_STRING_QR 29 -#define SCE_PL_STRING_QW 30 -#define SCE_PL_POD_VERB 31 -#define SCE_PL_SUB_PROTOTYPE 40 -#define SCE_PL_FORMAT_IDENT 41 -#define SCE_PL_FORMAT 42 -#define SCE_PL_STRING_VAR 43 -#define SCE_PL_XLAT 44 -#define SCE_PL_REGEX_VAR 54 -#define SCE_PL_REGSUBST_VAR 55 -#define SCE_PL_BACKTICKS_VAR 57 -#define SCE_PL_HERE_QQ_VAR 61 -#define SCE_PL_HERE_QX_VAR 62 -#define SCE_PL_STRING_QQ_VAR 64 -#define SCE_PL_STRING_QX_VAR 65 -#define SCE_PL_STRING_QR_VAR 66 -#define SCE_RB_DEFAULT 0 -#define SCE_RB_ERROR 1 -#define SCE_RB_COMMENTLINE 2 -#define SCE_RB_POD 3 -#define SCE_RB_NUMBER 4 -#define SCE_RB_WORD 5 -#define SCE_RB_STRING 6 -#define SCE_RB_CHARACTER 7 -#define SCE_RB_CLASSNAME 8 -#define SCE_RB_DEFNAME 9 -#define SCE_RB_OPERATOR 10 -#define SCE_RB_IDENTIFIER 11 -#define SCE_RB_REGEX 12 -#define SCE_RB_GLOBAL 13 -#define SCE_RB_SYMBOL 14 -#define SCE_RB_MODULE_NAME 15 -#define SCE_RB_INSTANCE_VAR 16 -#define SCE_RB_CLASS_VAR 17 -#define SCE_RB_BACKTICKS 18 -#define SCE_RB_DATASECTION 19 -#define SCE_RB_HERE_DELIM 20 -#define SCE_RB_HERE_Q 21 -#define SCE_RB_HERE_QQ 22 -#define SCE_RB_HERE_QX 23 -#define SCE_RB_STRING_Q 24 -#define SCE_RB_STRING_QQ 25 -#define SCE_RB_STRING_QX 26 -#define SCE_RB_STRING_QR 27 -#define SCE_RB_STRING_QW 28 -#define SCE_RB_WORD_DEMOTED 29 -#define SCE_RB_STDIN 30 -#define SCE_RB_STDOUT 31 -#define SCE_RB_STDERR 40 -#define SCE_RB_UPPER_BOUND 41 -#define SCE_B_DEFAULT 0 -#define SCE_B_COMMENT 1 -#define SCE_B_NUMBER 2 -#define SCE_B_KEYWORD 3 -#define SCE_B_STRING 4 -#define SCE_B_PREPROCESSOR 5 -#define SCE_B_OPERATOR 6 -#define SCE_B_IDENTIFIER 7 -#define SCE_B_DATE 8 -#define SCE_B_STRINGEOL 9 -#define SCE_B_KEYWORD2 10 -#define SCE_B_KEYWORD3 11 -#define SCE_B_KEYWORD4 12 -#define SCE_B_CONSTANT 13 -#define SCE_B_ASM 14 -#define SCE_B_LABEL 15 -#define SCE_B_ERROR 16 -#define SCE_B_HEXNUMBER 17 -#define SCE_B_BINNUMBER 18 -#define SCE_B_COMMENTBLOCK 19 -#define SCE_B_DOCLINE 20 -#define SCE_B_DOCBLOCK 21 -#define SCE_B_DOCKEYWORD 22 -#define SCE_PROPS_DEFAULT 0 -#define SCE_PROPS_COMMENT 1 -#define SCE_PROPS_SECTION 2 -#define SCE_PROPS_ASSIGNMENT 3 -#define SCE_PROPS_DEFVAL 4 -#define SCE_PROPS_KEY 5 -#define SCE_L_DEFAULT 0 -#define SCE_L_COMMAND 1 -#define SCE_L_TAG 2 -#define SCE_L_MATH 3 -#define SCE_L_COMMENT 4 -#define SCE_L_TAG2 5 -#define SCE_L_MATH2 6 -#define SCE_L_COMMENT2 7 -#define SCE_L_VERBATIM 8 -#define SCE_L_SHORTCMD 9 -#define SCE_L_SPECIAL 10 -#define SCE_L_CMDOPT 11 -#define SCE_L_ERROR 12 -#define SCE_LUA_DEFAULT 0 -#define SCE_LUA_COMMENT 1 -#define SCE_LUA_COMMENTLINE 2 -#define SCE_LUA_COMMENTDOC 3 -#define SCE_LUA_NUMBER 4 -#define SCE_LUA_WORD 5 -#define SCE_LUA_STRING 6 -#define SCE_LUA_CHARACTER 7 -#define SCE_LUA_LITERALSTRING 8 -#define SCE_LUA_PREPROCESSOR 9 -#define SCE_LUA_OPERATOR 10 -#define SCE_LUA_IDENTIFIER 11 -#define SCE_LUA_STRINGEOL 12 -#define SCE_LUA_WORD2 13 -#define SCE_LUA_WORD3 14 -#define SCE_LUA_WORD4 15 -#define SCE_LUA_WORD5 16 -#define SCE_LUA_WORD6 17 -#define SCE_LUA_WORD7 18 -#define SCE_LUA_WORD8 19 -#define SCE_LUA_LABEL 20 -#define SCE_ERR_DEFAULT 0 -#define SCE_ERR_PYTHON 1 -#define SCE_ERR_GCC 2 -#define SCE_ERR_MS 3 -#define SCE_ERR_CMD 4 -#define SCE_ERR_BORLAND 5 -#define SCE_ERR_PERL 6 -#define SCE_ERR_NET 7 -#define SCE_ERR_LUA 8 -#define SCE_ERR_CTAG 9 -#define SCE_ERR_DIFF_CHANGED 10 -#define SCE_ERR_DIFF_ADDITION 11 -#define SCE_ERR_DIFF_DELETION 12 -#define SCE_ERR_DIFF_MESSAGE 13 -#define SCE_ERR_PHP 14 -#define SCE_ERR_ELF 15 -#define SCE_ERR_IFC 16 -#define SCE_ERR_IFORT 17 -#define SCE_ERR_ABSF 18 -#define SCE_ERR_TIDY 19 -#define SCE_ERR_JAVA_STACK 20 -#define SCE_ERR_VALUE 21 -#define SCE_ERR_GCC_INCLUDED_FROM 22 -#define SCE_ERR_ESCSEQ 23 -#define SCE_ERR_ESCSEQ_UNKNOWN 24 -#define SCE_ERR_ES_BLACK 40 -#define SCE_ERR_ES_RED 41 -#define SCE_ERR_ES_GREEN 42 -#define SCE_ERR_ES_BROWN 43 -#define SCE_ERR_ES_BLUE 44 -#define SCE_ERR_ES_MAGENTA 45 -#define SCE_ERR_ES_CYAN 46 -#define SCE_ERR_ES_GRAY 47 -#define SCE_ERR_ES_DARK_GRAY 48 -#define SCE_ERR_ES_BRIGHT_RED 49 -#define SCE_ERR_ES_BRIGHT_GREEN 50 -#define SCE_ERR_ES_YELLOW 51 -#define SCE_ERR_ES_BRIGHT_BLUE 52 -#define SCE_ERR_ES_BRIGHT_MAGENTA 53 -#define SCE_ERR_ES_BRIGHT_CYAN 54 -#define SCE_ERR_ES_WHITE 55 -#define SCE_BAT_DEFAULT 0 -#define SCE_BAT_COMMENT 1 -#define SCE_BAT_WORD 2 -#define SCE_BAT_LABEL 3 -#define SCE_BAT_HIDE 4 -#define SCE_BAT_COMMAND 5 -#define SCE_BAT_IDENTIFIER 6 -#define SCE_BAT_OPERATOR 7 -#define SCE_TCMD_DEFAULT 0 -#define SCE_TCMD_COMMENT 1 -#define SCE_TCMD_WORD 2 -#define SCE_TCMD_LABEL 3 -#define SCE_TCMD_HIDE 4 -#define SCE_TCMD_COMMAND 5 -#define SCE_TCMD_IDENTIFIER 6 -#define SCE_TCMD_OPERATOR 7 -#define SCE_TCMD_ENVIRONMENT 8 -#define SCE_TCMD_EXPANSION 9 -#define SCE_TCMD_CLABEL 10 -#define SCE_MAKE_DEFAULT 0 -#define SCE_MAKE_COMMENT 1 -#define SCE_MAKE_PREPROCESSOR 2 -#define SCE_MAKE_IDENTIFIER 3 -#define SCE_MAKE_OPERATOR 4 -#define SCE_MAKE_TARGET 5 -#define SCE_MAKE_IDEOL 9 -#define SCE_DIFF_DEFAULT 0 -#define SCE_DIFF_COMMENT 1 -#define SCE_DIFF_COMMAND 2 -#define SCE_DIFF_HEADER 3 -#define SCE_DIFF_POSITION 4 -#define SCE_DIFF_DELETED 5 -#define SCE_DIFF_ADDED 6 -#define SCE_DIFF_CHANGED 7 -#define SCE_CONF_DEFAULT 0 -#define SCE_CONF_COMMENT 1 -#define SCE_CONF_NUMBER 2 -#define SCE_CONF_IDENTIFIER 3 -#define SCE_CONF_EXTENSION 4 -#define SCE_CONF_PARAMETER 5 -#define SCE_CONF_STRING 6 -#define SCE_CONF_OPERATOR 7 -#define SCE_CONF_IP 8 -#define SCE_CONF_DIRECTIVE 9 -#define SCE_AVE_DEFAULT 0 -#define SCE_AVE_COMMENT 1 -#define SCE_AVE_NUMBER 2 -#define SCE_AVE_WORD 3 -#define SCE_AVE_STRING 6 -#define SCE_AVE_ENUM 7 -#define SCE_AVE_STRINGEOL 8 -#define SCE_AVE_IDENTIFIER 9 -#define SCE_AVE_OPERATOR 10 -#define SCE_AVE_WORD1 11 -#define SCE_AVE_WORD2 12 -#define SCE_AVE_WORD3 13 -#define SCE_AVE_WORD4 14 -#define SCE_AVE_WORD5 15 -#define SCE_AVE_WORD6 16 -#define SCE_ADA_DEFAULT 0 -#define SCE_ADA_WORD 1 -#define SCE_ADA_IDENTIFIER 2 -#define SCE_ADA_NUMBER 3 -#define SCE_ADA_DELIMITER 4 -#define SCE_ADA_CHARACTER 5 -#define SCE_ADA_CHARACTEREOL 6 -#define SCE_ADA_STRING 7 -#define SCE_ADA_STRINGEOL 8 -#define SCE_ADA_LABEL 9 -#define SCE_ADA_COMMENTLINE 10 -#define SCE_ADA_ILLEGAL 11 -#define SCE_BAAN_DEFAULT 0 -#define SCE_BAAN_COMMENT 1 -#define SCE_BAAN_COMMENTDOC 2 -#define SCE_BAAN_NUMBER 3 -#define SCE_BAAN_WORD 4 -#define SCE_BAAN_STRING 5 -#define SCE_BAAN_PREPROCESSOR 6 -#define SCE_BAAN_OPERATOR 7 -#define SCE_BAAN_IDENTIFIER 8 -#define SCE_BAAN_STRINGEOL 9 -#define SCE_BAAN_WORD2 10 -#define SCE_BAAN_WORD3 11 -#define SCE_BAAN_WORD4 12 -#define SCE_BAAN_WORD5 13 -#define SCE_BAAN_WORD6 14 -#define SCE_BAAN_WORD7 15 -#define SCE_BAAN_WORD8 16 -#define SCE_BAAN_WORD9 17 -#define SCE_BAAN_TABLEDEF 18 -#define SCE_BAAN_TABLESQL 19 -#define SCE_BAAN_FUNCTION 20 -#define SCE_BAAN_DOMDEF 21 -#define SCE_BAAN_FUNCDEF 22 -#define SCE_BAAN_OBJECTDEF 23 -#define SCE_BAAN_DEFINEDEF 24 -#define SCE_LISP_DEFAULT 0 -#define SCE_LISP_COMMENT 1 -#define SCE_LISP_NUMBER 2 -#define SCE_LISP_KEYWORD 3 -#define SCE_LISP_KEYWORD_KW 4 -#define SCE_LISP_SYMBOL 5 -#define SCE_LISP_STRING 6 -#define SCE_LISP_STRINGEOL 8 -#define SCE_LISP_IDENTIFIER 9 -#define SCE_LISP_OPERATOR 10 -#define SCE_LISP_SPECIAL 11 -#define SCE_LISP_MULTI_COMMENT 12 -#define SCE_EIFFEL_DEFAULT 0 -#define SCE_EIFFEL_COMMENTLINE 1 -#define SCE_EIFFEL_NUMBER 2 -#define SCE_EIFFEL_WORD 3 -#define SCE_EIFFEL_STRING 4 -#define SCE_EIFFEL_CHARACTER 5 -#define SCE_EIFFEL_OPERATOR 6 -#define SCE_EIFFEL_IDENTIFIER 7 -#define SCE_EIFFEL_STRINGEOL 8 -#define SCE_NNCRONTAB_DEFAULT 0 -#define SCE_NNCRONTAB_COMMENT 1 -#define SCE_NNCRONTAB_TASK 2 -#define SCE_NNCRONTAB_SECTION 3 -#define SCE_NNCRONTAB_KEYWORD 4 -#define SCE_NNCRONTAB_MODIFIER 5 -#define SCE_NNCRONTAB_ASTERISK 6 -#define SCE_NNCRONTAB_NUMBER 7 -#define SCE_NNCRONTAB_STRING 8 -#define SCE_NNCRONTAB_ENVIRONMENT 9 -#define SCE_NNCRONTAB_IDENTIFIER 10 -#define SCE_FORTH_DEFAULT 0 -#define SCE_FORTH_COMMENT 1 -#define SCE_FORTH_COMMENT_ML 2 -#define SCE_FORTH_IDENTIFIER 3 -#define SCE_FORTH_CONTROL 4 -#define SCE_FORTH_KEYWORD 5 -#define SCE_FORTH_DEFWORD 6 -#define SCE_FORTH_PREWORD1 7 -#define SCE_FORTH_PREWORD2 8 -#define SCE_FORTH_NUMBER 9 -#define SCE_FORTH_STRING 10 -#define SCE_FORTH_LOCALE 11 -#define SCE_MATLAB_DEFAULT 0 -#define SCE_MATLAB_COMMENT 1 -#define SCE_MATLAB_COMMAND 2 -#define SCE_MATLAB_NUMBER 3 -#define SCE_MATLAB_KEYWORD 4 -#define SCE_MATLAB_STRING 5 -#define SCE_MATLAB_OPERATOR 6 -#define SCE_MATLAB_IDENTIFIER 7 -#define SCE_MATLAB_DOUBLEQUOTESTRING 8 -#define SCE_SCRIPTOL_DEFAULT 0 -#define SCE_SCRIPTOL_WHITE 1 -#define SCE_SCRIPTOL_COMMENTLINE 2 -#define SCE_SCRIPTOL_PERSISTENT 3 -#define SCE_SCRIPTOL_CSTYLE 4 -#define SCE_SCRIPTOL_COMMENTBLOCK 5 -#define SCE_SCRIPTOL_NUMBER 6 -#define SCE_SCRIPTOL_STRING 7 -#define SCE_SCRIPTOL_CHARACTER 8 -#define SCE_SCRIPTOL_STRINGEOL 9 -#define SCE_SCRIPTOL_KEYWORD 10 -#define SCE_SCRIPTOL_OPERATOR 11 -#define SCE_SCRIPTOL_IDENTIFIER 12 -#define SCE_SCRIPTOL_TRIPLE 13 -#define SCE_SCRIPTOL_CLASSNAME 14 -#define SCE_SCRIPTOL_PREPROCESSOR 15 -#define SCE_ASM_DEFAULT 0 -#define SCE_ASM_COMMENT 1 -#define SCE_ASM_NUMBER 2 -#define SCE_ASM_STRING 3 -#define SCE_ASM_OPERATOR 4 -#define SCE_ASM_IDENTIFIER 5 -#define SCE_ASM_CPUINSTRUCTION 6 -#define SCE_ASM_MATHINSTRUCTION 7 -#define SCE_ASM_REGISTER 8 -#define SCE_ASM_DIRECTIVE 9 -#define SCE_ASM_DIRECTIVEOPERAND 10 -#define SCE_ASM_COMMENTBLOCK 11 -#define SCE_ASM_CHARACTER 12 -#define SCE_ASM_STRINGEOL 13 -#define SCE_ASM_EXTINSTRUCTION 14 -#define SCE_ASM_COMMENTDIRECTIVE 15 -#define SCE_F_DEFAULT 0 -#define SCE_F_COMMENT 1 -#define SCE_F_NUMBER 2 -#define SCE_F_STRING1 3 -#define SCE_F_STRING2 4 -#define SCE_F_STRINGEOL 5 -#define SCE_F_OPERATOR 6 -#define SCE_F_IDENTIFIER 7 -#define SCE_F_WORD 8 -#define SCE_F_WORD2 9 -#define SCE_F_WORD3 10 -#define SCE_F_PREPROCESSOR 11 -#define SCE_F_OPERATOR2 12 -#define SCE_F_LABEL 13 -#define SCE_F_CONTINUATION 14 -#define SCE_CSS_DEFAULT 0 -#define SCE_CSS_TAG 1 -#define SCE_CSS_CLASS 2 -#define SCE_CSS_PSEUDOCLASS 3 -#define SCE_CSS_UNKNOWN_PSEUDOCLASS 4 -#define SCE_CSS_OPERATOR 5 -#define SCE_CSS_IDENTIFIER 6 -#define SCE_CSS_UNKNOWN_IDENTIFIER 7 -#define SCE_CSS_VALUE 8 -#define SCE_CSS_COMMENT 9 -#define SCE_CSS_ID 10 -#define SCE_CSS_IMPORTANT 11 -#define SCE_CSS_DIRECTIVE 12 -#define SCE_CSS_DOUBLESTRING 13 -#define SCE_CSS_SINGLESTRING 14 -#define SCE_CSS_IDENTIFIER2 15 -#define SCE_CSS_ATTRIBUTE 16 -#define SCE_CSS_IDENTIFIER3 17 -#define SCE_CSS_PSEUDOELEMENT 18 -#define SCE_CSS_EXTENDED_IDENTIFIER 19 -#define SCE_CSS_EXTENDED_PSEUDOCLASS 20 -#define SCE_CSS_EXTENDED_PSEUDOELEMENT 21 -#define SCE_CSS_MEDIA 22 -#define SCE_CSS_VARIABLE 23 -#define SCE_POV_DEFAULT 0 -#define SCE_POV_COMMENT 1 -#define SCE_POV_COMMENTLINE 2 -#define SCE_POV_NUMBER 3 -#define SCE_POV_OPERATOR 4 -#define SCE_POV_IDENTIFIER 5 -#define SCE_POV_STRING 6 -#define SCE_POV_STRINGEOL 7 -#define SCE_POV_DIRECTIVE 8 -#define SCE_POV_BADDIRECTIVE 9 -#define SCE_POV_WORD2 10 -#define SCE_POV_WORD3 11 -#define SCE_POV_WORD4 12 -#define SCE_POV_WORD5 13 -#define SCE_POV_WORD6 14 -#define SCE_POV_WORD7 15 -#define SCE_POV_WORD8 16 -#define SCE_LOUT_DEFAULT 0 -#define SCE_LOUT_COMMENT 1 -#define SCE_LOUT_NUMBER 2 -#define SCE_LOUT_WORD 3 -#define SCE_LOUT_WORD2 4 -#define SCE_LOUT_WORD3 5 -#define SCE_LOUT_WORD4 6 -#define SCE_LOUT_STRING 7 -#define SCE_LOUT_OPERATOR 8 -#define SCE_LOUT_IDENTIFIER 9 -#define SCE_LOUT_STRINGEOL 10 -#define SCE_ESCRIPT_DEFAULT 0 -#define SCE_ESCRIPT_COMMENT 1 -#define SCE_ESCRIPT_COMMENTLINE 2 -#define SCE_ESCRIPT_COMMENTDOC 3 -#define SCE_ESCRIPT_NUMBER 4 -#define SCE_ESCRIPT_WORD 5 -#define SCE_ESCRIPT_STRING 6 -#define SCE_ESCRIPT_OPERATOR 7 -#define SCE_ESCRIPT_IDENTIFIER 8 -#define SCE_ESCRIPT_BRACE 9 -#define SCE_ESCRIPT_WORD2 10 -#define SCE_ESCRIPT_WORD3 11 -#define SCE_PS_DEFAULT 0 -#define SCE_PS_COMMENT 1 -#define SCE_PS_DSC_COMMENT 2 -#define SCE_PS_DSC_VALUE 3 -#define SCE_PS_NUMBER 4 -#define SCE_PS_NAME 5 -#define SCE_PS_KEYWORD 6 -#define SCE_PS_LITERAL 7 -#define SCE_PS_IMMEVAL 8 -#define SCE_PS_PAREN_ARRAY 9 -#define SCE_PS_PAREN_DICT 10 -#define SCE_PS_PAREN_PROC 11 -#define SCE_PS_TEXT 12 -#define SCE_PS_HEXSTRING 13 -#define SCE_PS_BASE85STRING 14 -#define SCE_PS_BADSTRINGCHAR 15 -#define SCE_NSIS_DEFAULT 0 -#define SCE_NSIS_COMMENT 1 -#define SCE_NSIS_STRINGDQ 2 -#define SCE_NSIS_STRINGLQ 3 -#define SCE_NSIS_STRINGRQ 4 -#define SCE_NSIS_FUNCTION 5 -#define SCE_NSIS_VARIABLE 6 -#define SCE_NSIS_LABEL 7 -#define SCE_NSIS_USERDEFINED 8 -#define SCE_NSIS_SECTIONDEF 9 -#define SCE_NSIS_SUBSECTIONDEF 10 -#define SCE_NSIS_IFDEFINEDEF 11 -#define SCE_NSIS_MACRODEF 12 -#define SCE_NSIS_STRINGVAR 13 -#define SCE_NSIS_NUMBER 14 -#define SCE_NSIS_SECTIONGROUP 15 -#define SCE_NSIS_PAGEEX 16 -#define SCE_NSIS_FUNCTIONDEF 17 -#define SCE_NSIS_COMMENTBOX 18 -#define SCE_MMIXAL_LEADWS 0 -#define SCE_MMIXAL_COMMENT 1 -#define SCE_MMIXAL_LABEL 2 -#define SCE_MMIXAL_OPCODE 3 -#define SCE_MMIXAL_OPCODE_PRE 4 -#define SCE_MMIXAL_OPCODE_VALID 5 -#define SCE_MMIXAL_OPCODE_UNKNOWN 6 -#define SCE_MMIXAL_OPCODE_POST 7 -#define SCE_MMIXAL_OPERANDS 8 -#define SCE_MMIXAL_NUMBER 9 -#define SCE_MMIXAL_REF 10 -#define SCE_MMIXAL_CHAR 11 -#define SCE_MMIXAL_STRING 12 -#define SCE_MMIXAL_REGISTER 13 -#define SCE_MMIXAL_HEX 14 -#define SCE_MMIXAL_OPERATOR 15 -#define SCE_MMIXAL_SYMBOL 16 -#define SCE_MMIXAL_INCLUDE 17 -#define SCE_CLW_DEFAULT 0 -#define SCE_CLW_LABEL 1 -#define SCE_CLW_COMMENT 2 -#define SCE_CLW_STRING 3 -#define SCE_CLW_USER_IDENTIFIER 4 -#define SCE_CLW_INTEGER_CONSTANT 5 -#define SCE_CLW_REAL_CONSTANT 6 -#define SCE_CLW_PICTURE_STRING 7 -#define SCE_CLW_KEYWORD 8 -#define SCE_CLW_COMPILER_DIRECTIVE 9 -#define SCE_CLW_RUNTIME_EXPRESSIONS 10 -#define SCE_CLW_BUILTIN_PROCEDURES_FUNCTION 11 -#define SCE_CLW_STRUCTURE_DATA_TYPE 12 -#define SCE_CLW_ATTRIBUTE 13 -#define SCE_CLW_STANDARD_EQUATE 14 -#define SCE_CLW_ERROR 15 -#define SCE_CLW_DEPRECATED 16 -#define SCE_LOT_DEFAULT 0 -#define SCE_LOT_HEADER 1 -#define SCE_LOT_BREAK 2 -#define SCE_LOT_SET 3 -#define SCE_LOT_PASS 4 -#define SCE_LOT_FAIL 5 -#define SCE_LOT_ABORT 6 -#define SCE_YAML_DEFAULT 0 -#define SCE_YAML_COMMENT 1 -#define SCE_YAML_IDENTIFIER 2 -#define SCE_YAML_KEYWORD 3 -#define SCE_YAML_NUMBER 4 -#define SCE_YAML_REFERENCE 5 -#define SCE_YAML_DOCUMENT 6 -#define SCE_YAML_TEXT 7 -#define SCE_YAML_ERROR 8 -#define SCE_YAML_OPERATOR 9 -#define SCE_TEX_DEFAULT 0 -#define SCE_TEX_SPECIAL 1 -#define SCE_TEX_GROUP 2 -#define SCE_TEX_SYMBOL 3 -#define SCE_TEX_COMMAND 4 -#define SCE_TEX_TEXT 5 -#define SCE_METAPOST_DEFAULT 0 -#define SCE_METAPOST_SPECIAL 1 -#define SCE_METAPOST_GROUP 2 -#define SCE_METAPOST_SYMBOL 3 -#define SCE_METAPOST_COMMAND 4 -#define SCE_METAPOST_TEXT 5 -#define SCE_METAPOST_EXTRA 6 -#define SCE_ERLANG_DEFAULT 0 -#define SCE_ERLANG_COMMENT 1 -#define SCE_ERLANG_VARIABLE 2 -#define SCE_ERLANG_NUMBER 3 -#define SCE_ERLANG_KEYWORD 4 -#define SCE_ERLANG_STRING 5 -#define SCE_ERLANG_OPERATOR 6 -#define SCE_ERLANG_ATOM 7 -#define SCE_ERLANG_FUNCTION_NAME 8 -#define SCE_ERLANG_CHARACTER 9 -#define SCE_ERLANG_MACRO 10 -#define SCE_ERLANG_RECORD 11 -#define SCE_ERLANG_PREPROC 12 -#define SCE_ERLANG_NODE_NAME 13 -#define SCE_ERLANG_COMMENT_FUNCTION 14 -#define SCE_ERLANG_COMMENT_MODULE 15 -#define SCE_ERLANG_COMMENT_DOC 16 -#define SCE_ERLANG_COMMENT_DOC_MACRO 17 -#define SCE_ERLANG_ATOM_QUOTED 18 -#define SCE_ERLANG_MACRO_QUOTED 19 -#define SCE_ERLANG_RECORD_QUOTED 20 -#define SCE_ERLANG_NODE_NAME_QUOTED 21 -#define SCE_ERLANG_BIFS 22 -#define SCE_ERLANG_MODULES 23 -#define SCE_ERLANG_MODULES_ATT 24 -#define SCE_ERLANG_UNKNOWN 31 -#define SCE_MSSQL_DEFAULT 0 -#define SCE_MSSQL_COMMENT 1 -#define SCE_MSSQL_LINE_COMMENT 2 -#define SCE_MSSQL_NUMBER 3 -#define SCE_MSSQL_STRING 4 -#define SCE_MSSQL_OPERATOR 5 -#define SCE_MSSQL_IDENTIFIER 6 -#define SCE_MSSQL_VARIABLE 7 -#define SCE_MSSQL_COLUMN_NAME 8 -#define SCE_MSSQL_STATEMENT 9 -#define SCE_MSSQL_DATATYPE 10 -#define SCE_MSSQL_SYSTABLE 11 -#define SCE_MSSQL_GLOBAL_VARIABLE 12 -#define SCE_MSSQL_FUNCTION 13 -#define SCE_MSSQL_STORED_PROCEDURE 14 -#define SCE_MSSQL_DEFAULT_PREF_DATATYPE 15 -#define SCE_MSSQL_COLUMN_NAME_2 16 -#define SCE_V_DEFAULT 0 -#define SCE_V_COMMENT 1 -#define SCE_V_COMMENTLINE 2 -#define SCE_V_COMMENTLINEBANG 3 -#define SCE_V_NUMBER 4 -#define SCE_V_WORD 5 -#define SCE_V_STRING 6 -#define SCE_V_WORD2 7 -#define SCE_V_WORD3 8 -#define SCE_V_PREPROCESSOR 9 -#define SCE_V_OPERATOR 10 -#define SCE_V_IDENTIFIER 11 -#define SCE_V_STRINGEOL 12 -#define SCE_V_USER 19 -#define SCE_V_COMMENT_WORD 20 -#define SCE_V_INPUT 21 -#define SCE_V_OUTPUT 22 -#define SCE_V_INOUT 23 -#define SCE_V_PORT_CONNECT 24 -#define SCE_KIX_DEFAULT 0 -#define SCE_KIX_COMMENT 1 -#define SCE_KIX_STRING1 2 -#define SCE_KIX_STRING2 3 -#define SCE_KIX_NUMBER 4 -#define SCE_KIX_VAR 5 -#define SCE_KIX_MACRO 6 -#define SCE_KIX_KEYWORD 7 -#define SCE_KIX_FUNCTIONS 8 -#define SCE_KIX_OPERATOR 9 -#define SCE_KIX_COMMENTSTREAM 10 -#define SCE_KIX_IDENTIFIER 31 -#define SCE_GC_DEFAULT 0 -#define SCE_GC_COMMENTLINE 1 -#define SCE_GC_COMMENTBLOCK 2 -#define SCE_GC_GLOBAL 3 -#define SCE_GC_EVENT 4 -#define SCE_GC_ATTRIBUTE 5 -#define SCE_GC_CONTROL 6 -#define SCE_GC_COMMAND 7 -#define SCE_GC_STRING 8 -#define SCE_GC_OPERATOR 9 -#define SCE_SN_DEFAULT 0 -#define SCE_SN_CODE 1 -#define SCE_SN_COMMENTLINE 2 -#define SCE_SN_COMMENTLINEBANG 3 -#define SCE_SN_NUMBER 4 -#define SCE_SN_WORD 5 -#define SCE_SN_STRING 6 -#define SCE_SN_WORD2 7 -#define SCE_SN_WORD3 8 -#define SCE_SN_PREPROCESSOR 9 -#define SCE_SN_OPERATOR 10 -#define SCE_SN_IDENTIFIER 11 -#define SCE_SN_STRINGEOL 12 -#define SCE_SN_REGEXTAG 13 -#define SCE_SN_SIGNAL 14 -#define SCE_SN_USER 19 -#define SCE_AU3_DEFAULT 0 -#define SCE_AU3_COMMENT 1 -#define SCE_AU3_COMMENTBLOCK 2 -#define SCE_AU3_NUMBER 3 -#define SCE_AU3_FUNCTION 4 -#define SCE_AU3_KEYWORD 5 -#define SCE_AU3_MACRO 6 -#define SCE_AU3_STRING 7 -#define SCE_AU3_OPERATOR 8 -#define SCE_AU3_VARIABLE 9 -#define SCE_AU3_SENT 10 -#define SCE_AU3_PREPROCESSOR 11 -#define SCE_AU3_SPECIAL 12 -#define SCE_AU3_EXPAND 13 -#define SCE_AU3_COMOBJ 14 -#define SCE_AU3_UDF 15 -#define SCE_APDL_DEFAULT 0 -#define SCE_APDL_COMMENT 1 -#define SCE_APDL_COMMENTBLOCK 2 -#define SCE_APDL_NUMBER 3 -#define SCE_APDL_STRING 4 -#define SCE_APDL_OPERATOR 5 -#define SCE_APDL_WORD 6 -#define SCE_APDL_PROCESSOR 7 -#define SCE_APDL_COMMAND 8 -#define SCE_APDL_SLASHCOMMAND 9 -#define SCE_APDL_STARCOMMAND 10 -#define SCE_APDL_ARGUMENT 11 -#define SCE_APDL_FUNCTION 12 -#define SCE_SH_DEFAULT 0 -#define SCE_SH_ERROR 1 -#define SCE_SH_COMMENTLINE 2 -#define SCE_SH_NUMBER 3 -#define SCE_SH_WORD 4 -#define SCE_SH_STRING 5 -#define SCE_SH_CHARACTER 6 -#define SCE_SH_OPERATOR 7 -#define SCE_SH_IDENTIFIER 8 -#define SCE_SH_SCALAR 9 -#define SCE_SH_PARAM 10 -#define SCE_SH_BACKTICKS 11 -#define SCE_SH_HERE_DELIM 12 -#define SCE_SH_HERE_Q 13 -#define SCE_ASN1_DEFAULT 0 -#define SCE_ASN1_COMMENT 1 -#define SCE_ASN1_IDENTIFIER 2 -#define SCE_ASN1_STRING 3 -#define SCE_ASN1_OID 4 -#define SCE_ASN1_SCALAR 5 -#define SCE_ASN1_KEYWORD 6 -#define SCE_ASN1_ATTRIBUTE 7 -#define SCE_ASN1_DESCRIPTOR 8 -#define SCE_ASN1_TYPE 9 -#define SCE_ASN1_OPERATOR 10 -#define SCE_VHDL_DEFAULT 0 -#define SCE_VHDL_COMMENT 1 -#define SCE_VHDL_COMMENTLINEBANG 2 -#define SCE_VHDL_NUMBER 3 -#define SCE_VHDL_STRING 4 -#define SCE_VHDL_OPERATOR 5 -#define SCE_VHDL_IDENTIFIER 6 -#define SCE_VHDL_STRINGEOL 7 -#define SCE_VHDL_KEYWORD 8 -#define SCE_VHDL_STDOPERATOR 9 -#define SCE_VHDL_ATTRIBUTE 10 -#define SCE_VHDL_STDFUNCTION 11 -#define SCE_VHDL_STDPACKAGE 12 -#define SCE_VHDL_STDTYPE 13 -#define SCE_VHDL_USERWORD 14 -#define SCE_VHDL_BLOCK_COMMENT 15 -#define SCE_CAML_DEFAULT 0 -#define SCE_CAML_IDENTIFIER 1 -#define SCE_CAML_TAGNAME 2 -#define SCE_CAML_KEYWORD 3 -#define SCE_CAML_KEYWORD2 4 -#define SCE_CAML_KEYWORD3 5 -#define SCE_CAML_LINENUM 6 -#define SCE_CAML_OPERATOR 7 -#define SCE_CAML_NUMBER 8 -#define SCE_CAML_CHAR 9 -#define SCE_CAML_WHITE 10 -#define SCE_CAML_STRING 11 -#define SCE_CAML_COMMENT 12 -#define SCE_CAML_COMMENT1 13 -#define SCE_CAML_COMMENT2 14 -#define SCE_CAML_COMMENT3 15 -#define SCE_HA_DEFAULT 0 -#define SCE_HA_IDENTIFIER 1 -#define SCE_HA_KEYWORD 2 -#define SCE_HA_NUMBER 3 -#define SCE_HA_STRING 4 -#define SCE_HA_CHARACTER 5 -#define SCE_HA_CLASS 6 -#define SCE_HA_MODULE 7 -#define SCE_HA_CAPITAL 8 -#define SCE_HA_DATA 9 -#define SCE_HA_IMPORT 10 -#define SCE_HA_OPERATOR 11 -#define SCE_HA_INSTANCE 12 -#define SCE_HA_COMMENTLINE 13 -#define SCE_HA_COMMENTBLOCK 14 -#define SCE_HA_COMMENTBLOCK2 15 -#define SCE_HA_COMMENTBLOCK3 16 -#define SCE_HA_PRAGMA 17 -#define SCE_HA_PREPROCESSOR 18 -#define SCE_HA_STRINGEOL 19 -#define SCE_HA_RESERVED_OPERATOR 20 -#define SCE_HA_LITERATE_COMMENT 21 -#define SCE_HA_LITERATE_CODEDELIM 22 -#define SCE_T3_DEFAULT 0 -#define SCE_T3_X_DEFAULT 1 -#define SCE_T3_PREPROCESSOR 2 -#define SCE_T3_BLOCK_COMMENT 3 -#define SCE_T3_LINE_COMMENT 4 -#define SCE_T3_OPERATOR 5 -#define SCE_T3_KEYWORD 6 -#define SCE_T3_NUMBER 7 -#define SCE_T3_IDENTIFIER 8 -#define SCE_T3_S_STRING 9 -#define SCE_T3_D_STRING 10 -#define SCE_T3_X_STRING 11 -#define SCE_T3_LIB_DIRECTIVE 12 -#define SCE_T3_MSG_PARAM 13 -#define SCE_T3_HTML_TAG 14 -#define SCE_T3_HTML_DEFAULT 15 -#define SCE_T3_HTML_STRING 16 -#define SCE_T3_USER1 17 -#define SCE_T3_USER2 18 -#define SCE_T3_USER3 19 -#define SCE_T3_BRACE 20 -#define SCE_REBOL_DEFAULT 0 -#define SCE_REBOL_COMMENTLINE 1 -#define SCE_REBOL_COMMENTBLOCK 2 -#define SCE_REBOL_PREFACE 3 -#define SCE_REBOL_OPERATOR 4 -#define SCE_REBOL_CHARACTER 5 -#define SCE_REBOL_QUOTEDSTRING 6 -#define SCE_REBOL_BRACEDSTRING 7 -#define SCE_REBOL_NUMBER 8 -#define SCE_REBOL_PAIR 9 -#define SCE_REBOL_TUPLE 10 -#define SCE_REBOL_BINARY 11 -#define SCE_REBOL_MONEY 12 -#define SCE_REBOL_ISSUE 13 -#define SCE_REBOL_TAG 14 -#define SCE_REBOL_FILE 15 -#define SCE_REBOL_EMAIL 16 -#define SCE_REBOL_URL 17 -#define SCE_REBOL_DATE 18 -#define SCE_REBOL_TIME 19 -#define SCE_REBOL_IDENTIFIER 20 -#define SCE_REBOL_WORD 21 -#define SCE_REBOL_WORD2 22 -#define SCE_REBOL_WORD3 23 -#define SCE_REBOL_WORD4 24 -#define SCE_REBOL_WORD5 25 -#define SCE_REBOL_WORD6 26 -#define SCE_REBOL_WORD7 27 -#define SCE_REBOL_WORD8 28 -#define SCE_SQL_DEFAULT 0 -#define SCE_SQL_COMMENT 1 -#define SCE_SQL_COMMENTLINE 2 -#define SCE_SQL_COMMENTDOC 3 -#define SCE_SQL_NUMBER 4 -#define SCE_SQL_WORD 5 -#define SCE_SQL_STRING 6 -#define SCE_SQL_CHARACTER 7 -#define SCE_SQL_SQLPLUS 8 -#define SCE_SQL_SQLPLUS_PROMPT 9 -#define SCE_SQL_OPERATOR 10 -#define SCE_SQL_IDENTIFIER 11 -#define SCE_SQL_SQLPLUS_COMMENT 13 -#define SCE_SQL_COMMENTLINEDOC 15 -#define SCE_SQL_WORD2 16 -#define SCE_SQL_COMMENTDOCKEYWORD 17 -#define SCE_SQL_COMMENTDOCKEYWORDERROR 18 -#define SCE_SQL_USER1 19 -#define SCE_SQL_USER2 20 -#define SCE_SQL_USER3 21 -#define SCE_SQL_USER4 22 -#define SCE_SQL_QUOTEDIDENTIFIER 23 -#define SCE_SQL_QOPERATOR 24 -#define SCE_ST_DEFAULT 0 -#define SCE_ST_STRING 1 -#define SCE_ST_NUMBER 2 -#define SCE_ST_COMMENT 3 -#define SCE_ST_SYMBOL 4 -#define SCE_ST_BINARY 5 -#define SCE_ST_BOOL 6 -#define SCE_ST_SELF 7 -#define SCE_ST_SUPER 8 -#define SCE_ST_NIL 9 -#define SCE_ST_GLOBAL 10 -#define SCE_ST_RETURN 11 -#define SCE_ST_SPECIAL 12 -#define SCE_ST_KWSEND 13 -#define SCE_ST_ASSIGN 14 -#define SCE_ST_CHARACTER 15 -#define SCE_ST_SPEC_SEL 16 -#define SCE_FS_DEFAULT 0 -#define SCE_FS_COMMENT 1 -#define SCE_FS_COMMENTLINE 2 -#define SCE_FS_COMMENTDOC 3 -#define SCE_FS_COMMENTLINEDOC 4 -#define SCE_FS_COMMENTDOCKEYWORD 5 -#define SCE_FS_COMMENTDOCKEYWORDERROR 6 -#define SCE_FS_KEYWORD 7 -#define SCE_FS_KEYWORD2 8 -#define SCE_FS_KEYWORD3 9 -#define SCE_FS_KEYWORD4 10 -#define SCE_FS_NUMBER 11 -#define SCE_FS_STRING 12 -#define SCE_FS_PREPROCESSOR 13 -#define SCE_FS_OPERATOR 14 -#define SCE_FS_IDENTIFIER 15 -#define SCE_FS_DATE 16 -#define SCE_FS_STRINGEOL 17 -#define SCE_FS_CONSTANT 18 -#define SCE_FS_WORDOPERATOR 19 -#define SCE_FS_DISABLEDCODE 20 -#define SCE_FS_DEFAULT_C 21 -#define SCE_FS_COMMENTDOC_C 22 -#define SCE_FS_COMMENTLINEDOC_C 23 -#define SCE_FS_KEYWORD_C 24 -#define SCE_FS_KEYWORD2_C 25 -#define SCE_FS_NUMBER_C 26 -#define SCE_FS_STRING_C 27 -#define SCE_FS_PREPROCESSOR_C 28 -#define SCE_FS_OPERATOR_C 29 -#define SCE_FS_IDENTIFIER_C 30 -#define SCE_FS_STRINGEOL_C 31 -#define SCE_CSOUND_DEFAULT 0 -#define SCE_CSOUND_COMMENT 1 -#define SCE_CSOUND_NUMBER 2 -#define SCE_CSOUND_OPERATOR 3 -#define SCE_CSOUND_INSTR 4 -#define SCE_CSOUND_IDENTIFIER 5 -#define SCE_CSOUND_OPCODE 6 -#define SCE_CSOUND_HEADERSTMT 7 -#define SCE_CSOUND_USERKEYWORD 8 -#define SCE_CSOUND_COMMENTBLOCK 9 -#define SCE_CSOUND_PARAM 10 -#define SCE_CSOUND_ARATE_VAR 11 -#define SCE_CSOUND_KRATE_VAR 12 -#define SCE_CSOUND_IRATE_VAR 13 -#define SCE_CSOUND_GLOBAL_VAR 14 -#define SCE_CSOUND_STRINGEOL 15 -#define SCE_INNO_DEFAULT 0 -#define SCE_INNO_COMMENT 1 -#define SCE_INNO_KEYWORD 2 -#define SCE_INNO_PARAMETER 3 -#define SCE_INNO_SECTION 4 -#define SCE_INNO_PREPROC 5 -#define SCE_INNO_INLINE_EXPANSION 6 -#define SCE_INNO_COMMENT_PASCAL 7 -#define SCE_INNO_KEYWORD_PASCAL 8 -#define SCE_INNO_KEYWORD_USER 9 -#define SCE_INNO_STRING_DOUBLE 10 -#define SCE_INNO_STRING_SINGLE 11 -#define SCE_INNO_IDENTIFIER 12 -#define SCE_OPAL_SPACE 0 -#define SCE_OPAL_COMMENT_BLOCK 1 -#define SCE_OPAL_COMMENT_LINE 2 -#define SCE_OPAL_INTEGER 3 -#define SCE_OPAL_KEYWORD 4 -#define SCE_OPAL_SORT 5 -#define SCE_OPAL_STRING 6 -#define SCE_OPAL_PAR 7 -#define SCE_OPAL_BOOL_CONST 8 -#define SCE_OPAL_DEFAULT 32 -#define SCE_SPICE_DEFAULT 0 -#define SCE_SPICE_IDENTIFIER 1 -#define SCE_SPICE_KEYWORD 2 -#define SCE_SPICE_KEYWORD2 3 -#define SCE_SPICE_KEYWORD3 4 -#define SCE_SPICE_NUMBER 5 -#define SCE_SPICE_DELIMITER 6 -#define SCE_SPICE_VALUE 7 -#define SCE_SPICE_COMMENTLINE 8 -#define SCE_CMAKE_DEFAULT 0 -#define SCE_CMAKE_COMMENT 1 -#define SCE_CMAKE_STRINGDQ 2 -#define SCE_CMAKE_STRINGLQ 3 -#define SCE_CMAKE_STRINGRQ 4 -#define SCE_CMAKE_COMMANDS 5 -#define SCE_CMAKE_PARAMETERS 6 -#define SCE_CMAKE_VARIABLE 7 -#define SCE_CMAKE_USERDEFINED 8 -#define SCE_CMAKE_WHILEDEF 9 -#define SCE_CMAKE_FOREACHDEF 10 -#define SCE_CMAKE_IFDEFINEDEF 11 -#define SCE_CMAKE_MACRODEF 12 -#define SCE_CMAKE_STRINGVAR 13 -#define SCE_CMAKE_NUMBER 14 -#define SCE_GAP_DEFAULT 0 -#define SCE_GAP_IDENTIFIER 1 -#define SCE_GAP_KEYWORD 2 -#define SCE_GAP_KEYWORD2 3 -#define SCE_GAP_KEYWORD3 4 -#define SCE_GAP_KEYWORD4 5 -#define SCE_GAP_STRING 6 -#define SCE_GAP_CHAR 7 -#define SCE_GAP_OPERATOR 8 -#define SCE_GAP_COMMENT 9 -#define SCE_GAP_NUMBER 10 -#define SCE_GAP_STRINGEOL 11 -#define SCE_PLM_DEFAULT 0 -#define SCE_PLM_COMMENT 1 -#define SCE_PLM_STRING 2 -#define SCE_PLM_NUMBER 3 -#define SCE_PLM_IDENTIFIER 4 -#define SCE_PLM_OPERATOR 5 -#define SCE_PLM_CONTROL 6 -#define SCE_PLM_KEYWORD 7 -#define SCE_ABL_DEFAULT 0 -#define SCE_ABL_NUMBER 1 -#define SCE_ABL_WORD 2 -#define SCE_ABL_STRING 3 -#define SCE_ABL_CHARACTER 4 -#define SCE_ABL_PREPROCESSOR 5 -#define SCE_ABL_OPERATOR 6 -#define SCE_ABL_IDENTIFIER 7 -#define SCE_ABL_BLOCK 8 -#define SCE_ABL_END 9 -#define SCE_ABL_COMMENT 10 -#define SCE_ABL_TASKMARKER 11 -#define SCE_ABL_LINECOMMENT 12 -#define SCE_ABAQUS_DEFAULT 0 -#define SCE_ABAQUS_COMMENT 1 -#define SCE_ABAQUS_COMMENTBLOCK 2 -#define SCE_ABAQUS_NUMBER 3 -#define SCE_ABAQUS_STRING 4 -#define SCE_ABAQUS_OPERATOR 5 -#define SCE_ABAQUS_WORD 6 -#define SCE_ABAQUS_PROCESSOR 7 -#define SCE_ABAQUS_COMMAND 8 -#define SCE_ABAQUS_SLASHCOMMAND 9 -#define SCE_ABAQUS_STARCOMMAND 10 -#define SCE_ABAQUS_ARGUMENT 11 -#define SCE_ABAQUS_FUNCTION 12 -#define SCE_ASY_DEFAULT 0 -#define SCE_ASY_COMMENT 1 -#define SCE_ASY_COMMENTLINE 2 -#define SCE_ASY_NUMBER 3 -#define SCE_ASY_WORD 4 -#define SCE_ASY_STRING 5 -#define SCE_ASY_CHARACTER 6 -#define SCE_ASY_OPERATOR 7 -#define SCE_ASY_IDENTIFIER 8 -#define SCE_ASY_STRINGEOL 9 -#define SCE_ASY_COMMENTLINEDOC 10 -#define SCE_ASY_WORD2 11 -#define SCE_R_DEFAULT 0 -#define SCE_R_COMMENT 1 -#define SCE_R_KWORD 2 -#define SCE_R_BASEKWORD 3 -#define SCE_R_OTHERKWORD 4 -#define SCE_R_NUMBER 5 -#define SCE_R_STRING 6 -#define SCE_R_STRING2 7 -#define SCE_R_OPERATOR 8 -#define SCE_R_IDENTIFIER 9 -#define SCE_R_INFIX 10 -#define SCE_R_INFIXEOL 11 -#define SCE_MAGIK_DEFAULT 0 -#define SCE_MAGIK_COMMENT 1 -#define SCE_MAGIK_HYPER_COMMENT 16 -#define SCE_MAGIK_STRING 2 -#define SCE_MAGIK_CHARACTER 3 -#define SCE_MAGIK_NUMBER 4 -#define SCE_MAGIK_IDENTIFIER 5 -#define SCE_MAGIK_OPERATOR 6 -#define SCE_MAGIK_FLOW 7 -#define SCE_MAGIK_CONTAINER 8 -#define SCE_MAGIK_BRACKET_BLOCK 9 -#define SCE_MAGIK_BRACE_BLOCK 10 -#define SCE_MAGIK_SQBRACKET_BLOCK 11 -#define SCE_MAGIK_UNKNOWN_KEYWORD 12 -#define SCE_MAGIK_KEYWORD 13 -#define SCE_MAGIK_PRAGMA 14 -#define SCE_MAGIK_SYMBOL 15 -#define SCE_POWERSHELL_DEFAULT 0 -#define SCE_POWERSHELL_COMMENT 1 -#define SCE_POWERSHELL_STRING 2 -#define SCE_POWERSHELL_CHARACTER 3 -#define SCE_POWERSHELL_NUMBER 4 -#define SCE_POWERSHELL_VARIABLE 5 -#define SCE_POWERSHELL_OPERATOR 6 -#define SCE_POWERSHELL_IDENTIFIER 7 -#define SCE_POWERSHELL_KEYWORD 8 -#define SCE_POWERSHELL_CMDLET 9 -#define SCE_POWERSHELL_ALIAS 10 -#define SCE_POWERSHELL_FUNCTION 11 -#define SCE_POWERSHELL_USER1 12 -#define SCE_POWERSHELL_COMMENTSTREAM 13 -#define SCE_POWERSHELL_HERE_STRING 14 -#define SCE_POWERSHELL_HERE_CHARACTER 15 -#define SCE_POWERSHELL_COMMENTDOCKEYWORD 16 -#define SCE_MYSQL_DEFAULT 0 -#define SCE_MYSQL_COMMENT 1 -#define SCE_MYSQL_COMMENTLINE 2 -#define SCE_MYSQL_VARIABLE 3 -#define SCE_MYSQL_SYSTEMVARIABLE 4 -#define SCE_MYSQL_KNOWNSYSTEMVARIABLE 5 -#define SCE_MYSQL_NUMBER 6 -#define SCE_MYSQL_MAJORKEYWORD 7 -#define SCE_MYSQL_KEYWORD 8 -#define SCE_MYSQL_DATABASEOBJECT 9 -#define SCE_MYSQL_PROCEDUREKEYWORD 10 -#define SCE_MYSQL_STRING 11 -#define SCE_MYSQL_SQSTRING 12 -#define SCE_MYSQL_DQSTRING 13 -#define SCE_MYSQL_OPERATOR 14 -#define SCE_MYSQL_FUNCTION 15 -#define SCE_MYSQL_IDENTIFIER 16 -#define SCE_MYSQL_QUOTEDIDENTIFIER 17 -#define SCE_MYSQL_USER1 18 -#define SCE_MYSQL_USER2 19 -#define SCE_MYSQL_USER3 20 -#define SCE_MYSQL_HIDDENCOMMAND 21 -#define SCE_MYSQL_PLACEHOLDER 22 -#define SCE_PO_DEFAULT 0 -#define SCE_PO_COMMENT 1 -#define SCE_PO_MSGID 2 -#define SCE_PO_MSGID_TEXT 3 -#define SCE_PO_MSGSTR 4 -#define SCE_PO_MSGSTR_TEXT 5 -#define SCE_PO_MSGCTXT 6 -#define SCE_PO_MSGCTXT_TEXT 7 -#define SCE_PO_FUZZY 8 -#define SCE_PO_PROGRAMMER_COMMENT 9 -#define SCE_PO_REFERENCE 10 -#define SCE_PO_FLAGS 11 -#define SCE_PO_MSGID_TEXT_EOL 12 -#define SCE_PO_MSGSTR_TEXT_EOL 13 -#define SCE_PO_MSGCTXT_TEXT_EOL 14 -#define SCE_PO_ERROR 15 -#define SCE_PAS_DEFAULT 0 -#define SCE_PAS_IDENTIFIER 1 -#define SCE_PAS_COMMENT 2 -#define SCE_PAS_COMMENT2 3 -#define SCE_PAS_COMMENTLINE 4 -#define SCE_PAS_PREPROCESSOR 5 -#define SCE_PAS_PREPROCESSOR2 6 -#define SCE_PAS_NUMBER 7 -#define SCE_PAS_HEXNUMBER 8 -#define SCE_PAS_WORD 9 -#define SCE_PAS_STRING 10 -#define SCE_PAS_STRINGEOL 11 -#define SCE_PAS_CHARACTER 12 -#define SCE_PAS_OPERATOR 13 -#define SCE_PAS_ASM 14 -#define SCE_SORCUS_DEFAULT 0 -#define SCE_SORCUS_COMMAND 1 -#define SCE_SORCUS_PARAMETER 2 -#define SCE_SORCUS_COMMENTLINE 3 -#define SCE_SORCUS_STRING 4 -#define SCE_SORCUS_STRINGEOL 5 -#define SCE_SORCUS_IDENTIFIER 6 -#define SCE_SORCUS_OPERATOR 7 -#define SCE_SORCUS_NUMBER 8 -#define SCE_SORCUS_CONSTANT 9 -#define SCE_POWERPRO_DEFAULT 0 -#define SCE_POWERPRO_COMMENTBLOCK 1 -#define SCE_POWERPRO_COMMENTLINE 2 -#define SCE_POWERPRO_NUMBER 3 -#define SCE_POWERPRO_WORD 4 -#define SCE_POWERPRO_WORD2 5 -#define SCE_POWERPRO_WORD3 6 -#define SCE_POWERPRO_WORD4 7 -#define SCE_POWERPRO_DOUBLEQUOTEDSTRING 8 -#define SCE_POWERPRO_SINGLEQUOTEDSTRING 9 -#define SCE_POWERPRO_LINECONTINUE 10 -#define SCE_POWERPRO_OPERATOR 11 -#define SCE_POWERPRO_IDENTIFIER 12 -#define SCE_POWERPRO_STRINGEOL 13 -#define SCE_POWERPRO_VERBATIM 14 -#define SCE_POWERPRO_ALTQUOTE 15 -#define SCE_POWERPRO_FUNCTION 16 -#define SCE_SML_DEFAULT 0 -#define SCE_SML_IDENTIFIER 1 -#define SCE_SML_TAGNAME 2 -#define SCE_SML_KEYWORD 3 -#define SCE_SML_KEYWORD2 4 -#define SCE_SML_KEYWORD3 5 -#define SCE_SML_LINENUM 6 -#define SCE_SML_OPERATOR 7 -#define SCE_SML_NUMBER 8 -#define SCE_SML_CHAR 9 -#define SCE_SML_STRING 11 -#define SCE_SML_COMMENT 12 -#define SCE_SML_COMMENT1 13 -#define SCE_SML_COMMENT2 14 -#define SCE_SML_COMMENT3 15 -#define SCE_MARKDOWN_DEFAULT 0 -#define SCE_MARKDOWN_LINE_BEGIN 1 -#define SCE_MARKDOWN_STRONG1 2 -#define SCE_MARKDOWN_STRONG2 3 -#define SCE_MARKDOWN_EM1 4 -#define SCE_MARKDOWN_EM2 5 -#define SCE_MARKDOWN_HEADER1 6 -#define SCE_MARKDOWN_HEADER2 7 -#define SCE_MARKDOWN_HEADER3 8 -#define SCE_MARKDOWN_HEADER4 9 -#define SCE_MARKDOWN_HEADER5 10 -#define SCE_MARKDOWN_HEADER6 11 -#define SCE_MARKDOWN_PRECHAR 12 -#define SCE_MARKDOWN_ULIST_ITEM 13 -#define SCE_MARKDOWN_OLIST_ITEM 14 -#define SCE_MARKDOWN_BLOCKQUOTE 15 -#define SCE_MARKDOWN_STRIKEOUT 16 -#define SCE_MARKDOWN_HRULE 17 -#define SCE_MARKDOWN_LINK 18 -#define SCE_MARKDOWN_CODE 19 -#define SCE_MARKDOWN_CODE2 20 -#define SCE_MARKDOWN_CODEBK 21 -#define SCE_TXT2TAGS_DEFAULT 0 -#define SCE_TXT2TAGS_LINE_BEGIN 1 -#define SCE_TXT2TAGS_STRONG1 2 -#define SCE_TXT2TAGS_STRONG2 3 -#define SCE_TXT2TAGS_EM1 4 -#define SCE_TXT2TAGS_EM2 5 -#define SCE_TXT2TAGS_HEADER1 6 -#define SCE_TXT2TAGS_HEADER2 7 -#define SCE_TXT2TAGS_HEADER3 8 -#define SCE_TXT2TAGS_HEADER4 9 -#define SCE_TXT2TAGS_HEADER5 10 -#define SCE_TXT2TAGS_HEADER6 11 -#define SCE_TXT2TAGS_PRECHAR 12 -#define SCE_TXT2TAGS_ULIST_ITEM 13 -#define SCE_TXT2TAGS_OLIST_ITEM 14 -#define SCE_TXT2TAGS_BLOCKQUOTE 15 -#define SCE_TXT2TAGS_STRIKEOUT 16 -#define SCE_TXT2TAGS_HRULE 17 -#define SCE_TXT2TAGS_LINK 18 -#define SCE_TXT2TAGS_CODE 19 -#define SCE_TXT2TAGS_CODE2 20 -#define SCE_TXT2TAGS_CODEBK 21 -#define SCE_TXT2TAGS_COMMENT 22 -#define SCE_TXT2TAGS_OPTION 23 -#define SCE_TXT2TAGS_PREPROC 24 -#define SCE_TXT2TAGS_POSTPROC 25 -#define SCE_A68K_DEFAULT 0 -#define SCE_A68K_COMMENT 1 -#define SCE_A68K_NUMBER_DEC 2 -#define SCE_A68K_NUMBER_BIN 3 -#define SCE_A68K_NUMBER_HEX 4 -#define SCE_A68K_STRING1 5 -#define SCE_A68K_OPERATOR 6 -#define SCE_A68K_CPUINSTRUCTION 7 -#define SCE_A68K_EXTINSTRUCTION 8 -#define SCE_A68K_REGISTER 9 -#define SCE_A68K_DIRECTIVE 10 -#define SCE_A68K_MACRO_ARG 11 -#define SCE_A68K_LABEL 12 -#define SCE_A68K_STRING2 13 -#define SCE_A68K_IDENTIFIER 14 -#define SCE_A68K_MACRO_DECLARATION 15 -#define SCE_A68K_COMMENT_WORD 16 -#define SCE_A68K_COMMENT_SPECIAL 17 -#define SCE_A68K_COMMENT_DOXYGEN 18 -#define SCE_MODULA_DEFAULT 0 -#define SCE_MODULA_COMMENT 1 -#define SCE_MODULA_DOXYCOMM 2 -#define SCE_MODULA_DOXYKEY 3 -#define SCE_MODULA_KEYWORD 4 -#define SCE_MODULA_RESERVED 5 -#define SCE_MODULA_NUMBER 6 -#define SCE_MODULA_BASENUM 7 -#define SCE_MODULA_FLOAT 8 -#define SCE_MODULA_STRING 9 -#define SCE_MODULA_STRSPEC 10 -#define SCE_MODULA_CHAR 11 -#define SCE_MODULA_CHARSPEC 12 -#define SCE_MODULA_PROC 13 -#define SCE_MODULA_PRAGMA 14 -#define SCE_MODULA_PRGKEY 15 -#define SCE_MODULA_OPERATOR 16 -#define SCE_MODULA_BADSTR 17 -#define SCE_COFFEESCRIPT_DEFAULT 0 -#define SCE_COFFEESCRIPT_COMMENT 1 -#define SCE_COFFEESCRIPT_COMMENTLINE 2 -#define SCE_COFFEESCRIPT_COMMENTDOC 3 -#define SCE_COFFEESCRIPT_NUMBER 4 -#define SCE_COFFEESCRIPT_WORD 5 -#define SCE_COFFEESCRIPT_STRING 6 -#define SCE_COFFEESCRIPT_CHARACTER 7 -#define SCE_COFFEESCRIPT_UUID 8 -#define SCE_COFFEESCRIPT_PREPROCESSOR 9 -#define SCE_COFFEESCRIPT_OPERATOR 10 -#define SCE_COFFEESCRIPT_IDENTIFIER 11 -#define SCE_COFFEESCRIPT_STRINGEOL 12 -#define SCE_COFFEESCRIPT_VERBATIM 13 -#define SCE_COFFEESCRIPT_REGEX 14 -#define SCE_COFFEESCRIPT_COMMENTLINEDOC 15 -#define SCE_COFFEESCRIPT_WORD2 16 -#define SCE_COFFEESCRIPT_COMMENTDOCKEYWORD 17 -#define SCE_COFFEESCRIPT_COMMENTDOCKEYWORDERROR 18 -#define SCE_COFFEESCRIPT_GLOBALCLASS 19 -#define SCE_COFFEESCRIPT_STRINGRAW 20 -#define SCE_COFFEESCRIPT_TRIPLEVERBATIM 21 -#define SCE_COFFEESCRIPT_COMMENTBLOCK 22 -#define SCE_COFFEESCRIPT_VERBOSE_REGEX 23 -#define SCE_COFFEESCRIPT_VERBOSE_REGEX_COMMENT 24 -#define SCE_COFFEESCRIPT_INSTANCEPROPERTY 25 -#define SCE_AVS_DEFAULT 0 -#define SCE_AVS_COMMENTBLOCK 1 -#define SCE_AVS_COMMENTBLOCKN 2 -#define SCE_AVS_COMMENTLINE 3 -#define SCE_AVS_NUMBER 4 -#define SCE_AVS_OPERATOR 5 -#define SCE_AVS_IDENTIFIER 6 -#define SCE_AVS_STRING 7 -#define SCE_AVS_TRIPLESTRING 8 -#define SCE_AVS_KEYWORD 9 -#define SCE_AVS_FILTER 10 -#define SCE_AVS_PLUGIN 11 -#define SCE_AVS_FUNCTION 12 -#define SCE_AVS_CLIPPROP 13 -#define SCE_AVS_USERDFN 14 -#define SCE_ECL_DEFAULT 0 -#define SCE_ECL_COMMENT 1 -#define SCE_ECL_COMMENTLINE 2 -#define SCE_ECL_NUMBER 3 -#define SCE_ECL_STRING 4 -#define SCE_ECL_WORD0 5 -#define SCE_ECL_OPERATOR 6 -#define SCE_ECL_CHARACTER 7 -#define SCE_ECL_UUID 8 -#define SCE_ECL_PREPROCESSOR 9 -#define SCE_ECL_UNKNOWN 10 -#define SCE_ECL_IDENTIFIER 11 -#define SCE_ECL_STRINGEOL 12 -#define SCE_ECL_VERBATIM 13 -#define SCE_ECL_REGEX 14 -#define SCE_ECL_COMMENTLINEDOC 15 -#define SCE_ECL_WORD1 16 -#define SCE_ECL_COMMENTDOCKEYWORD 17 -#define SCE_ECL_COMMENTDOCKEYWORDERROR 18 -#define SCE_ECL_WORD2 19 -#define SCE_ECL_WORD3 20 -#define SCE_ECL_WORD4 21 -#define SCE_ECL_WORD5 22 -#define SCE_ECL_COMMENTDOC 23 -#define SCE_ECL_ADDED 24 -#define SCE_ECL_DELETED 25 -#define SCE_ECL_CHANGED 26 -#define SCE_ECL_MOVED 27 -#define SCE_OSCRIPT_DEFAULT 0 -#define SCE_OSCRIPT_LINE_COMMENT 1 -#define SCE_OSCRIPT_BLOCK_COMMENT 2 -#define SCE_OSCRIPT_DOC_COMMENT 3 -#define SCE_OSCRIPT_PREPROCESSOR 4 -#define SCE_OSCRIPT_NUMBER 5 -#define SCE_OSCRIPT_SINGLEQUOTE_STRING 6 -#define SCE_OSCRIPT_DOUBLEQUOTE_STRING 7 -#define SCE_OSCRIPT_CONSTANT 8 -#define SCE_OSCRIPT_IDENTIFIER 9 -#define SCE_OSCRIPT_GLOBAL 10 -#define SCE_OSCRIPT_KEYWORD 11 -#define SCE_OSCRIPT_OPERATOR 12 -#define SCE_OSCRIPT_LABEL 13 -#define SCE_OSCRIPT_TYPE 14 -#define SCE_OSCRIPT_FUNCTION 15 -#define SCE_OSCRIPT_OBJECT 16 -#define SCE_OSCRIPT_PROPERTY 17 -#define SCE_OSCRIPT_METHOD 18 -#define SCE_VISUALPROLOG_DEFAULT 0 -#define SCE_VISUALPROLOG_KEY_MAJOR 1 -#define SCE_VISUALPROLOG_KEY_MINOR 2 -#define SCE_VISUALPROLOG_KEY_DIRECTIVE 3 -#define SCE_VISUALPROLOG_COMMENT_BLOCK 4 -#define SCE_VISUALPROLOG_COMMENT_LINE 5 -#define SCE_VISUALPROLOG_COMMENT_KEY 6 -#define SCE_VISUALPROLOG_COMMENT_KEY_ERROR 7 -#define SCE_VISUALPROLOG_IDENTIFIER 8 -#define SCE_VISUALPROLOG_VARIABLE 9 -#define SCE_VISUALPROLOG_ANONYMOUS 10 -#define SCE_VISUALPROLOG_NUMBER 11 -#define SCE_VISUALPROLOG_OPERATOR 12 -#define SCE_VISUALPROLOG_CHARACTER 13 -#define SCE_VISUALPROLOG_CHARACTER_TOO_MANY 14 -#define SCE_VISUALPROLOG_CHARACTER_ESCAPE_ERROR 15 -#define SCE_VISUALPROLOG_STRING 16 -#define SCE_VISUALPROLOG_STRING_ESCAPE 17 -#define SCE_VISUALPROLOG_STRING_ESCAPE_ERROR 18 -#define SCE_VISUALPROLOG_STRING_EOL_OPEN 19 -#define SCE_VISUALPROLOG_STRING_VERBATIM 20 -#define SCE_VISUALPROLOG_STRING_VERBATIM_SPECIAL 21 -#define SCE_VISUALPROLOG_STRING_VERBATIM_EOL 22 -#define SCE_STTXT_DEFAULT 0 -#define SCE_STTXT_COMMENT 1 -#define SCE_STTXT_COMMENTLINE 2 -#define SCE_STTXT_KEYWORD 3 -#define SCE_STTXT_TYPE 4 -#define SCE_STTXT_FUNCTION 5 -#define SCE_STTXT_FB 6 -#define SCE_STTXT_NUMBER 7 -#define SCE_STTXT_HEXNUMBER 8 -#define SCE_STTXT_PRAGMA 9 -#define SCE_STTXT_OPERATOR 10 -#define SCE_STTXT_CHARACTER 11 -#define SCE_STTXT_STRING1 12 -#define SCE_STTXT_STRING2 13 -#define SCE_STTXT_STRINGEOL 14 -#define SCE_STTXT_IDENTIFIER 15 -#define SCE_STTXT_DATETIME 16 -#define SCE_STTXT_VARS 17 -#define SCE_STTXT_PRAGMAS 18 -#define SCE_KVIRC_DEFAULT 0 -#define SCE_KVIRC_COMMENT 1 -#define SCE_KVIRC_COMMENTBLOCK 2 -#define SCE_KVIRC_STRING 3 -#define SCE_KVIRC_WORD 4 -#define SCE_KVIRC_KEYWORD 5 -#define SCE_KVIRC_FUNCTION_KEYWORD 6 -#define SCE_KVIRC_FUNCTION 7 -#define SCE_KVIRC_VARIABLE 8 -#define SCE_KVIRC_NUMBER 9 -#define SCE_KVIRC_OPERATOR 10 -#define SCE_KVIRC_STRING_FUNCTION 11 -#define SCE_KVIRC_STRING_VARIABLE 12 -#define SCE_RUST_DEFAULT 0 -#define SCE_RUST_COMMENTBLOCK 1 -#define SCE_RUST_COMMENTLINE 2 -#define SCE_RUST_COMMENTBLOCKDOC 3 -#define SCE_RUST_COMMENTLINEDOC 4 -#define SCE_RUST_NUMBER 5 -#define SCE_RUST_WORD 6 -#define SCE_RUST_WORD2 7 -#define SCE_RUST_WORD3 8 -#define SCE_RUST_WORD4 9 -#define SCE_RUST_WORD5 10 -#define SCE_RUST_WORD6 11 -#define SCE_RUST_WORD7 12 -#define SCE_RUST_STRING 13 -#define SCE_RUST_STRINGR 14 -#define SCE_RUST_CHARACTER 15 -#define SCE_RUST_OPERATOR 16 -#define SCE_RUST_IDENTIFIER 17 -#define SCE_RUST_LIFETIME 18 -#define SCE_RUST_MACRO 19 -#define SCE_RUST_LEXERROR 20 -#define SCE_RUST_BYTESTRING 21 -#define SCE_RUST_BYTESTRINGR 22 -#define SCE_RUST_BYTECHARACTER 23 -#define SCE_DMAP_DEFAULT 0 -#define SCE_DMAP_COMMENT 1 -#define SCE_DMAP_NUMBER 2 -#define SCE_DMAP_STRING1 3 -#define SCE_DMAP_STRING2 4 -#define SCE_DMAP_STRINGEOL 5 -#define SCE_DMAP_OPERATOR 6 -#define SCE_DMAP_IDENTIFIER 7 -#define SCE_DMAP_WORD 8 -#define SCE_DMAP_WORD2 9 -#define SCE_DMAP_WORD3 10 -#define SCE_DMIS_DEFAULT 0 -#define SCE_DMIS_COMMENT 1 -#define SCE_DMIS_STRING 2 -#define SCE_DMIS_NUMBER 3 -#define SCE_DMIS_KEYWORD 4 -#define SCE_DMIS_MAJORWORD 5 -#define SCE_DMIS_MINORWORD 6 -#define SCE_DMIS_UNSUPPORTED_MAJOR 7 -#define SCE_DMIS_UNSUPPORTED_MINOR 8 -#define SCE_DMIS_LABEL 9 -#define SCE_REG_DEFAULT 0 -#define SCE_REG_COMMENT 1 -#define SCE_REG_VALUENAME 2 -#define SCE_REG_STRING 3 -#define SCE_REG_HEXDIGIT 4 -#define SCE_REG_VALUETYPE 5 -#define SCE_REG_ADDEDKEY 6 -#define SCE_REG_DELETEDKEY 7 -#define SCE_REG_ESCAPED 8 -#define SCE_REG_KEYPATH_GUID 9 -#define SCE_REG_STRING_GUID 10 -#define SCE_REG_PARAMETER 11 -#define SCE_REG_OPERATOR 12 -#define SCE_BIBTEX_DEFAULT 0 -#define SCE_BIBTEX_ENTRY 1 -#define SCE_BIBTEX_UNKNOWN_ENTRY 2 -#define SCE_BIBTEX_KEY 3 -#define SCE_BIBTEX_PARAMETER 4 -#define SCE_BIBTEX_VALUE 5 -#define SCE_BIBTEX_COMMENT 6 -#define SCE_HEX_DEFAULT 0 -#define SCE_HEX_RECSTART 1 -#define SCE_HEX_RECTYPE 2 -#define SCE_HEX_RECTYPE_UNKNOWN 3 -#define SCE_HEX_BYTECOUNT 4 -#define SCE_HEX_BYTECOUNT_WRONG 5 -#define SCE_HEX_NOADDRESS 6 -#define SCE_HEX_DATAADDRESS 7 -#define SCE_HEX_RECCOUNT 8 -#define SCE_HEX_STARTADDRESS 9 -#define SCE_HEX_ADDRESSFIELD_UNKNOWN 10 -#define SCE_HEX_EXTENDEDADDRESS 11 -#define SCE_HEX_DATA_ODD 12 -#define SCE_HEX_DATA_EVEN 13 -#define SCE_HEX_DATA_UNKNOWN 14 -#define SCE_HEX_DATA_EMPTY 15 -#define SCE_HEX_CHECKSUM 16 -#define SCE_HEX_CHECKSUM_WRONG 17 -#define SCE_HEX_GARBAGE 18 -#define SCE_JSON_DEFAULT 0 -#define SCE_JSON_NUMBER 1 -#define SCE_JSON_STRING 2 -#define SCE_JSON_STRINGEOL 3 -#define SCE_JSON_PROPERTYNAME 4 -#define SCE_JSON_ESCAPESEQUENCE 5 -#define SCE_JSON_LINECOMMENT 6 -#define SCE_JSON_BLOCKCOMMENT 7 -#define SCE_JSON_OPERATOR 8 -#define SCE_JSON_URI 9 -#define SCE_JSON_COMPACTIRI 10 -#define SCE_JSON_KEYWORD 11 -#define SCE_JSON_LDKEYWORD 12 -#define SCE_JSON_ERROR 13 -#define SCE_EDI_DEFAULT 0 -#define SCE_EDI_SEGMENTSTART 1 -#define SCE_EDI_SEGMENTEND 2 -#define SCE_EDI_SEP_ELEMENT 3 -#define SCE_EDI_SEP_COMPOSITE 4 -#define SCE_EDI_SEP_RELEASE 5 -#define SCE_EDI_UNA 6 -#define SCE_EDI_UNH 7 -#define SCE_EDI_BADSEGMENT 8 -/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/include/Sci_Position.h b/qrenderdoc/3rdparty/scintilla/include/Sci_Position.h deleted file mode 100644 index a83e2864f..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/Sci_Position.h +++ /dev/null @@ -1,21 +0,0 @@ -// Scintilla source code edit control -/** @file Sci_Position.h - ** Define the Sci_Position type used in Scintilla's external interfaces. - ** These need to be available to clients written in C so are not in a C++ namespace. - **/ -// Copyright 2015 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SCI_POSITION_H -#define SCI_POSITION_H - -// Basic signed type used throughout interface -typedef int Sci_Position; - -// Unsigned variant used for ILexer::Lex and ILexer::Fold -typedef unsigned int Sci_PositionU; - -// For Sci_CharacterRange which is defined as long to be compatible with Win32 CHARRANGE -typedef long Sci_PositionCR; - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/include/Scintilla.h b/qrenderdoc/3rdparty/scintilla/include/Scintilla.h deleted file mode 100644 index 6a36d24f4..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/Scintilla.h +++ /dev/null @@ -1,1208 +0,0 @@ -/* Scintilla source code edit control */ -/** @file Scintilla.h - ** Interface to the edit control. - **/ -/* Copyright 1998-2003 by Neil Hodgson - * The License.txt file describes the conditions under which this software may be distributed. */ - -/* Most of this file is automatically generated from the Scintilla.iface interface definition - * file which contains any comments about the definitions. HFacer.py does the generation. */ - -#ifndef SCINTILLA_H -#define SCINTILLA_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(_WIN32) -/* Return false on failure: */ -int Scintilla_RegisterClasses(void *hInstance); -int Scintilla_ReleaseResources(void); -#endif -int Scintilla_LinkLexers(void); - -#ifdef __cplusplus -} -#endif - -// Include header that defines basic numeric types. -#if defined(_MSC_VER) -// Older releases of MSVC did not have stdint.h. -#include -#else -#include -#endif - -// Define uptr_t, an unsigned integer type large enough to hold a pointer. -typedef uintptr_t uptr_t; -// Define sptr_t, a signed integer large enough to hold a pointer. -typedef intptr_t sptr_t; - -#include "Sci_Position.h" - -typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam); - -/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ -#define INVALID_POSITION -1 -#define SCI_START 2000 -#define SCI_OPTIONAL_START 3000 -#define SCI_LEXER_START 4000 -#define SCI_ADDTEXT 2001 -#define SCI_ADDSTYLEDTEXT 2002 -#define SCI_INSERTTEXT 2003 -#define SCI_CHANGEINSERTION 2672 -#define SCI_CLEARALL 2004 -#define SCI_DELETERANGE 2645 -#define SCI_CLEARDOCUMENTSTYLE 2005 -#define SCI_GETLENGTH 2006 -#define SCI_GETCHARAT 2007 -#define SCI_GETCURRENTPOS 2008 -#define SCI_GETANCHOR 2009 -#define SCI_GETSTYLEAT 2010 -#define SCI_REDO 2011 -#define SCI_SETUNDOCOLLECTION 2012 -#define SCI_SELECTALL 2013 -#define SCI_SETSAVEPOINT 2014 -#define SCI_GETSTYLEDTEXT 2015 -#define SCI_CANREDO 2016 -#define SCI_MARKERLINEFROMHANDLE 2017 -#define SCI_MARKERDELETEHANDLE 2018 -#define SCI_GETUNDOCOLLECTION 2019 -#define SCWS_INVISIBLE 0 -#define SCWS_VISIBLEALWAYS 1 -#define SCWS_VISIBLEAFTERINDENT 2 -#define SCWS_VISIBLEONLYININDENT 3 -#define SCI_GETVIEWWS 2020 -#define SCI_SETVIEWWS 2021 -#define SCTD_LONGARROW 0 -#define SCTD_STRIKEOUT 1 -#define SCI_GETTABDRAWMODE 2698 -#define SCI_SETTABDRAWMODE 2699 -#define SCI_POSITIONFROMPOINT 2022 -#define SCI_POSITIONFROMPOINTCLOSE 2023 -#define SCI_GOTOLINE 2024 -#define SCI_GOTOPOS 2025 -#define SCI_SETANCHOR 2026 -#define SCI_GETCURLINE 2027 -#define SCI_GETENDSTYLED 2028 -#define SC_EOL_CRLF 0 -#define SC_EOL_CR 1 -#define SC_EOL_LF 2 -#define SCI_CONVERTEOLS 2029 -#define SCI_GETEOLMODE 2030 -#define SCI_SETEOLMODE 2031 -#define SCI_STARTSTYLING 2032 -#define SCI_SETSTYLING 2033 -#define SCI_GETBUFFEREDDRAW 2034 -#define SCI_SETBUFFEREDDRAW 2035 -#define SCI_SETTABWIDTH 2036 -#define SCI_GETTABWIDTH 2121 -#define SCI_CLEARTABSTOPS 2675 -#define SCI_ADDTABSTOP 2676 -#define SCI_GETNEXTTABSTOP 2677 -#define SC_CP_UTF8 65001 -#define SCI_SETCODEPAGE 2037 -#define SC_IME_WINDOWED 0 -#define SC_IME_INLINE 1 -#define SCI_GETIMEINTERACTION 2678 -#define SCI_SETIMEINTERACTION 2679 -#define MARKER_MAX 31 -#define SC_MARK_CIRCLE 0 -#define SC_MARK_ROUNDRECT 1 -#define SC_MARK_ARROW 2 -#define SC_MARK_SMALLRECT 3 -#define SC_MARK_SHORTARROW 4 -#define SC_MARK_EMPTY 5 -#define SC_MARK_ARROWDOWN 6 -#define SC_MARK_MINUS 7 -#define SC_MARK_PLUS 8 -#define SC_MARK_VLINE 9 -#define SC_MARK_LCORNER 10 -#define SC_MARK_TCORNER 11 -#define SC_MARK_BOXPLUS 12 -#define SC_MARK_BOXPLUSCONNECTED 13 -#define SC_MARK_BOXMINUS 14 -#define SC_MARK_BOXMINUSCONNECTED 15 -#define SC_MARK_LCORNERCURVE 16 -#define SC_MARK_TCORNERCURVE 17 -#define SC_MARK_CIRCLEPLUS 18 -#define SC_MARK_CIRCLEPLUSCONNECTED 19 -#define SC_MARK_CIRCLEMINUS 20 -#define SC_MARK_CIRCLEMINUSCONNECTED 21 -#define SC_MARK_BACKGROUND 22 -#define SC_MARK_DOTDOTDOT 23 -#define SC_MARK_ARROWS 24 -#define SC_MARK_PIXMAP 25 -#define SC_MARK_FULLRECT 26 -#define SC_MARK_LEFTRECT 27 -#define SC_MARK_AVAILABLE 28 -#define SC_MARK_UNDERLINE 29 -#define SC_MARK_RGBAIMAGE 30 -#define SC_MARK_BOOKMARK 31 -#define SC_MARK_CHARACTER 10000 -#define SC_MARKNUM_FOLDEREND 25 -#define SC_MARKNUM_FOLDEROPENMID 26 -#define SC_MARKNUM_FOLDERMIDTAIL 27 -#define SC_MARKNUM_FOLDERTAIL 28 -#define SC_MARKNUM_FOLDERSUB 29 -#define SC_MARKNUM_FOLDER 30 -#define SC_MARKNUM_FOLDEROPEN 31 -#define SC_MASK_FOLDERS 0xFE000000 -#define SCI_MARKERDEFINE 2040 -#define SCI_MARKERSETFORE 2041 -#define SCI_MARKERSETBACK 2042 -#define SCI_MARKERSETBACKSELECTED 2292 -#define SCI_MARKERENABLEHIGHLIGHT 2293 -#define SCI_MARKERADD 2043 -#define SCI_MARKERDELETE 2044 -#define SCI_MARKERDELETEALL 2045 -#define SCI_MARKERGET 2046 -#define SCI_MARKERNEXT 2047 -#define SCI_MARKERPREVIOUS 2048 -#define SCI_MARKERDEFINEPIXMAP 2049 -#define SCI_MARKERADDSET 2466 -#define SCI_MARKERSETALPHA 2476 -#define SC_MAX_MARGIN 4 -#define SC_MARGIN_SYMBOL 0 -#define SC_MARGIN_NUMBER 1 -#define SC_MARGIN_BACK 2 -#define SC_MARGIN_FORE 3 -#define SC_MARGIN_TEXT 4 -#define SC_MARGIN_RTEXT 5 -#define SC_MARGIN_COLOUR 6 -#define SCI_SETMARGINTYPEN 2240 -#define SCI_GETMARGINTYPEN 2241 -#define SCI_SETMARGINWIDTHN 2242 -#define SCI_GETMARGINWIDTHN 2243 -#define SCI_SETMARGINMASKN 2244 -#define SCI_GETMARGINMASKN 2245 -#define SCI_SETMARGINSENSITIVEN 2246 -#define SCI_GETMARGINSENSITIVEN 2247 -#define SCI_SETMARGINCURSORN 2248 -#define SCI_GETMARGINCURSORN 2249 -#define SCI_SETMARGINBACKN 2250 -#define SCI_GETMARGINBACKN 2251 -#define SCI_SETMARGINS 2252 -#define SCI_GETMARGINS 2253 -#define STYLE_DEFAULT 32 -#define STYLE_LINENUMBER 33 -#define STYLE_BRACELIGHT 34 -#define STYLE_BRACEBAD 35 -#define STYLE_CONTROLCHAR 36 -#define STYLE_INDENTGUIDE 37 -#define STYLE_CALLTIP 38 -#define STYLE_FOLDDISPLAYTEXT 39 -#define STYLE_LASTPREDEFINED 39 -#define STYLE_MAX 255 -#define SC_CHARSET_ANSI 0 -#define SC_CHARSET_DEFAULT 1 -#define SC_CHARSET_BALTIC 186 -#define SC_CHARSET_CHINESEBIG5 136 -#define SC_CHARSET_EASTEUROPE 238 -#define SC_CHARSET_GB2312 134 -#define SC_CHARSET_GREEK 161 -#define SC_CHARSET_HANGUL 129 -#define SC_CHARSET_MAC 77 -#define SC_CHARSET_OEM 255 -#define SC_CHARSET_RUSSIAN 204 -#define SC_CHARSET_OEM866 866 -#define SC_CHARSET_CYRILLIC 1251 -#define SC_CHARSET_SHIFTJIS 128 -#define SC_CHARSET_SYMBOL 2 -#define SC_CHARSET_TURKISH 162 -#define SC_CHARSET_JOHAB 130 -#define SC_CHARSET_HEBREW 177 -#define SC_CHARSET_ARABIC 178 -#define SC_CHARSET_VIETNAMESE 163 -#define SC_CHARSET_THAI 222 -#define SC_CHARSET_8859_15 1000 -#define SCI_STYLECLEARALL 2050 -#define SCI_STYLESETFORE 2051 -#define SCI_STYLESETBACK 2052 -#define SCI_STYLESETBOLD 2053 -#define SCI_STYLESETITALIC 2054 -#define SCI_STYLESETSIZE 2055 -#define SCI_STYLESETFONT 2056 -#define SCI_STYLESETEOLFILLED 2057 -#define SCI_STYLERESETDEFAULT 2058 -#define SCI_STYLESETUNDERLINE 2059 -#define SC_CASE_MIXED 0 -#define SC_CASE_UPPER 1 -#define SC_CASE_LOWER 2 -#define SC_CASE_CAMEL 3 -#define SCI_STYLEGETFORE 2481 -#define SCI_STYLEGETBACK 2482 -#define SCI_STYLEGETBOLD 2483 -#define SCI_STYLEGETITALIC 2484 -#define SCI_STYLEGETSIZE 2485 -#define SCI_STYLEGETFONT 2486 -#define SCI_STYLEGETEOLFILLED 2487 -#define SCI_STYLEGETUNDERLINE 2488 -#define SCI_STYLEGETCASE 2489 -#define SCI_STYLEGETCHARACTERSET 2490 -#define SCI_STYLEGETVISIBLE 2491 -#define SCI_STYLEGETCHANGEABLE 2492 -#define SCI_STYLEGETHOTSPOT 2493 -#define SCI_STYLESETCASE 2060 -#define SC_FONT_SIZE_MULTIPLIER 100 -#define SCI_STYLESETSIZEFRACTIONAL 2061 -#define SCI_STYLEGETSIZEFRACTIONAL 2062 -#define SC_WEIGHT_NORMAL 400 -#define SC_WEIGHT_SEMIBOLD 600 -#define SC_WEIGHT_BOLD 700 -#define SCI_STYLESETWEIGHT 2063 -#define SCI_STYLEGETWEIGHT 2064 -#define SCI_STYLESETCHARACTERSET 2066 -#define SCI_STYLESETHOTSPOT 2409 -#define SCI_SETSELFORE 2067 -#define SCI_SETSELBACK 2068 -#define SCI_GETSELALPHA 2477 -#define SCI_SETSELALPHA 2478 -#define SCI_GETSELEOLFILLED 2479 -#define SCI_SETSELEOLFILLED 2480 -#define SCI_SETCARETFORE 2069 -#define SCI_ASSIGNCMDKEY 2070 -#define SCI_CLEARCMDKEY 2071 -#define SCI_CLEARALLCMDKEYS 2072 -#define SCI_SETSTYLINGEX 2073 -#define SCI_STYLESETVISIBLE 2074 -#define SCI_GETCARETPERIOD 2075 -#define SCI_SETCARETPERIOD 2076 -#define SCI_SETWORDCHARS 2077 -#define SCI_GETWORDCHARS 2646 -#define SCI_BEGINUNDOACTION 2078 -#define SCI_ENDUNDOACTION 2079 -#define INDIC_PLAIN 0 -#define INDIC_SQUIGGLE 1 -#define INDIC_TT 2 -#define INDIC_DIAGONAL 3 -#define INDIC_STRIKE 4 -#define INDIC_HIDDEN 5 -#define INDIC_BOX 6 -#define INDIC_ROUNDBOX 7 -#define INDIC_STRAIGHTBOX 8 -#define INDIC_DASH 9 -#define INDIC_DOTS 10 -#define INDIC_SQUIGGLELOW 11 -#define INDIC_DOTBOX 12 -#define INDIC_SQUIGGLEPIXMAP 13 -#define INDIC_COMPOSITIONTHICK 14 -#define INDIC_COMPOSITIONTHIN 15 -#define INDIC_FULLBOX 16 -#define INDIC_TEXTFORE 17 -#define INDIC_POINT 18 -#define INDIC_POINTCHARACTER 19 -#define INDIC_IME 32 -#define INDIC_IME_MAX 35 -#define INDIC_MAX 35 -#define INDIC_CONTAINER 8 -#define INDIC0_MASK 0x20 -#define INDIC1_MASK 0x40 -#define INDIC2_MASK 0x80 -#define INDICS_MASK 0xE0 -#define SCI_INDICSETSTYLE 2080 -#define SCI_INDICGETSTYLE 2081 -#define SCI_INDICSETFORE 2082 -#define SCI_INDICGETFORE 2083 -#define SCI_INDICSETUNDER 2510 -#define SCI_INDICGETUNDER 2511 -#define SCI_INDICSETHOVERSTYLE 2680 -#define SCI_INDICGETHOVERSTYLE 2681 -#define SCI_INDICSETHOVERFORE 2682 -#define SCI_INDICGETHOVERFORE 2683 -#define SC_INDICVALUEBIT 0x1000000 -#define SC_INDICVALUEMASK 0xFFFFFF -#define SC_INDICFLAG_VALUEFORE 1 -#define SCI_INDICSETFLAGS 2684 -#define SCI_INDICGETFLAGS 2685 -#define SCI_SETWHITESPACEFORE 2084 -#define SCI_SETWHITESPACEBACK 2085 -#define SCI_SETWHITESPACESIZE 2086 -#define SCI_GETWHITESPACESIZE 2087 -#define SCI_SETSTYLEBITS 2090 -#define SCI_GETSTYLEBITS 2091 -#define SCI_SETLINESTATE 2092 -#define SCI_GETLINESTATE 2093 -#define SCI_GETMAXLINESTATE 2094 -#define SCI_GETCARETLINEVISIBLE 2095 -#define SCI_SETCARETLINEVISIBLE 2096 -#define SCI_GETCARETLINEBACK 2097 -#define SCI_SETCARETLINEBACK 2098 -#define SCI_STYLESETCHANGEABLE 2099 -#define SCI_AUTOCSHOW 2100 -#define SCI_AUTOCCANCEL 2101 -#define SCI_AUTOCACTIVE 2102 -#define SCI_AUTOCPOSSTART 2103 -#define SCI_AUTOCCOMPLETE 2104 -#define SCI_AUTOCSTOPS 2105 -#define SCI_AUTOCSETSEPARATOR 2106 -#define SCI_AUTOCGETSEPARATOR 2107 -#define SCI_AUTOCSELECT 2108 -#define SCI_AUTOCSETCANCELATSTART 2110 -#define SCI_AUTOCGETCANCELATSTART 2111 -#define SCI_AUTOCSETFILLUPS 2112 -#define SCI_AUTOCSETCHOOSESINGLE 2113 -#define SCI_AUTOCGETCHOOSESINGLE 2114 -#define SCI_AUTOCSETIGNORECASE 2115 -#define SCI_AUTOCGETIGNORECASE 2116 -#define SCI_USERLISTSHOW 2117 -#define SCI_AUTOCSETAUTOHIDE 2118 -#define SCI_AUTOCGETAUTOHIDE 2119 -#define SCI_AUTOCSETDROPRESTOFWORD 2270 -#define SCI_AUTOCGETDROPRESTOFWORD 2271 -#define SCI_REGISTERIMAGE 2405 -#define SCI_CLEARREGISTEREDIMAGES 2408 -#define SCI_AUTOCGETTYPESEPARATOR 2285 -#define SCI_AUTOCSETTYPESEPARATOR 2286 -#define SCI_AUTOCSETMAXWIDTH 2208 -#define SCI_AUTOCGETMAXWIDTH 2209 -#define SCI_AUTOCSETMAXHEIGHT 2210 -#define SCI_AUTOCGETMAXHEIGHT 2211 -#define SCI_SETINDENT 2122 -#define SCI_GETINDENT 2123 -#define SCI_SETUSETABS 2124 -#define SCI_GETUSETABS 2125 -#define SCI_SETLINEINDENTATION 2126 -#define SCI_GETLINEINDENTATION 2127 -#define SCI_GETLINEINDENTPOSITION 2128 -#define SCI_GETCOLUMN 2129 -#define SCI_COUNTCHARACTERS 2633 -#define SCI_SETHSCROLLBAR 2130 -#define SCI_GETHSCROLLBAR 2131 -#define SC_IV_NONE 0 -#define SC_IV_REAL 1 -#define SC_IV_LOOKFORWARD 2 -#define SC_IV_LOOKBOTH 3 -#define SCI_SETINDENTATIONGUIDES 2132 -#define SCI_GETINDENTATIONGUIDES 2133 -#define SCI_SETHIGHLIGHTGUIDE 2134 -#define SCI_GETHIGHLIGHTGUIDE 2135 -#define SCI_GETLINEENDPOSITION 2136 -#define SCI_GETCODEPAGE 2137 -#define SCI_GETCARETFORE 2138 -#define SCI_GETREADONLY 2140 -#define SCI_SETCURRENTPOS 2141 -#define SCI_SETSELECTIONSTART 2142 -#define SCI_GETSELECTIONSTART 2143 -#define SCI_SETSELECTIONEND 2144 -#define SCI_GETSELECTIONEND 2145 -#define SCI_SETEMPTYSELECTION 2556 -#define SCI_SETPRINTMAGNIFICATION 2146 -#define SCI_GETPRINTMAGNIFICATION 2147 -#define SC_PRINT_NORMAL 0 -#define SC_PRINT_INVERTLIGHT 1 -#define SC_PRINT_BLACKONWHITE 2 -#define SC_PRINT_COLOURONWHITE 3 -#define SC_PRINT_COLOURONWHITEDEFAULTBG 4 -#define SCI_SETPRINTCOLOURMODE 2148 -#define SCI_GETPRINTCOLOURMODE 2149 -#define SCFIND_WHOLEWORD 0x2 -#define SCFIND_MATCHCASE 0x4 -#define SCFIND_WORDSTART 0x00100000 -#define SCFIND_REGEXP 0x00200000 -#define SCFIND_POSIX 0x00400000 -#define SCFIND_CXX11REGEX 0x00800000 -#define SCI_FINDTEXT 2150 -#define SCI_FORMATRANGE 2151 -#define SCI_GETFIRSTVISIBLELINE 2152 -#define SCI_GETLINE 2153 -#define SCI_GETLINECOUNT 2154 -#define SCI_SETMARGINLEFT 2155 -#define SCI_GETMARGINLEFT 2156 -#define SCI_SETMARGINRIGHT 2157 -#define SCI_GETMARGINRIGHT 2158 -#define SCI_GETMODIFY 2159 -#define SCI_SETSEL 2160 -#define SCI_GETSELTEXT 2161 -#define SCI_GETTEXTRANGE 2162 -#define SCI_HIDESELECTION 2163 -#define SCI_POINTXFROMPOSITION 2164 -#define SCI_POINTYFROMPOSITION 2165 -#define SCI_LINEFROMPOSITION 2166 -#define SCI_POSITIONFROMLINE 2167 -#define SCI_LINESCROLL 2168 -#define SCI_SCROLLCARET 2169 -#define SCI_SCROLLRANGE 2569 -#define SCI_REPLACESEL 2170 -#define SCI_SETREADONLY 2171 -#define SCI_NULL 2172 -#define SCI_CANPASTE 2173 -#define SCI_CANUNDO 2174 -#define SCI_EMPTYUNDOBUFFER 2175 -#define SCI_UNDO 2176 -#define SCI_CUT 2177 -#define SCI_COPY 2178 -#define SCI_PASTE 2179 -#define SCI_CLEAR 2180 -#define SCI_SETTEXT 2181 -#define SCI_GETTEXT 2182 -#define SCI_GETTEXTLENGTH 2183 -#define SCI_GETDIRECTFUNCTION 2184 -#define SCI_GETDIRECTPOINTER 2185 -#define SCI_SETOVERTYPE 2186 -#define SCI_GETOVERTYPE 2187 -#define SCI_SETCARETWIDTH 2188 -#define SCI_GETCARETWIDTH 2189 -#define SCI_SETTARGETSTART 2190 -#define SCI_GETTARGETSTART 2191 -#define SCI_SETTARGETEND 2192 -#define SCI_GETTARGETEND 2193 -#define SCI_SETTARGETRANGE 2686 -#define SCI_GETTARGETTEXT 2687 -#define SCI_TARGETFROMSELECTION 2287 -#define SCI_TARGETWHOLEDOCUMENT 2690 -#define SCI_REPLACETARGET 2194 -#define SCI_REPLACETARGETRE 2195 -#define SCI_SEARCHINTARGET 2197 -#define SCI_SETSEARCHFLAGS 2198 -#define SCI_GETSEARCHFLAGS 2199 -#define SCI_CALLTIPSHOW 2200 -#define SCI_CALLTIPCANCEL 2201 -#define SCI_CALLTIPACTIVE 2202 -#define SCI_CALLTIPPOSSTART 2203 -#define SCI_CALLTIPSETPOSSTART 2214 -#define SCI_CALLTIPSETHLT 2204 -#define SCI_CALLTIPSETBACK 2205 -#define SCI_CALLTIPSETFORE 2206 -#define SCI_CALLTIPSETFOREHLT 2207 -#define SCI_CALLTIPUSESTYLE 2212 -#define SCI_CALLTIPSETPOSITION 2213 -#define SCI_VISIBLEFROMDOCLINE 2220 -#define SCI_DOCLINEFROMVISIBLE 2221 -#define SCI_WRAPCOUNT 2235 -#define SC_FOLDLEVELBASE 0x400 -#define SC_FOLDLEVELWHITEFLAG 0x1000 -#define SC_FOLDLEVELHEADERFLAG 0x2000 -#define SC_FOLDLEVELNUMBERMASK 0x0FFF -#define SCI_SETFOLDLEVEL 2222 -#define SCI_GETFOLDLEVEL 2223 -#define SCI_GETLASTCHILD 2224 -#define SCI_GETFOLDPARENT 2225 -#define SCI_SHOWLINES 2226 -#define SCI_HIDELINES 2227 -#define SCI_GETLINEVISIBLE 2228 -#define SCI_GETALLLINESVISIBLE 2236 -#define SCI_SETFOLDEXPANDED 2229 -#define SCI_GETFOLDEXPANDED 2230 -#define SCI_TOGGLEFOLD 2231 -#define SCI_TOGGLEFOLDSHOWTEXT 2700 -#define SC_FOLDDISPLAYTEXT_HIDDEN 0 -#define SC_FOLDDISPLAYTEXT_STANDARD 1 -#define SC_FOLDDISPLAYTEXT_BOXED 2 -#define SCI_FOLDDISPLAYTEXTSETSTYLE 2701 -#define SC_FOLDACTION_CONTRACT 0 -#define SC_FOLDACTION_EXPAND 1 -#define SC_FOLDACTION_TOGGLE 2 -#define SCI_FOLDLINE 2237 -#define SCI_FOLDCHILDREN 2238 -#define SCI_EXPANDCHILDREN 2239 -#define SCI_FOLDALL 2662 -#define SCI_ENSUREVISIBLE 2232 -#define SC_AUTOMATICFOLD_SHOW 0x0001 -#define SC_AUTOMATICFOLD_CLICK 0x0002 -#define SC_AUTOMATICFOLD_CHANGE 0x0004 -#define SCI_SETAUTOMATICFOLD 2663 -#define SCI_GETAUTOMATICFOLD 2664 -#define SC_FOLDFLAG_LINEBEFORE_EXPANDED 0x0002 -#define SC_FOLDFLAG_LINEBEFORE_CONTRACTED 0x0004 -#define SC_FOLDFLAG_LINEAFTER_EXPANDED 0x0008 -#define SC_FOLDFLAG_LINEAFTER_CONTRACTED 0x0010 -#define SC_FOLDFLAG_LEVELNUMBERS 0x0040 -#define SC_FOLDFLAG_LINESTATE 0x0080 -#define SCI_SETFOLDFLAGS 2233 -#define SCI_ENSUREVISIBLEENFORCEPOLICY 2234 -#define SCI_SETTABINDENTS 2260 -#define SCI_GETTABINDENTS 2261 -#define SCI_SETBACKSPACEUNINDENTS 2262 -#define SCI_GETBACKSPACEUNINDENTS 2263 -#define SC_TIME_FOREVER 10000000 -#define SCI_SETMOUSEDWELLTIME 2264 -#define SCI_GETMOUSEDWELLTIME 2265 -#define SCI_WORDSTARTPOSITION 2266 -#define SCI_WORDENDPOSITION 2267 -#define SCI_ISRANGEWORD 2691 -#define SC_IDLESTYLING_NONE 0 -#define SC_IDLESTYLING_TOVISIBLE 1 -#define SC_IDLESTYLING_AFTERVISIBLE 2 -#define SC_IDLESTYLING_ALL 3 -#define SCI_SETIDLESTYLING 2692 -#define SCI_GETIDLESTYLING 2693 -#define SC_WRAP_NONE 0 -#define SC_WRAP_WORD 1 -#define SC_WRAP_CHAR 2 -#define SC_WRAP_WHITESPACE 3 -#define SCI_SETWRAPMODE 2268 -#define SCI_GETWRAPMODE 2269 -#define SC_WRAPVISUALFLAG_NONE 0x0000 -#define SC_WRAPVISUALFLAG_END 0x0001 -#define SC_WRAPVISUALFLAG_START 0x0002 -#define SC_WRAPVISUALFLAG_MARGIN 0x0004 -#define SCI_SETWRAPVISUALFLAGS 2460 -#define SCI_GETWRAPVISUALFLAGS 2461 -#define SC_WRAPVISUALFLAGLOC_DEFAULT 0x0000 -#define SC_WRAPVISUALFLAGLOC_END_BY_TEXT 0x0001 -#define SC_WRAPVISUALFLAGLOC_START_BY_TEXT 0x0002 -#define SCI_SETWRAPVISUALFLAGSLOCATION 2462 -#define SCI_GETWRAPVISUALFLAGSLOCATION 2463 -#define SCI_SETWRAPSTARTINDENT 2464 -#define SCI_GETWRAPSTARTINDENT 2465 -#define SC_WRAPINDENT_FIXED 0 -#define SC_WRAPINDENT_SAME 1 -#define SC_WRAPINDENT_INDENT 2 -#define SCI_SETWRAPINDENTMODE 2472 -#define SCI_GETWRAPINDENTMODE 2473 -#define SC_CACHE_NONE 0 -#define SC_CACHE_CARET 1 -#define SC_CACHE_PAGE 2 -#define SC_CACHE_DOCUMENT 3 -#define SCI_SETLAYOUTCACHE 2272 -#define SCI_GETLAYOUTCACHE 2273 -#define SCI_SETSCROLLWIDTH 2274 -#define SCI_GETSCROLLWIDTH 2275 -#define SCI_SETSCROLLWIDTHTRACKING 2516 -#define SCI_GETSCROLLWIDTHTRACKING 2517 -#define SCI_TEXTWIDTH 2276 -#define SCI_SETENDATLASTLINE 2277 -#define SCI_GETENDATLASTLINE 2278 -#define SCI_TEXTHEIGHT 2279 -#define SCI_SETVSCROLLBAR 2280 -#define SCI_GETVSCROLLBAR 2281 -#define SCI_APPENDTEXT 2282 -#define SCI_GETTWOPHASEDRAW 2283 -#define SCI_SETTWOPHASEDRAW 2284 -#define SC_PHASES_ONE 0 -#define SC_PHASES_TWO 1 -#define SC_PHASES_MULTIPLE 2 -#define SCI_GETPHASESDRAW 2673 -#define SCI_SETPHASESDRAW 2674 -#define SC_EFF_QUALITY_MASK 0xF -#define SC_EFF_QUALITY_DEFAULT 0 -#define SC_EFF_QUALITY_NON_ANTIALIASED 1 -#define SC_EFF_QUALITY_ANTIALIASED 2 -#define SC_EFF_QUALITY_LCD_OPTIMIZED 3 -#define SCI_SETFONTQUALITY 2611 -#define SCI_GETFONTQUALITY 2612 -#define SCI_SETFIRSTVISIBLELINE 2613 -#define SC_MULTIPASTE_ONCE 0 -#define SC_MULTIPASTE_EACH 1 -#define SCI_SETMULTIPASTE 2614 -#define SCI_GETMULTIPASTE 2615 -#define SCI_GETTAG 2616 -#define SCI_LINESJOIN 2288 -#define SCI_LINESSPLIT 2289 -#define SCI_SETFOLDMARGINCOLOUR 2290 -#define SCI_SETFOLDMARGINHICOLOUR 2291 -#define SCI_LINEDOWN 2300 -#define SCI_LINEDOWNEXTEND 2301 -#define SCI_LINEUP 2302 -#define SCI_LINEUPEXTEND 2303 -#define SCI_CHARLEFT 2304 -#define SCI_CHARLEFTEXTEND 2305 -#define SCI_CHARRIGHT 2306 -#define SCI_CHARRIGHTEXTEND 2307 -#define SCI_WORDLEFT 2308 -#define SCI_WORDLEFTEXTEND 2309 -#define SCI_WORDRIGHT 2310 -#define SCI_WORDRIGHTEXTEND 2311 -#define SCI_HOME 2312 -#define SCI_HOMEEXTEND 2313 -#define SCI_LINEEND 2314 -#define SCI_LINEENDEXTEND 2315 -#define SCI_DOCUMENTSTART 2316 -#define SCI_DOCUMENTSTARTEXTEND 2317 -#define SCI_DOCUMENTEND 2318 -#define SCI_DOCUMENTENDEXTEND 2319 -#define SCI_PAGEUP 2320 -#define SCI_PAGEUPEXTEND 2321 -#define SCI_PAGEDOWN 2322 -#define SCI_PAGEDOWNEXTEND 2323 -#define SCI_EDITTOGGLEOVERTYPE 2324 -#define SCI_CANCEL 2325 -#define SCI_DELETEBACK 2326 -#define SCI_TAB 2327 -#define SCI_BACKTAB 2328 -#define SCI_NEWLINE 2329 -#define SCI_FORMFEED 2330 -#define SCI_VCHOME 2331 -#define SCI_VCHOMEEXTEND 2332 -#define SCI_ZOOMIN 2333 -#define SCI_ZOOMOUT 2334 -#define SCI_DELWORDLEFT 2335 -#define SCI_DELWORDRIGHT 2336 -#define SCI_DELWORDRIGHTEND 2518 -#define SCI_LINECUT 2337 -#define SCI_LINEDELETE 2338 -#define SCI_LINETRANSPOSE 2339 -#define SCI_LINEDUPLICATE 2404 -#define SCI_LOWERCASE 2340 -#define SCI_UPPERCASE 2341 -#define SCI_LINESCROLLDOWN 2342 -#define SCI_LINESCROLLUP 2343 -#define SCI_DELETEBACKNOTLINE 2344 -#define SCI_HOMEDISPLAY 2345 -#define SCI_HOMEDISPLAYEXTEND 2346 -#define SCI_LINEENDDISPLAY 2347 -#define SCI_LINEENDDISPLAYEXTEND 2348 -#define SCI_HOMEWRAP 2349 -#define SCI_HOMEWRAPEXTEND 2450 -#define SCI_LINEENDWRAP 2451 -#define SCI_LINEENDWRAPEXTEND 2452 -#define SCI_VCHOMEWRAP 2453 -#define SCI_VCHOMEWRAPEXTEND 2454 -#define SCI_LINECOPY 2455 -#define SCI_MOVECARETINSIDEVIEW 2401 -#define SCI_LINELENGTH 2350 -#define SCI_BRACEHIGHLIGHT 2351 -#define SCI_BRACEHIGHLIGHTINDICATOR 2498 -#define SCI_BRACEBADLIGHT 2352 -#define SCI_BRACEBADLIGHTINDICATOR 2499 -#define SCI_BRACEMATCH 2353 -#define SCI_GETVIEWEOL 2355 -#define SCI_SETVIEWEOL 2356 -#define SCI_GETDOCPOINTER 2357 -#define SCI_SETDOCPOINTER 2358 -#define SCI_SETMODEVENTMASK 2359 -#define EDGE_NONE 0 -#define EDGE_LINE 1 -#define EDGE_BACKGROUND 2 -#define EDGE_MULTILINE 3 -#define SCI_GETEDGECOLUMN 2360 -#define SCI_SETEDGECOLUMN 2361 -#define SCI_GETEDGEMODE 2362 -#define SCI_SETEDGEMODE 2363 -#define SCI_GETEDGECOLOUR 2364 -#define SCI_SETEDGECOLOUR 2365 -#define SCI_MULTIEDGEADDLINE 2694 -#define SCI_MULTIEDGECLEARALL 2695 -#define SCI_SEARCHANCHOR 2366 -#define SCI_SEARCHNEXT 2367 -#define SCI_SEARCHPREV 2368 -#define SCI_LINESONSCREEN 2370 -#define SC_POPUP_NEVER 0 -#define SC_POPUP_ALL 1 -#define SC_POPUP_TEXT 2 -#define SCI_USEPOPUP 2371 -#define SCI_SELECTIONISRECTANGLE 2372 -#define SCI_SETZOOM 2373 -#define SCI_GETZOOM 2374 -#define SCI_CREATEDOCUMENT 2375 -#define SCI_ADDREFDOCUMENT 2376 -#define SCI_RELEASEDOCUMENT 2377 -#define SCI_GETMODEVENTMASK 2378 -#define SCI_SETFOCUS 2380 -#define SCI_GETFOCUS 2381 -#define SC_STATUS_OK 0 -#define SC_STATUS_FAILURE 1 -#define SC_STATUS_BADALLOC 2 -#define SC_STATUS_WARN_START 1000 -#define SC_STATUS_WARN_REGEX 1001 -#define SCI_SETSTATUS 2382 -#define SCI_GETSTATUS 2383 -#define SCI_SETMOUSEDOWNCAPTURES 2384 -#define SCI_GETMOUSEDOWNCAPTURES 2385 -#define SCI_SETMOUSEWHEELCAPTURES 2696 -#define SCI_GETMOUSEWHEELCAPTURES 2697 -#define SC_CURSORNORMAL -1 -#define SC_CURSORARROW 2 -#define SC_CURSORWAIT 4 -#define SC_CURSORREVERSEARROW 7 -#define SCI_SETCURSOR 2386 -#define SCI_GETCURSOR 2387 -#define SCI_SETCONTROLCHARSYMBOL 2388 -#define SCI_GETCONTROLCHARSYMBOL 2389 -#define SCI_WORDPARTLEFT 2390 -#define SCI_WORDPARTLEFTEXTEND 2391 -#define SCI_WORDPARTRIGHT 2392 -#define SCI_WORDPARTRIGHTEXTEND 2393 -#define VISIBLE_SLOP 0x01 -#define VISIBLE_STRICT 0x04 -#define SCI_SETVISIBLEPOLICY 2394 -#define SCI_DELLINELEFT 2395 -#define SCI_DELLINERIGHT 2396 -#define SCI_SETXOFFSET 2397 -#define SCI_GETXOFFSET 2398 -#define SCI_CHOOSECARETX 2399 -#define SCI_GRABFOCUS 2400 -#define CARET_SLOP 0x01 -#define CARET_STRICT 0x04 -#define CARET_JUMPS 0x10 -#define CARET_EVEN 0x08 -#define SCI_SETXCARETPOLICY 2402 -#define SCI_SETYCARETPOLICY 2403 -#define SCI_SETPRINTWRAPMODE 2406 -#define SCI_GETPRINTWRAPMODE 2407 -#define SCI_SETHOTSPOTACTIVEFORE 2410 -#define SCI_GETHOTSPOTACTIVEFORE 2494 -#define SCI_SETHOTSPOTACTIVEBACK 2411 -#define SCI_GETHOTSPOTACTIVEBACK 2495 -#define SCI_SETHOTSPOTACTIVEUNDERLINE 2412 -#define SCI_GETHOTSPOTACTIVEUNDERLINE 2496 -#define SCI_SETHOTSPOTSINGLELINE 2421 -#define SCI_GETHOTSPOTSINGLELINE 2497 -#define SCI_PARADOWN 2413 -#define SCI_PARADOWNEXTEND 2414 -#define SCI_PARAUP 2415 -#define SCI_PARAUPEXTEND 2416 -#define SCI_POSITIONBEFORE 2417 -#define SCI_POSITIONAFTER 2418 -#define SCI_POSITIONRELATIVE 2670 -#define SCI_COPYRANGE 2419 -#define SCI_COPYTEXT 2420 -#define SC_SEL_STREAM 0 -#define SC_SEL_RECTANGLE 1 -#define SC_SEL_LINES 2 -#define SC_SEL_THIN 3 -#define SCI_SETSELECTIONMODE 2422 -#define SCI_GETSELECTIONMODE 2423 -#define SCI_GETLINESELSTARTPOSITION 2424 -#define SCI_GETLINESELENDPOSITION 2425 -#define SCI_LINEDOWNRECTEXTEND 2426 -#define SCI_LINEUPRECTEXTEND 2427 -#define SCI_CHARLEFTRECTEXTEND 2428 -#define SCI_CHARRIGHTRECTEXTEND 2429 -#define SCI_HOMERECTEXTEND 2430 -#define SCI_VCHOMERECTEXTEND 2431 -#define SCI_LINEENDRECTEXTEND 2432 -#define SCI_PAGEUPRECTEXTEND 2433 -#define SCI_PAGEDOWNRECTEXTEND 2434 -#define SCI_STUTTEREDPAGEUP 2435 -#define SCI_STUTTEREDPAGEUPEXTEND 2436 -#define SCI_STUTTEREDPAGEDOWN 2437 -#define SCI_STUTTEREDPAGEDOWNEXTEND 2438 -#define SCI_WORDLEFTEND 2439 -#define SCI_WORDLEFTENDEXTEND 2440 -#define SCI_WORDRIGHTEND 2441 -#define SCI_WORDRIGHTENDEXTEND 2442 -#define SCI_SETWHITESPACECHARS 2443 -#define SCI_GETWHITESPACECHARS 2647 -#define SCI_SETPUNCTUATIONCHARS 2648 -#define SCI_GETPUNCTUATIONCHARS 2649 -#define SCI_SETCHARSDEFAULT 2444 -#define SCI_AUTOCGETCURRENT 2445 -#define SCI_AUTOCGETCURRENTTEXT 2610 -#define SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE 0 -#define SC_CASEINSENSITIVEBEHAVIOUR_IGNORECASE 1 -#define SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR 2634 -#define SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR 2635 -#define SC_MULTIAUTOC_ONCE 0 -#define SC_MULTIAUTOC_EACH 1 -#define SCI_AUTOCSETMULTI 2636 -#define SCI_AUTOCGETMULTI 2637 -#define SC_ORDER_PRESORTED 0 -#define SC_ORDER_PERFORMSORT 1 -#define SC_ORDER_CUSTOM 2 -#define SCI_AUTOCSETORDER 2660 -#define SCI_AUTOCGETORDER 2661 -#define SCI_ALLOCATE 2446 -#define SCI_TARGETASUTF8 2447 -#define SCI_SETLENGTHFORENCODE 2448 -#define SCI_ENCODEDFROMUTF8 2449 -#define SCI_FINDCOLUMN 2456 -#define SCI_GETCARETSTICKY 2457 -#define SCI_SETCARETSTICKY 2458 -#define SC_CARETSTICKY_OFF 0 -#define SC_CARETSTICKY_ON 1 -#define SC_CARETSTICKY_WHITESPACE 2 -#define SCI_TOGGLECARETSTICKY 2459 -#define SCI_SETPASTECONVERTENDINGS 2467 -#define SCI_GETPASTECONVERTENDINGS 2468 -#define SCI_SELECTIONDUPLICATE 2469 -#define SC_ALPHA_TRANSPARENT 0 -#define SC_ALPHA_OPAQUE 255 -#define SC_ALPHA_NOALPHA 256 -#define SCI_SETCARETLINEBACKALPHA 2470 -#define SCI_GETCARETLINEBACKALPHA 2471 -#define CARETSTYLE_INVISIBLE 0 -#define CARETSTYLE_LINE 1 -#define CARETSTYLE_BLOCK 2 -#define SCI_SETCARETSTYLE 2512 -#define SCI_GETCARETSTYLE 2513 -#define SCI_SETINDICATORCURRENT 2500 -#define SCI_GETINDICATORCURRENT 2501 -#define SCI_SETINDICATORVALUE 2502 -#define SCI_GETINDICATORVALUE 2503 -#define SCI_INDICATORFILLRANGE 2504 -#define SCI_INDICATORCLEARRANGE 2505 -#define SCI_INDICATORALLONFOR 2506 -#define SCI_INDICATORVALUEAT 2507 -#define SCI_INDICATORSTART 2508 -#define SCI_INDICATOREND 2509 -#define SCI_SETPOSITIONCACHE 2514 -#define SCI_GETPOSITIONCACHE 2515 -#define SCI_COPYALLOWLINE 2519 -#define SCI_GETCHARACTERPOINTER 2520 -#define SCI_GETRANGEPOINTER 2643 -#define SCI_GETGAPPOSITION 2644 -#define SCI_INDICSETALPHA 2523 -#define SCI_INDICGETALPHA 2524 -#define SCI_INDICSETOUTLINEALPHA 2558 -#define SCI_INDICGETOUTLINEALPHA 2559 -#define SCI_SETEXTRAASCENT 2525 -#define SCI_GETEXTRAASCENT 2526 -#define SCI_SETEXTRADESCENT 2527 -#define SCI_GETEXTRADESCENT 2528 -#define SCI_MARKERSYMBOLDEFINED 2529 -#define SCI_MARGINSETTEXT 2530 -#define SCI_MARGINGETTEXT 2531 -#define SCI_MARGINSETSTYLE 2532 -#define SCI_MARGINGETSTYLE 2533 -#define SCI_MARGINSETSTYLES 2534 -#define SCI_MARGINGETSTYLES 2535 -#define SCI_MARGINTEXTCLEARALL 2536 -#define SCI_MARGINSETSTYLEOFFSET 2537 -#define SCI_MARGINGETSTYLEOFFSET 2538 -#define SC_MARGINOPTION_NONE 0 -#define SC_MARGINOPTION_SUBLINESELECT 1 -#define SCI_SETMARGINOPTIONS 2539 -#define SCI_GETMARGINOPTIONS 2557 -#define SCI_ANNOTATIONSETTEXT 2540 -#define SCI_ANNOTATIONGETTEXT 2541 -#define SCI_ANNOTATIONSETSTYLE 2542 -#define SCI_ANNOTATIONGETSTYLE 2543 -#define SCI_ANNOTATIONSETSTYLES 2544 -#define SCI_ANNOTATIONGETSTYLES 2545 -#define SCI_ANNOTATIONGETLINES 2546 -#define SCI_ANNOTATIONCLEARALL 2547 -#define ANNOTATION_HIDDEN 0 -#define ANNOTATION_STANDARD 1 -#define ANNOTATION_BOXED 2 -#define ANNOTATION_INDENTED 3 -#define SCI_ANNOTATIONSETVISIBLE 2548 -#define SCI_ANNOTATIONGETVISIBLE 2549 -#define SCI_ANNOTATIONSETSTYLEOFFSET 2550 -#define SCI_ANNOTATIONGETSTYLEOFFSET 2551 -#define SCI_RELEASEALLEXTENDEDSTYLES 2552 -#define SCI_ALLOCATEEXTENDEDSTYLES 2553 -#define UNDO_MAY_COALESCE 1 -#define SCI_ADDUNDOACTION 2560 -#define SCI_CHARPOSITIONFROMPOINT 2561 -#define SCI_CHARPOSITIONFROMPOINTCLOSE 2562 -#define SCI_SETMOUSESELECTIONRECTANGULARSWITCH 2668 -#define SCI_GETMOUSESELECTIONRECTANGULARSWITCH 2669 -#define SCI_SETMULTIPLESELECTION 2563 -#define SCI_GETMULTIPLESELECTION 2564 -#define SCI_SETADDITIONALSELECTIONTYPING 2565 -#define SCI_GETADDITIONALSELECTIONTYPING 2566 -#define SCI_SETADDITIONALCARETSBLINK 2567 -#define SCI_GETADDITIONALCARETSBLINK 2568 -#define SCI_SETADDITIONALCARETSVISIBLE 2608 -#define SCI_GETADDITIONALCARETSVISIBLE 2609 -#define SCI_GETSELECTIONS 2570 -#define SCI_GETSELECTIONEMPTY 2650 -#define SCI_CLEARSELECTIONS 2571 -#define SCI_SETSELECTION 2572 -#define SCI_ADDSELECTION 2573 -#define SCI_DROPSELECTIONN 2671 -#define SCI_SETMAINSELECTION 2574 -#define SCI_GETMAINSELECTION 2575 -#define SCI_SETSELECTIONNCARET 2576 -#define SCI_GETSELECTIONNCARET 2577 -#define SCI_SETSELECTIONNANCHOR 2578 -#define SCI_GETSELECTIONNANCHOR 2579 -#define SCI_SETSELECTIONNCARETVIRTUALSPACE 2580 -#define SCI_GETSELECTIONNCARETVIRTUALSPACE 2581 -#define SCI_SETSELECTIONNANCHORVIRTUALSPACE 2582 -#define SCI_GETSELECTIONNANCHORVIRTUALSPACE 2583 -#define SCI_SETSELECTIONNSTART 2584 -#define SCI_GETSELECTIONNSTART 2585 -#define SCI_SETSELECTIONNEND 2586 -#define SCI_GETSELECTIONNEND 2587 -#define SCI_SETRECTANGULARSELECTIONCARET 2588 -#define SCI_GETRECTANGULARSELECTIONCARET 2589 -#define SCI_SETRECTANGULARSELECTIONANCHOR 2590 -#define SCI_GETRECTANGULARSELECTIONANCHOR 2591 -#define SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE 2592 -#define SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE 2593 -#define SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2594 -#define SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE 2595 -#define SCVS_NONE 0 -#define SCVS_RECTANGULARSELECTION 1 -#define SCVS_USERACCESSIBLE 2 -#define SCVS_NOWRAPLINESTART 4 -#define SCI_SETVIRTUALSPACEOPTIONS 2596 -#define SCI_GETVIRTUALSPACEOPTIONS 2597 -#define SCI_SETRECTANGULARSELECTIONMODIFIER 2598 -#define SCI_GETRECTANGULARSELECTIONMODIFIER 2599 -#define SCI_SETADDITIONALSELFORE 2600 -#define SCI_SETADDITIONALSELBACK 2601 -#define SCI_SETADDITIONALSELALPHA 2602 -#define SCI_GETADDITIONALSELALPHA 2603 -#define SCI_SETADDITIONALCARETFORE 2604 -#define SCI_GETADDITIONALCARETFORE 2605 -#define SCI_ROTATESELECTION 2606 -#define SCI_SWAPMAINANCHORCARET 2607 -#define SCI_MULTIPLESELECTADDNEXT 2688 -#define SCI_MULTIPLESELECTADDEACH 2689 -#define SCI_CHANGELEXERSTATE 2617 -#define SCI_CONTRACTEDFOLDNEXT 2618 -#define SCI_VERTICALCENTRECARET 2619 -#define SCI_MOVESELECTEDLINESUP 2620 -#define SCI_MOVESELECTEDLINESDOWN 2621 -#define SCI_SETIDENTIFIER 2622 -#define SCI_GETIDENTIFIER 2623 -#define SCI_RGBAIMAGESETWIDTH 2624 -#define SCI_RGBAIMAGESETHEIGHT 2625 -#define SCI_RGBAIMAGESETSCALE 2651 -#define SCI_MARKERDEFINERGBAIMAGE 2626 -#define SCI_REGISTERRGBAIMAGE 2627 -#define SCI_SCROLLTOSTART 2628 -#define SCI_SCROLLTOEND 2629 -#define SC_TECHNOLOGY_DEFAULT 0 -#define SC_TECHNOLOGY_DIRECTWRITE 1 -#define SC_TECHNOLOGY_DIRECTWRITERETAIN 2 -#define SC_TECHNOLOGY_DIRECTWRITEDC 3 -#define SCI_SETTECHNOLOGY 2630 -#define SCI_GETTECHNOLOGY 2631 -#define SCI_CREATELOADER 2632 -#define SCI_FINDINDICATORSHOW 2640 -#define SCI_FINDINDICATORFLASH 2641 -#define SCI_FINDINDICATORHIDE 2642 -#define SCI_VCHOMEDISPLAY 2652 -#define SCI_VCHOMEDISPLAYEXTEND 2653 -#define SCI_GETCARETLINEVISIBLEALWAYS 2654 -#define SCI_SETCARETLINEVISIBLEALWAYS 2655 -#define SC_LINE_END_TYPE_DEFAULT 0 -#define SC_LINE_END_TYPE_UNICODE 1 -#define SCI_SETLINEENDTYPESALLOWED 2656 -#define SCI_GETLINEENDTYPESALLOWED 2657 -#define SCI_GETLINEENDTYPESACTIVE 2658 -#define SCI_SETREPRESENTATION 2665 -#define SCI_GETREPRESENTATION 2666 -#define SCI_CLEARREPRESENTATION 2667 -#define SCI_STARTRECORD 3001 -#define SCI_STOPRECORD 3002 -#define SCI_SETLEXER 4001 -#define SCI_GETLEXER 4002 -#define SCI_COLOURISE 4003 -#define SCI_SETPROPERTY 4004 -#define KEYWORDSET_MAX 8 -#define SCI_SETKEYWORDS 4005 -#define SCI_SETLEXERLANGUAGE 4006 -#define SCI_LOADLEXERLIBRARY 4007 -#define SCI_GETPROPERTY 4008 -#define SCI_GETPROPERTYEXPANDED 4009 -#define SCI_GETPROPERTYINT 4010 -#define SCI_GETSTYLEBITSNEEDED 4011 -#define SCI_GETLEXERLANGUAGE 4012 -#define SCI_PRIVATELEXERCALL 4013 -#define SCI_PROPERTYNAMES 4014 -#define SC_TYPE_BOOLEAN 0 -#define SC_TYPE_INTEGER 1 -#define SC_TYPE_STRING 2 -#define SCI_PROPERTYTYPE 4015 -#define SCI_DESCRIBEPROPERTY 4016 -#define SCI_DESCRIBEKEYWORDSETS 4017 -#define SCI_GETLINEENDTYPESSUPPORTED 4018 -#define SCI_ALLOCATESUBSTYLES 4020 -#define SCI_GETSUBSTYLESSTART 4021 -#define SCI_GETSUBSTYLESLENGTH 4022 -#define SCI_GETSTYLEFROMSUBSTYLE 4027 -#define SCI_GETPRIMARYSTYLEFROMSTYLE 4028 -#define SCI_FREESUBSTYLES 4023 -#define SCI_SETIDENTIFIERS 4024 -#define SCI_DISTANCETOSECONDARYSTYLES 4025 -#define SCI_GETSUBSTYLEBASES 4026 -#define SC_MOD_INSERTTEXT 0x1 -#define SC_MOD_DELETETEXT 0x2 -#define SC_MOD_CHANGESTYLE 0x4 -#define SC_MOD_CHANGEFOLD 0x8 -#define SC_PERFORMED_USER 0x10 -#define SC_PERFORMED_UNDO 0x20 -#define SC_PERFORMED_REDO 0x40 -#define SC_MULTISTEPUNDOREDO 0x80 -#define SC_LASTSTEPINUNDOREDO 0x100 -#define SC_MOD_CHANGEMARKER 0x200 -#define SC_MOD_BEFOREINSERT 0x400 -#define SC_MOD_BEFOREDELETE 0x800 -#define SC_MULTILINEUNDOREDO 0x1000 -#define SC_STARTACTION 0x2000 -#define SC_MOD_CHANGEINDICATOR 0x4000 -#define SC_MOD_CHANGELINESTATE 0x8000 -#define SC_MOD_CHANGEMARGIN 0x10000 -#define SC_MOD_CHANGEANNOTATION 0x20000 -#define SC_MOD_CONTAINER 0x40000 -#define SC_MOD_LEXERSTATE 0x80000 -#define SC_MOD_INSERTCHECK 0x100000 -#define SC_MOD_CHANGETABSTOPS 0x200000 -#define SC_MODEVENTMASKALL 0x3FFFFF -#define SC_UPDATE_CONTENT 0x1 -#define SC_UPDATE_SELECTION 0x2 -#define SC_UPDATE_V_SCROLL 0x4 -#define SC_UPDATE_H_SCROLL 0x8 -#define SCEN_CHANGE 768 -#define SCEN_SETFOCUS 512 -#define SCEN_KILLFOCUS 256 -#define SCK_DOWN 300 -#define SCK_UP 301 -#define SCK_LEFT 302 -#define SCK_RIGHT 303 -#define SCK_HOME 304 -#define SCK_END 305 -#define SCK_PRIOR 306 -#define SCK_NEXT 307 -#define SCK_DELETE 308 -#define SCK_INSERT 309 -#define SCK_ESCAPE 7 -#define SCK_BACK 8 -#define SCK_TAB 9 -#define SCK_RETURN 13 -#define SCK_ADD 310 -#define SCK_SUBTRACT 311 -#define SCK_DIVIDE 312 -#define SCK_WIN 313 -#define SCK_RWIN 314 -#define SCK_MENU 315 -#define SCMOD_NORM 0 -#define SCMOD_SHIFT 1 -#define SCMOD_CTRL 2 -#define SCMOD_ALT 4 -#define SCMOD_SUPER 8 -#define SCMOD_META 16 -#define SC_AC_FILLUP 1 -#define SC_AC_DOUBLECLICK 2 -#define SC_AC_TAB 3 -#define SC_AC_NEWLINE 4 -#define SC_AC_COMMAND 5 -#define SCN_STYLENEEDED 2000 -#define SCN_CHARADDED 2001 -#define SCN_SAVEPOINTREACHED 2002 -#define SCN_SAVEPOINTLEFT 2003 -#define SCN_MODIFYATTEMPTRO 2004 -#define SCN_KEY 2005 -#define SCN_DOUBLECLICK 2006 -#define SCN_UPDATEUI 2007 -#define SCN_MODIFIED 2008 -#define SCN_MACRORECORD 2009 -#define SCN_MARGINCLICK 2010 -#define SCN_NEEDSHOWN 2011 -#define SCN_PAINTED 2013 -#define SCN_USERLISTSELECTION 2014 -#define SCN_URIDROPPED 2015 -#define SCN_DWELLSTART 2016 -#define SCN_DWELLEND 2017 -#define SCN_ZOOM 2018 -#define SCN_HOTSPOTCLICK 2019 -#define SCN_HOTSPOTDOUBLECLICK 2020 -#define SCN_CALLTIPCLICK 2021 -#define SCN_AUTOCSELECTION 2022 -#define SCN_INDICATORCLICK 2023 -#define SCN_INDICATORRELEASE 2024 -#define SCN_AUTOCCANCELLED 2025 -#define SCN_AUTOCCHARDELETED 2026 -#define SCN_HOTSPOTRELEASECLICK 2027 -#define SCN_FOCUSIN 2028 -#define SCN_FOCUSOUT 2029 -#define SCN_AUTOCCOMPLETED 2030 -#define SCN_MARGINRIGHTCLICK 2031 -/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ - -/* These structures are defined to be exactly the same shape as the Win32 - * CHARRANGE, TEXTRANGE, FINDTEXTEX, FORMATRANGE, and NMHDR structs. - * So older code that treats Scintilla as a RichEdit will work. */ - -struct Sci_CharacterRange { - Sci_PositionCR cpMin; - Sci_PositionCR cpMax; -}; - -struct Sci_TextRange { - struct Sci_CharacterRange chrg; - char *lpstrText; -}; - -struct Sci_TextToFind { - struct Sci_CharacterRange chrg; - const char *lpstrText; - struct Sci_CharacterRange chrgText; -}; - -typedef void *Sci_SurfaceID; - -struct Sci_Rectangle { - int left; - int top; - int right; - int bottom; -}; - -/* This structure is used in printing and requires some of the graphics types - * from Platform.h. Not needed by most client code. */ - -struct Sci_RangeToFormat { - Sci_SurfaceID hdc; - Sci_SurfaceID hdcTarget; - struct Sci_Rectangle rc; - struct Sci_Rectangle rcPage; - struct Sci_CharacterRange chrg; -}; - -#ifndef __cplusplus -/* For the GTK+ platform, g-ir-scanner needs to have these typedefs. This - * is not required in C++ code and actually seems to break ScintillaEditPy */ -typedef struct Sci_NotifyHeader Sci_NotifyHeader; -typedef struct SCNotification SCNotification; -#endif - -struct Sci_NotifyHeader { - /* Compatible with Windows NMHDR. - * hwndFrom is really an environment specific window handle or pointer - * but most clients of Scintilla.h do not have this type visible. */ - void *hwndFrom; - uptr_t idFrom; - unsigned int code; -}; - -struct SCNotification { - Sci_NotifyHeader nmhdr; - Sci_Position position; - /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */ - /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */ - /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */ - /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ - /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */ - - int ch; - /* SCN_CHARADDED, SCN_KEY, SCN_AUTOCCOMPLETED, SCN_AUTOCSELECTION, */ - /* SCN_USERLISTSELECTION */ - int modifiers; - /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */ - /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */ - - int modificationType; /* SCN_MODIFIED */ - const char *text; - /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */ - - Sci_Position length; /* SCN_MODIFIED */ - Sci_Position linesAdded; /* SCN_MODIFIED */ - int message; /* SCN_MACRORECORD */ - uptr_t wParam; /* SCN_MACRORECORD */ - sptr_t lParam; /* SCN_MACRORECORD */ - Sci_Position line; /* SCN_MODIFIED */ - int foldLevelNow; /* SCN_MODIFIED */ - int foldLevelPrev; /* SCN_MODIFIED */ - int margin; /* SCN_MARGINCLICK */ - int listType; /* SCN_USERLISTSELECTION */ - int x; /* SCN_DWELLSTART, SCN_DWELLEND */ - int y; /* SCN_DWELLSTART, SCN_DWELLEND */ - int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */ - Sci_Position annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */ - int updated; /* SCN_UPDATEUI */ - int listCompletionMethod; - /* SCN_AUTOCSELECTION, SCN_AUTOCCOMPLETED, SCN_USERLISTSELECTION, */ -}; - -#ifdef INCLUDE_DEPRECATED_FEATURES - -#define SCI_SETKEYSUNICODE 2521 -#define SCI_GETKEYSUNICODE 2522 - -#define CharacterRange Sci_CharacterRange -#define TextRange Sci_TextRange -#define TextToFind Sci_TextToFind -#define RangeToFormat Sci_RangeToFormat -#define NotifyHeader Sci_NotifyHeader - -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/include/ScintillaWidget.h b/qrenderdoc/3rdparty/scintilla/include/ScintillaWidget.h deleted file mode 100644 index 1721f65d9..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/ScintillaWidget.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Scintilla source code edit control */ -/* @file ScintillaWidget.h - * Definition of Scintilla widget for GTK+. - * Only needed by GTK+ code but is harmless on other platforms. - * This comment is not a doc-comment as that causes warnings from g-ir-scanner. - */ -/* Copyright 1998-2001 by Neil Hodgson - * The License.txt file describes the conditions under which this software may be distributed. */ - -#ifndef SCINTILLAWIDGET_H -#define SCINTILLAWIDGET_H - -#if defined(GTK) - -#ifdef __cplusplus -extern "C" { -#endif - -#define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject) -#define SCINTILLA_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass) -#define IS_SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, scintilla_get_type ()) - -#define SCINTILLA_TYPE_OBJECT (scintilla_object_get_type()) -#define SCINTILLA_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SCINTILLA_TYPE_OBJECT, ScintillaObject)) -#define SCINTILLA_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SCINTILLA_TYPE_OBJECT)) -#define SCINTILLA_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SCINTILLA_TYPE_OBJECT, ScintillaObjectClass)) -#define SCINTILLA_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SCINTILLA_TYPE_OBJECT)) -#define SCINTILLA_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), SCINTILLA_TYPE_OBJECT, ScintillaObjectClass)) - -typedef struct _ScintillaObject ScintillaObject; -typedef struct _ScintillaClass ScintillaObjectClass; - -struct _ScintillaObject { - GtkContainer cont; - void *pscin; -}; - -struct _ScintillaClass { - GtkContainerClass parent_class; - - void (* command) (ScintillaObject *sci, int cmd, GtkWidget *window); - void (* notify) (ScintillaObject *sci, int id, SCNotification *scn); -}; - -GType scintilla_object_get_type (void); -GtkWidget* scintilla_object_new (void); -gintptr scintilla_object_send_message (ScintillaObject *sci, unsigned int iMessage, guintptr wParam, gintptr lParam); - - -GType scnotification_get_type (void); -#define SCINTILLA_TYPE_NOTIFICATION (scnotification_get_type()) - -#ifndef G_IR_SCANNING -/* The legacy names confuse the g-ir-scanner program */ -typedef struct _ScintillaClass ScintillaClass; - -GType scintilla_get_type (void); -GtkWidget* scintilla_new (void); -void scintilla_set_id (ScintillaObject *sci, uptr_t id); -sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam); -void scintilla_release_resources(void); -#endif - -#define SCINTILLA_NOTIFY "sci-notify" - -#ifdef __cplusplus -} -#endif - -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaDocument.h b/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaDocument.h deleted file mode 100644 index 510127f94..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaDocument.h +++ /dev/null @@ -1,109 +0,0 @@ -// ScintillaDocument.h -// Wrapper for Scintilla document object so it can be manipulated independently. -// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware - -#ifndef SCINTILLADOCUMENT_H -#define SCINTILLADOCUMENT_H - -#include - -class WatcherHelper; - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#ifndef EXPORT_IMPORT_API -#ifdef WIN32 -#ifdef MAKING_LIBRARY -#define EXPORT_IMPORT_API __declspec(dllexport) -#else -// Defining dllimport upsets moc -#define EXPORT_IMPORT_API __declspec(dllimport) -//#define EXPORT_IMPORT_API -#endif -#else -#define EXPORT_IMPORT_API -#endif -#endif - -class EXPORT_IMPORT_API ScintillaDocument : public QObject -{ - Q_OBJECT - - void *pdoc; - WatcherHelper *docWatcher; - -public: - explicit ScintillaDocument(QObject *parent = 0, void *pdoc_=0); - virtual ~ScintillaDocument(); - void *pointer(); - - int line_from_position(int pos); - bool is_cr_lf(int pos); - bool delete_chars(int pos, int len); - int undo(); - int redo(); - bool can_undo(); - bool can_redo(); - void delete_undo_history(); - bool set_undo_collection(bool collect_undo); - bool is_collecting_undo(); - void begin_undo_action(); - void end_undo_action(); - void set_save_point(); - bool is_save_point(); - void set_read_only(bool read_only); - bool is_read_only(); - void insert_string(int position, QByteArray &str); - QByteArray get_char_range(int position, int length); - char style_at(int position); - int line_start(int lineno); - int line_end(int lineno); - int line_end_position(int pos); - int length(); - int lines_total(); - void start_styling(int position, char flags); - bool set_style_for(int length, char style); - int get_end_styled(); - void ensure_styled_to(int position); - void set_current_indicator(int indic); - void decoration_fill_range(int position, int value, int fillLength); - int decorations_value_at(int indic, int position); - int decorations_start(int indic, int position); - int decorations_end(int indic, int position); - int get_code_page(); - void set_code_page(int code_page); - int get_eol_mode(); - void set_eol_mode(int eol_mode); - int move_position_outside_char(int pos, int move_dir, bool check_line_end); - - int get_character(int pos); // Calls GetCharacterAndWidth(pos, NULL) - -private: - void emit_modify_attempt(); - void emit_save_point(bool atSavePoint); - void emit_modified(int position, int modification_type, const QByteArray& text, int length, - int linesAdded, int line, int foldLevelNow, int foldLevelPrev); - void emit_style_needed(int pos); - void emit_lexer_changed(); - void emit_error_occurred(int status); - -signals: - void modify_attempt(); - void save_point(bool atSavePoint); - void modified(int position, int modification_type, const QByteArray& text, int length, - int linesAdded, int line, int foldLevelNow, int foldLevelPrev); - void style_needed(int pos); - void lexer_changed(); - void error_occurred(int status); - - friend class ::WatcherHelper; - -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif // SCINTILLADOCUMENT_H diff --git a/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEdit.h b/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEdit.h deleted file mode 100644 index 56d2cfe46..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEdit.h +++ /dev/null @@ -1,766 +0,0 @@ -// ScintillaEdit.h -// Extended version of ScintillaEditBase with a method for each API -// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware - -#ifndef SCINTILLAEDIT_H -#define SCINTILLAEDIT_H - -#include - -#include "ScintillaEditBase.h" -#include "ScintillaDocument.h" - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#ifndef EXPORT_IMPORT_API -#ifdef WIN32 -#ifdef MAKING_LIBRARY -#define EXPORT_IMPORT_API __declspec(dllexport) -#else -// Defining dllimport upsets moc -#define EXPORT_IMPORT_API __declspec(dllimport) -//#define EXPORT_IMPORT_API -#endif -#else -#define EXPORT_IMPORT_API -#endif -#endif - -class EXPORT_IMPORT_API ScintillaEdit : public ScintillaEditBase { - Q_OBJECT - -public: - ScintillaEdit(QWidget *parent = 0); - virtual ~ScintillaEdit(); - - QByteArray TextReturner(int message, uptr_t wParam) const; - - QPairfind_text(int flags, const char *text, int cpMin, int cpMax); - QByteArray get_text_range(int start, int end); - ScintillaDocument *get_doc(); - void set_doc(ScintillaDocument *pdoc_); - - // Same as previous two methods but with Qt style names - QPairfindText(int flags, const char *text, int cpMin, int cpMax) { - return find_text(flags, text, cpMin, cpMax); - } - - QByteArray textRange(int start, int end) { - return get_text_range(start, end); - } - - // Exposing the FORMATRANGE api with both underscore & qt style names - long format_range(bool draw, QPaintDevice* target, QPaintDevice* measure, - const QRect& print_rect, const QRect& page_rect, - long range_start, long range_end); - long formatRange(bool draw, QPaintDevice* target, QPaintDevice* measure, - const QRect& print_rect, const QRect& page_rect, - long range_start, long range_end) { - return format_range(draw, target, measure, print_rect, page_rect, - range_start, range_end); - } - -/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ - void addText(sptr_t length, const char * text); - void addStyledText(sptr_t length, const char * c); - void insertText(sptr_t pos, const char * text); - void changeInsertion(sptr_t length, const char * text); - void clearAll(); - void deleteRange(sptr_t start, sptr_t lengthDelete); - void clearDocumentStyle(); - sptr_t length() const; - sptr_t charAt(sptr_t pos) const; - sptr_t currentPos() const; - sptr_t anchor() const; - sptr_t styleAt(sptr_t pos) const; - void redo(); - void setUndoCollection(bool collectUndo); - void selectAll(); - void setSavePoint(); - bool canRedo(); - sptr_t markerLineFromHandle(sptr_t markerHandle); - void markerDeleteHandle(sptr_t markerHandle); - bool undoCollection() const; - sptr_t viewWS() const; - void setViewWS(sptr_t viewWS); - sptr_t tabDrawMode() const; - void setTabDrawMode(sptr_t tabDrawMode); - sptr_t positionFromPoint(sptr_t x, sptr_t y); - sptr_t positionFromPointClose(sptr_t x, sptr_t y); - void gotoLine(sptr_t line); - void gotoPos(sptr_t caret); - void setAnchor(sptr_t anchor); - QByteArray getCurLine(sptr_t length); - sptr_t endStyled() const; - void convertEOLs(sptr_t eolMode); - sptr_t eOLMode() const; - void setEOLMode(sptr_t eolMode); - void startStyling(sptr_t start, sptr_t unused); - void setStyling(sptr_t length, sptr_t style); - bool bufferedDraw() const; - void setBufferedDraw(bool buffered); - void setTabWidth(sptr_t tabWidth); - sptr_t tabWidth() const; - void clearTabStops(sptr_t line); - void addTabStop(sptr_t line, sptr_t x); - sptr_t getNextTabStop(sptr_t line, sptr_t x); - void setCodePage(sptr_t codePage); - sptr_t iMEInteraction() const; - void setIMEInteraction(sptr_t imeInteraction); - void markerDefine(sptr_t markerNumber, sptr_t markerSymbol); - void markerSetFore(sptr_t markerNumber, sptr_t fore); - void markerSetBack(sptr_t markerNumber, sptr_t back); - void markerSetBackSelected(sptr_t markerNumber, sptr_t back); - void markerEnableHighlight(bool enabled); - sptr_t markerAdd(sptr_t line, sptr_t markerNumber); - void markerDelete(sptr_t line, sptr_t markerNumber); - void markerDeleteAll(sptr_t markerNumber); - sptr_t markerGet(sptr_t line); - sptr_t markerNext(sptr_t lineStart, sptr_t markerMask); - sptr_t markerPrevious(sptr_t lineStart, sptr_t markerMask); - void markerDefinePixmap(sptr_t markerNumber, const char * pixmap); - void markerAddSet(sptr_t line, sptr_t markerSet); - void markerSetAlpha(sptr_t markerNumber, sptr_t alpha); - void setMarginTypeN(sptr_t margin, sptr_t marginType); - sptr_t marginTypeN(sptr_t margin) const; - void setMarginWidthN(sptr_t margin, sptr_t pixelWidth); - sptr_t marginWidthN(sptr_t margin) const; - void setMarginMaskN(sptr_t margin, sptr_t mask); - sptr_t marginMaskN(sptr_t margin) const; - void setMarginSensitiveN(sptr_t margin, bool sensitive); - bool marginSensitiveN(sptr_t margin) const; - void setMarginCursorN(sptr_t margin, sptr_t cursor); - sptr_t marginCursorN(sptr_t margin) const; - void setMarginBackN(sptr_t margin, sptr_t back); - sptr_t marginBackN(sptr_t margin) const; - void setMargins(sptr_t margins); - sptr_t margins() const; - void styleClearAll(); - void styleSetFore(sptr_t style, sptr_t fore); - void styleSetBack(sptr_t style, sptr_t back); - void styleSetBold(sptr_t style, bool bold); - void styleSetItalic(sptr_t style, bool italic); - void styleSetSize(sptr_t style, sptr_t sizePoints); - void styleSetFont(sptr_t style, const char * fontName); - void styleSetEOLFilled(sptr_t style, bool eolFilled); - void styleResetDefault(); - void styleSetUnderline(sptr_t style, bool underline); - sptr_t styleFore(sptr_t style) const; - sptr_t styleBack(sptr_t style) const; - bool styleBold(sptr_t style) const; - bool styleItalic(sptr_t style) const; - sptr_t styleSize(sptr_t style) const; - QByteArray styleFont(sptr_t style) const; - bool styleEOLFilled(sptr_t style) const; - bool styleUnderline(sptr_t style) const; - sptr_t styleCase(sptr_t style) const; - sptr_t styleCharacterSet(sptr_t style) const; - bool styleVisible(sptr_t style) const; - bool styleChangeable(sptr_t style) const; - bool styleHotSpot(sptr_t style) const; - void styleSetCase(sptr_t style, sptr_t caseVisible); - void styleSetSizeFractional(sptr_t style, sptr_t sizeHundredthPoints); - sptr_t styleSizeFractional(sptr_t style) const; - void styleSetWeight(sptr_t style, sptr_t weight); - sptr_t styleWeight(sptr_t style) const; - void styleSetCharacterSet(sptr_t style, sptr_t characterSet); - void styleSetHotSpot(sptr_t style, bool hotspot); - void setSelFore(bool useSetting, sptr_t fore); - void setSelBack(bool useSetting, sptr_t back); - sptr_t selAlpha() const; - void setSelAlpha(sptr_t alpha); - bool selEOLFilled() const; - void setSelEOLFilled(bool filled); - void setCaretFore(sptr_t fore); - void assignCmdKey(sptr_t keyDefinition, sptr_t sciCommand); - void clearCmdKey(sptr_t keyDefinition); - void clearAllCmdKeys(); - void setStylingEx(sptr_t length, const char * styles); - void styleSetVisible(sptr_t style, bool visible); - sptr_t caretPeriod() const; - void setCaretPeriod(sptr_t periodMilliseconds); - void setWordChars(const char * characters); - QByteArray wordChars() const; - void beginUndoAction(); - void endUndoAction(); - void indicSetStyle(sptr_t indicator, sptr_t indicatorStyle); - sptr_t indicStyle(sptr_t indicator) const; - void indicSetFore(sptr_t indicator, sptr_t fore); - sptr_t indicFore(sptr_t indicator) const; - void indicSetUnder(sptr_t indicator, bool under); - bool indicUnder(sptr_t indicator) const; - void indicSetHoverStyle(sptr_t indicator, sptr_t indicatorStyle); - sptr_t indicHoverStyle(sptr_t indicator) const; - void indicSetHoverFore(sptr_t indicator, sptr_t fore); - sptr_t indicHoverFore(sptr_t indicator) const; - void indicSetFlags(sptr_t indicator, sptr_t flags); - sptr_t indicFlags(sptr_t indicator) const; - void setWhitespaceFore(bool useSetting, sptr_t fore); - void setWhitespaceBack(bool useSetting, sptr_t back); - void setWhitespaceSize(sptr_t size); - sptr_t whitespaceSize() const; - void setStyleBits(sptr_t bits); - sptr_t styleBits() const; - void setLineState(sptr_t line, sptr_t state); - sptr_t lineState(sptr_t line) const; - sptr_t maxLineState() const; - bool caretLineVisible() const; - void setCaretLineVisible(bool show); - sptr_t caretLineBack() const; - void setCaretLineBack(sptr_t back); - void styleSetChangeable(sptr_t style, bool changeable); - void autoCShow(sptr_t lengthEntered, const char * itemList); - void autoCCancel(); - bool autoCActive(); - sptr_t autoCPosStart(); - void autoCComplete(); - void autoCStops(const char * characterSet); - void autoCSetSeparator(sptr_t separatorCharacter); - sptr_t autoCSeparator() const; - void autoCSelect(const char * select); - void autoCSetCancelAtStart(bool cancel); - bool autoCCancelAtStart() const; - void autoCSetFillUps(const char * characterSet); - void autoCSetChooseSingle(bool chooseSingle); - bool autoCChooseSingle() const; - void autoCSetIgnoreCase(bool ignoreCase); - bool autoCIgnoreCase() const; - void userListShow(sptr_t listType, const char * itemList); - void autoCSetAutoHide(bool autoHide); - bool autoCAutoHide() const; - void autoCSetDropRestOfWord(bool dropRestOfWord); - bool autoCDropRestOfWord() const; - void registerImage(sptr_t type, const char * xpmData); - void clearRegisteredImages(); - sptr_t autoCTypeSeparator() const; - void autoCSetTypeSeparator(sptr_t separatorCharacter); - void autoCSetMaxWidth(sptr_t characterCount); - sptr_t autoCMaxWidth() const; - void autoCSetMaxHeight(sptr_t rowCount); - sptr_t autoCMaxHeight() const; - void setIndent(sptr_t indentSize); - sptr_t indent() const; - void setUseTabs(bool useTabs); - bool useTabs() const; - void setLineIndentation(sptr_t line, sptr_t indentation); - sptr_t lineIndentation(sptr_t line) const; - sptr_t lineIndentPosition(sptr_t line) const; - sptr_t column(sptr_t pos) const; - sptr_t countCharacters(sptr_t start, sptr_t end); - void setHScrollBar(bool visible); - bool hScrollBar() const; - void setIndentationGuides(sptr_t indentView); - sptr_t indentationGuides() const; - void setHighlightGuide(sptr_t column); - sptr_t highlightGuide() const; - sptr_t lineEndPosition(sptr_t line) const; - sptr_t codePage() const; - sptr_t caretFore() const; - bool readOnly() const; - void setCurrentPos(sptr_t caret); - void setSelectionStart(sptr_t anchor); - sptr_t selectionStart() const; - void setSelectionEnd(sptr_t caret); - sptr_t selectionEnd() const; - void setEmptySelection(sptr_t caret); - void setPrintMagnification(sptr_t magnification); - sptr_t printMagnification() const; - void setPrintColourMode(sptr_t mode); - sptr_t printColourMode() const; - sptr_t firstVisibleLine() const; - QByteArray getLine(sptr_t line); - sptr_t lineCount() const; - void setMarginLeft(sptr_t pixelWidth); - sptr_t marginLeft() const; - void setMarginRight(sptr_t pixelWidth); - sptr_t marginRight() const; - bool modify() const; - void setSel(sptr_t anchor, sptr_t caret); - QByteArray getSelText(); - void hideSelection(bool hide); - sptr_t pointXFromPosition(sptr_t pos); - sptr_t pointYFromPosition(sptr_t pos); - sptr_t lineFromPosition(sptr_t pos); - sptr_t positionFromLine(sptr_t line); - void lineScroll(sptr_t columns, sptr_t lines); - void scrollCaret(); - void scrollRange(sptr_t secondary, sptr_t primary); - void replaceSel(const char * text); - void setReadOnly(bool readOnly); - void null(); - bool canPaste(); - bool canUndo(); - void emptyUndoBuffer(); - void undo(); - void cut(); - void copy(); - void paste(); - void clear(); - void setText(const char * text); - QByteArray getText(sptr_t length); - sptr_t textLength() const; - sptr_t directFunction() const; - sptr_t directPointer() const; - void setOvertype(bool overType); - bool overtype() const; - void setCaretWidth(sptr_t pixelWidth); - sptr_t caretWidth() const; - void setTargetStart(sptr_t start); - sptr_t targetStart() const; - void setTargetEnd(sptr_t end); - sptr_t targetEnd() const; - void setTargetRange(sptr_t start, sptr_t end); - QByteArray targetText() const; - void targetFromSelection(); - void targetWholeDocument(); - sptr_t replaceTarget(sptr_t length, const char * text); - sptr_t replaceTargetRE(sptr_t length, const char * text); - sptr_t searchInTarget(sptr_t length, const char * text); - void setSearchFlags(sptr_t searchFlags); - sptr_t searchFlags() const; - void callTipShow(sptr_t pos, const char * definition); - void callTipCancel(); - bool callTipActive(); - sptr_t callTipPosStart(); - void callTipSetPosStart(sptr_t posStart); - void callTipSetHlt(sptr_t highlightStart, sptr_t highlightEnd); - void callTipSetBack(sptr_t back); - void callTipSetFore(sptr_t fore); - void callTipSetForeHlt(sptr_t fore); - void callTipUseStyle(sptr_t tabSize); - void callTipSetPosition(bool above); - sptr_t visibleFromDocLine(sptr_t docLine); - sptr_t docLineFromVisible(sptr_t displayLine); - sptr_t wrapCount(sptr_t docLine); - void setFoldLevel(sptr_t line, sptr_t level); - sptr_t foldLevel(sptr_t line) const; - sptr_t lastChild(sptr_t line, sptr_t level) const; - sptr_t foldParent(sptr_t line) const; - void showLines(sptr_t lineStart, sptr_t lineEnd); - void hideLines(sptr_t lineStart, sptr_t lineEnd); - bool lineVisible(sptr_t line) const; - bool allLinesVisible() const; - void setFoldExpanded(sptr_t line, bool expanded); - bool foldExpanded(sptr_t line) const; - void toggleFold(sptr_t line); - void toggleFoldShowText(sptr_t line, const char * text); - void foldDisplayTextSetStyle(sptr_t style); - void foldLine(sptr_t line, sptr_t action); - void foldChildren(sptr_t line, sptr_t action); - void expandChildren(sptr_t line, sptr_t level); - void foldAll(sptr_t action); - void ensureVisible(sptr_t line); - void setAutomaticFold(sptr_t automaticFold); - sptr_t automaticFold() const; - void setFoldFlags(sptr_t flags); - void ensureVisibleEnforcePolicy(sptr_t line); - void setTabIndents(bool tabIndents); - bool tabIndents() const; - void setBackSpaceUnIndents(bool bsUnIndents); - bool backSpaceUnIndents() const; - void setMouseDwellTime(sptr_t periodMilliseconds); - sptr_t mouseDwellTime() const; - sptr_t wordStartPosition(sptr_t pos, bool onlyWordCharacters); - sptr_t wordEndPosition(sptr_t pos, bool onlyWordCharacters); - bool isRangeWord(sptr_t start, sptr_t end); - void setIdleStyling(sptr_t idleStyling); - sptr_t idleStyling() const; - void setWrapMode(sptr_t wrapMode); - sptr_t wrapMode() const; - void setWrapVisualFlags(sptr_t wrapVisualFlags); - sptr_t wrapVisualFlags() const; - void setWrapVisualFlagsLocation(sptr_t wrapVisualFlagsLocation); - sptr_t wrapVisualFlagsLocation() const; - void setWrapStartIndent(sptr_t indent); - sptr_t wrapStartIndent() const; - void setWrapIndentMode(sptr_t wrapIndentMode); - sptr_t wrapIndentMode() const; - void setLayoutCache(sptr_t cacheMode); - sptr_t layoutCache() const; - void setScrollWidth(sptr_t pixelWidth); - sptr_t scrollWidth() const; - void setScrollWidthTracking(bool tracking); - bool scrollWidthTracking() const; - sptr_t textWidth(sptr_t style, const char * text); - void setEndAtLastLine(bool endAtLastLine); - bool endAtLastLine() const; - sptr_t textHeight(sptr_t line); - void setVScrollBar(bool visible); - bool vScrollBar() const; - void appendText(sptr_t length, const char * text); - bool twoPhaseDraw() const; - void setTwoPhaseDraw(bool twoPhase); - sptr_t phasesDraw() const; - void setPhasesDraw(sptr_t phases); - void setFontQuality(sptr_t fontQuality); - sptr_t fontQuality() const; - void setFirstVisibleLine(sptr_t displayLine); - void setMultiPaste(sptr_t multiPaste); - sptr_t multiPaste() const; - QByteArray tag(sptr_t tagNumber) const; - void linesJoin(); - void linesSplit(sptr_t pixelWidth); - void setFoldMarginColour(bool useSetting, sptr_t back); - void setFoldMarginHiColour(bool useSetting, sptr_t fore); - void lineDown(); - void lineDownExtend(); - void lineUp(); - void lineUpExtend(); - void charLeft(); - void charLeftExtend(); - void charRight(); - void charRightExtend(); - void wordLeft(); - void wordLeftExtend(); - void wordRight(); - void wordRightExtend(); - void home(); - void homeExtend(); - void lineEnd(); - void lineEndExtend(); - void documentStart(); - void documentStartExtend(); - void documentEnd(); - void documentEndExtend(); - void pageUp(); - void pageUpExtend(); - void pageDown(); - void pageDownExtend(); - void editToggleOvertype(); - void cancel(); - void deleteBack(); - void tab(); - void backTab(); - void newLine(); - void formFeed(); - void vCHome(); - void vCHomeExtend(); - void zoomIn(); - void zoomOut(); - void delWordLeft(); - void delWordRight(); - void delWordRightEnd(); - void lineCut(); - void lineDelete(); - void lineTranspose(); - void lineDuplicate(); - void lowerCase(); - void upperCase(); - void lineScrollDown(); - void lineScrollUp(); - void deleteBackNotLine(); - void homeDisplay(); - void homeDisplayExtend(); - void lineEndDisplay(); - void lineEndDisplayExtend(); - void homeWrap(); - void homeWrapExtend(); - void lineEndWrap(); - void lineEndWrapExtend(); - void vCHomeWrap(); - void vCHomeWrapExtend(); - void lineCopy(); - void moveCaretInsideView(); - sptr_t lineLength(sptr_t line); - void braceHighlight(sptr_t posA, sptr_t posB); - void braceHighlightIndicator(bool useSetting, sptr_t indicator); - void braceBadLight(sptr_t pos); - void braceBadLightIndicator(bool useSetting, sptr_t indicator); - sptr_t braceMatch(sptr_t pos, sptr_t maxReStyle); - bool viewEOL() const; - void setViewEOL(bool visible); - sptr_t docPointer() const; - void setDocPointer(sptr_t doc); - void setModEventMask(sptr_t eventMask); - sptr_t edgeColumn() const; - void setEdgeColumn(sptr_t column); - sptr_t edgeMode() const; - void setEdgeMode(sptr_t edgeMode); - sptr_t edgeColour() const; - void setEdgeColour(sptr_t edgeColour); - void multiEdgeAddLine(sptr_t column, sptr_t edgeColour); - void multiEdgeClearAll(); - void searchAnchor(); - sptr_t searchNext(sptr_t searchFlags, const char * text); - sptr_t searchPrev(sptr_t searchFlags, const char * text); - sptr_t linesOnScreen() const; - void usePopUp(sptr_t popUpMode); - bool selectionIsRectangle() const; - void setZoom(sptr_t zoomInPoints); - sptr_t zoom() const; - sptr_t createDocument(); - void addRefDocument(sptr_t doc); - void releaseDocument(sptr_t doc); - sptr_t modEventMask() const; - void setFocus(bool focus); - bool focus() const; - void setStatus(sptr_t status); - sptr_t status() const; - void setMouseDownCaptures(bool captures); - bool mouseDownCaptures() const; - void setMouseWheelCaptures(bool captures); - bool mouseWheelCaptures() const; - void setCursor(sptr_t cursorType); - sptr_t cursor() const; - void setControlCharSymbol(sptr_t symbol); - sptr_t controlCharSymbol() const; - void wordPartLeft(); - void wordPartLeftExtend(); - void wordPartRight(); - void wordPartRightExtend(); - void setVisiblePolicy(sptr_t visiblePolicy, sptr_t visibleSlop); - void delLineLeft(); - void delLineRight(); - void setXOffset(sptr_t xOffset); - sptr_t xOffset() const; - void chooseCaretX(); - void grabFocus(); - void setXCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop); - void setYCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop); - void setPrintWrapMode(sptr_t wrapMode); - sptr_t printWrapMode() const; - void setHotspotActiveFore(bool useSetting, sptr_t fore); - sptr_t hotspotActiveFore() const; - void setHotspotActiveBack(bool useSetting, sptr_t back); - sptr_t hotspotActiveBack() const; - void setHotspotActiveUnderline(bool underline); - bool hotspotActiveUnderline() const; - void setHotspotSingleLine(bool singleLine); - bool hotspotSingleLine() const; - void paraDown(); - void paraDownExtend(); - void paraUp(); - void paraUpExtend(); - sptr_t positionBefore(sptr_t pos); - sptr_t positionAfter(sptr_t pos); - sptr_t positionRelative(sptr_t pos, sptr_t relative); - void copyRange(sptr_t start, sptr_t end); - void copyText(sptr_t length, const char * text); - void setSelectionMode(sptr_t selectionMode); - sptr_t selectionMode() const; - sptr_t getLineSelStartPosition(sptr_t line); - sptr_t getLineSelEndPosition(sptr_t line); - void lineDownRectExtend(); - void lineUpRectExtend(); - void charLeftRectExtend(); - void charRightRectExtend(); - void homeRectExtend(); - void vCHomeRectExtend(); - void lineEndRectExtend(); - void pageUpRectExtend(); - void pageDownRectExtend(); - void stutteredPageUp(); - void stutteredPageUpExtend(); - void stutteredPageDown(); - void stutteredPageDownExtend(); - void wordLeftEnd(); - void wordLeftEndExtend(); - void wordRightEnd(); - void wordRightEndExtend(); - void setWhitespaceChars(const char * characters); - QByteArray whitespaceChars() const; - void setPunctuationChars(const char * characters); - QByteArray punctuationChars() const; - void setCharsDefault(); - sptr_t autoCCurrent() const; - QByteArray autoCCurrentText() const; - void autoCSetCaseInsensitiveBehaviour(sptr_t behaviour); - sptr_t autoCCaseInsensitiveBehaviour() const; - void autoCSetMulti(sptr_t multi); - sptr_t autoCMulti() const; - void autoCSetOrder(sptr_t order); - sptr_t autoCOrder() const; - void allocate(sptr_t bytes); - QByteArray targetAsUTF8(); - void setLengthForEncode(sptr_t bytes); - QByteArray encodedFromUTF8(const char * utf8); - sptr_t findColumn(sptr_t line, sptr_t column); - sptr_t caretSticky() const; - void setCaretSticky(sptr_t useCaretStickyBehaviour); - void toggleCaretSticky(); - void setPasteConvertEndings(bool convert); - bool pasteConvertEndings() const; - void selectionDuplicate(); - void setCaretLineBackAlpha(sptr_t alpha); - sptr_t caretLineBackAlpha() const; - void setCaretStyle(sptr_t caretStyle); - sptr_t caretStyle() const; - void setIndicatorCurrent(sptr_t indicator); - sptr_t indicatorCurrent() const; - void setIndicatorValue(sptr_t value); - sptr_t indicatorValue() const; - void indicatorFillRange(sptr_t start, sptr_t lengthFill); - void indicatorClearRange(sptr_t start, sptr_t lengthClear); - sptr_t indicatorAllOnFor(sptr_t pos); - sptr_t indicatorValueAt(sptr_t indicator, sptr_t pos); - sptr_t indicatorStart(sptr_t indicator, sptr_t pos); - sptr_t indicatorEnd(sptr_t indicator, sptr_t pos); - void setPositionCache(sptr_t size); - sptr_t positionCache() const; - void copyAllowLine(); - sptr_t characterPointer() const; - sptr_t rangePointer(sptr_t start, sptr_t lengthRange) const; - sptr_t gapPosition() const; - void indicSetAlpha(sptr_t indicator, sptr_t alpha); - sptr_t indicAlpha(sptr_t indicator) const; - void indicSetOutlineAlpha(sptr_t indicator, sptr_t alpha); - sptr_t indicOutlineAlpha(sptr_t indicator) const; - void setExtraAscent(sptr_t extraAscent); - sptr_t extraAscent() const; - void setExtraDescent(sptr_t extraDescent); - sptr_t extraDescent() const; - sptr_t markerSymbolDefined(sptr_t markerNumber); - void marginSetText(sptr_t line, const char * text); - QByteArray marginText(sptr_t line) const; - void marginSetStyle(sptr_t line, sptr_t style); - sptr_t marginStyle(sptr_t line) const; - void marginSetStyles(sptr_t line, const char * styles); - QByteArray marginStyles(sptr_t line) const; - void marginTextClearAll(); - void marginSetStyleOffset(sptr_t style); - sptr_t marginStyleOffset() const; - void setMarginOptions(sptr_t marginOptions); - sptr_t marginOptions() const; - void annotationSetText(sptr_t line, const char * text); - QByteArray annotationText(sptr_t line) const; - void annotationSetStyle(sptr_t line, sptr_t style); - sptr_t annotationStyle(sptr_t line) const; - void annotationSetStyles(sptr_t line, const char * styles); - QByteArray annotationStyles(sptr_t line) const; - sptr_t annotationLines(sptr_t line) const; - void annotationClearAll(); - void annotationSetVisible(sptr_t visible); - sptr_t annotationVisible() const; - void annotationSetStyleOffset(sptr_t style); - sptr_t annotationStyleOffset() const; - void releaseAllExtendedStyles(); - sptr_t allocateExtendedStyles(sptr_t numberStyles); - void addUndoAction(sptr_t token, sptr_t flags); - sptr_t charPositionFromPoint(sptr_t x, sptr_t y); - sptr_t charPositionFromPointClose(sptr_t x, sptr_t y); - void setMouseSelectionRectangularSwitch(bool mouseSelectionRectangularSwitch); - bool mouseSelectionRectangularSwitch() const; - void setMultipleSelection(bool multipleSelection); - bool multipleSelection() const; - void setAdditionalSelectionTyping(bool additionalSelectionTyping); - bool additionalSelectionTyping() const; - void setAdditionalCaretsBlink(bool additionalCaretsBlink); - bool additionalCaretsBlink() const; - void setAdditionalCaretsVisible(bool additionalCaretsVisible); - bool additionalCaretsVisible() const; - sptr_t selections() const; - bool selectionEmpty() const; - void clearSelections(); - sptr_t setSelection(sptr_t caret, sptr_t anchor); - sptr_t addSelection(sptr_t caret, sptr_t anchor); - void dropSelectionN(sptr_t selection); - void setMainSelection(sptr_t selection); - sptr_t mainSelection() const; - void setSelectionNCaret(sptr_t selection, sptr_t caret); - sptr_t selectionNCaret(sptr_t selection) const; - void setSelectionNAnchor(sptr_t selection, sptr_t anchor); - sptr_t selectionNAnchor(sptr_t selection) const; - void setSelectionNCaretVirtualSpace(sptr_t selection, sptr_t space); - sptr_t selectionNCaretVirtualSpace(sptr_t selection) const; - void setSelectionNAnchorVirtualSpace(sptr_t selection, sptr_t space); - sptr_t selectionNAnchorVirtualSpace(sptr_t selection) const; - void setSelectionNStart(sptr_t selection, sptr_t anchor); - sptr_t selectionNStart(sptr_t selection) const; - void setSelectionNEnd(sptr_t selection, sptr_t caret); - sptr_t selectionNEnd(sptr_t selection) const; - void setRectangularSelectionCaret(sptr_t caret); - sptr_t rectangularSelectionCaret() const; - void setRectangularSelectionAnchor(sptr_t anchor); - sptr_t rectangularSelectionAnchor() const; - void setRectangularSelectionCaretVirtualSpace(sptr_t space); - sptr_t rectangularSelectionCaretVirtualSpace() const; - void setRectangularSelectionAnchorVirtualSpace(sptr_t space); - sptr_t rectangularSelectionAnchorVirtualSpace() const; - void setVirtualSpaceOptions(sptr_t virtualSpaceOptions); - sptr_t virtualSpaceOptions() const; - void setRectangularSelectionModifier(sptr_t modifier); - sptr_t rectangularSelectionModifier() const; - void setAdditionalSelFore(sptr_t fore); - void setAdditionalSelBack(sptr_t back); - void setAdditionalSelAlpha(sptr_t alpha); - sptr_t additionalSelAlpha() const; - void setAdditionalCaretFore(sptr_t fore); - sptr_t additionalCaretFore() const; - void rotateSelection(); - void swapMainAnchorCaret(); - void multipleSelectAddNext(); - void multipleSelectAddEach(); - sptr_t changeLexerState(sptr_t start, sptr_t end); - sptr_t contractedFoldNext(sptr_t lineStart); - void verticalCentreCaret(); - void moveSelectedLinesUp(); - void moveSelectedLinesDown(); - void setIdentifier(sptr_t identifier); - sptr_t identifier() const; - void rGBAImageSetWidth(sptr_t width); - void rGBAImageSetHeight(sptr_t height); - void rGBAImageSetScale(sptr_t scalePercent); - void markerDefineRGBAImage(sptr_t markerNumber, const char * pixels); - void registerRGBAImage(sptr_t type, const char * pixels); - void scrollToStart(); - void scrollToEnd(); - void setTechnology(sptr_t technology); - sptr_t technology() const; - sptr_t createLoader(sptr_t bytes); - void findIndicatorShow(sptr_t start, sptr_t end); - void findIndicatorFlash(sptr_t start, sptr_t end); - void findIndicatorHide(); - void vCHomeDisplay(); - void vCHomeDisplayExtend(); - bool caretLineVisibleAlways() const; - void setCaretLineVisibleAlways(bool alwaysVisible); - void setLineEndTypesAllowed(sptr_t lineEndBitSet); - sptr_t lineEndTypesAllowed() const; - sptr_t lineEndTypesActive() const; - void setRepresentation(const char * encodedCharacter, const char * representation); - QByteArray representation(const char * encodedCharacter) const; - void clearRepresentation(const char * encodedCharacter); - void startRecord(); - void stopRecord(); - void setLexer(sptr_t lexer); - sptr_t lexer() const; - void colourise(sptr_t start, sptr_t end); - void setProperty(const char * key, const char * value); - void setKeyWords(sptr_t keyWordSet, const char * keyWords); - void setLexerLanguage(const char * language); - void loadLexerLibrary(const char * path); - QByteArray property(const char * key) const; - QByteArray propertyExpanded(const char * key) const; - sptr_t propertyInt(const char * key, sptr_t defaultValue) const; - sptr_t styleBitsNeeded() const; - QByteArray lexerLanguage() const; - sptr_t privateLexerCall(sptr_t operation, sptr_t pointer); - QByteArray propertyNames(); - sptr_t propertyType(const char * name); - QByteArray describeProperty(const char * name); - QByteArray describeKeyWordSets(); - sptr_t lineEndTypesSupported() const; - sptr_t allocateSubStyles(sptr_t styleBase, sptr_t numberStyles); - sptr_t subStylesStart(sptr_t styleBase) const; - sptr_t subStylesLength(sptr_t styleBase) const; - sptr_t styleFromSubStyle(sptr_t subStyle) const; - sptr_t primaryStyleFromStyle(sptr_t style) const; - void freeSubStyles(); - void setIdentifiers(sptr_t style, const char * identifiers); - sptr_t distanceToSecondaryStyles() const; - QByteArray subStyleBases() const; -/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ - -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#if defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif - -#endif /* SCINTILLAEDIT_H */ diff --git a/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEditBase.h b/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEditBase.h deleted file mode 100644 index a7ba73427..000000000 --- a/qrenderdoc/3rdparty/scintilla/include/qt/ScintillaEditBase.h +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// ScintillaWidget.h - Qt widget that wraps ScintillaQt and provides events and scrolling - - -#ifndef SCINTILLAEDITBASE_H -#define SCINTILLAEDITBASE_H - -#include "../Platform.h" -#include "../Scintilla.h" - -#include -#include -#include - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class ScintillaQt; -class SurfaceImpl; -struct SCNotification; - -#ifdef WIN32 -#ifdef MAKING_LIBRARY -#define EXPORT_IMPORT_API __declspec(dllexport) -#else -// Defining dllimport upsets moc -#define EXPORT_IMPORT_API __declspec(dllimport) -//#define EXPORT_IMPORT_API -#endif -#else -#define EXPORT_IMPORT_API -#endif - -class EXPORT_IMPORT_API ScintillaEditBase : public QAbstractScrollArea { - Q_OBJECT - -public: - explicit ScintillaEditBase(QWidget *parent = 0); - virtual ~ScintillaEditBase(); - - virtual sptr_t send( - unsigned int iMessage, - uptr_t wParam = 0, - sptr_t lParam = 0) const; - - virtual sptr_t sends( - unsigned int iMessage, - uptr_t wParam = 0, - const char *s = 0) const; - -public slots: - // Scroll events coming from GUI to be sent to Scintilla. - void scrollHorizontal(int value); - void scrollVertical(int value); - - // Emit Scintilla notifications as signals. - void notifyParent(SCNotification scn); - void event_command(uptr_t wParam, sptr_t lParam); - -signals: - void horizontalScrolled(int value); - void verticalScrolled(int value); - void horizontalRangeChanged(int max, int page); - void verticalRangeChanged(int max, int page); - void notifyChange(); - void linesAdded(int linesAdded); - - // Clients can use this hook to add additional - // formats (e.g. rich text) to the MIME data. - void aboutToCopy(QMimeData *data); - - // Scintilla Notifications - void styleNeeded(int position); - void charAdded(int ch); - void savePointChanged(bool dirty); - void modifyAttemptReadOnly(); - void key(int key); - void doubleClick(int position, int line); - void updateUi(); - void modified(int type, int position, int length, int linesAdded, - const QByteArray &text, int line, int foldNow, int foldPrev); - void macroRecord(int message, uptr_t wParam, sptr_t lParam); - void marginClicked(int position, int modifiers, int margin); - void textAreaClicked(int line, int modifiers); - void needShown(int position, int length); - void painted(); - void userListSelection(); // Wants some args. - void uriDropped(); // Wants some args. - void dwellStart(int x, int y); - void dwellEnd(int x, int y); - void zoom(int zoom); - void hotSpotClick(int position, int modifiers); - void hotSpotDoubleClick(int position, int modifiers); - void callTipClick(); - void autoCompleteSelection(int position, const QString &text); - void autoCompleteCancelled(); - - // Base notifications for compatibility with other Scintilla implementations - void notify(SCNotification *pscn); - void command(uptr_t wParam, sptr_t lParam); - - // GUI event notifications needed under Qt - void buttonPressed(QMouseEvent *event); - void buttonReleased(QMouseEvent *event); - void keyPressed(QKeyEvent *event); - void resized(); - -protected: - virtual bool event(QEvent *event); - virtual void paintEvent(QPaintEvent *event); - virtual void wheelEvent(QWheelEvent *event); - virtual void focusInEvent(QFocusEvent *event); - virtual void focusOutEvent(QFocusEvent *event); - virtual void resizeEvent(QResizeEvent *event); - virtual void keyPressEvent(QKeyEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void mouseDoubleClickEvent(QMouseEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void contextMenuEvent(QContextMenuEvent *event); - virtual void dragEnterEvent(QDragEnterEvent *event); - virtual void dragLeaveEvent(QDragLeaveEvent *event); - virtual void dragMoveEvent(QDragMoveEvent *event); - virtual void dropEvent(QDropEvent *event); - virtual void inputMethodEvent(QInputMethodEvent *event); - virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; - virtual void scrollContentsBy(int, int) {} - -private: - ScintillaQt *sqt; - - QTime time; - - int preeditPos; - QString preeditString; - - int wheelDelta; - - static bool IsHangul(const QChar qchar); - void MoveImeCarets(int offset); - void DrawImeIndicator(int indicator, int len); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif /* SCINTILLAEDITBASE_H */ diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexCPP.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexCPP.cxx deleted file mode 100644 index ec040fbf6..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexCPP.cxx +++ /dev/null @@ -1,1640 +0,0 @@ -// Scintilla source code edit control -/** @file LexCPP.cxx - ** Lexer for C++, C, Java, and JavaScript. - ** Further folding features and configuration properties added by "Udo Lechner" - **/ -// Copyright 1998-2005 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" -#include "OptionSet.h" -#include "SparseState.h" -#include "SubStyles.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -namespace { - // Use an unnamed namespace to protect the functions and classes from name conflicts - -bool IsSpaceEquiv(int state) { - return (state <= SCE_C_COMMENTDOC) || - // including SCE_C_DEFAULT, SCE_C_COMMENT, SCE_C_COMMENTLINE - (state == SCE_C_COMMENTLINEDOC) || (state == SCE_C_COMMENTDOCKEYWORD) || - (state == SCE_C_COMMENTDOCKEYWORDERROR); -} - -// Preconditions: sc.currentPos points to a character after '+' or '-'. -// The test for pos reaching 0 should be redundant, -// and is in only for safety measures. -// Limitation: this code will give the incorrect answer for code like -// a = b+++/ptn/... -// Putting a space between the '++' post-inc operator and the '+' binary op -// fixes this, and is highly recommended for readability anyway. -bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) { - Sci_Position pos = (Sci_Position) sc.currentPos; - while (--pos > 0) { - char ch = styler[pos]; - if (ch == '+' || ch == '-') { - return styler[pos - 1] == ch; - } - } - return false; -} - -bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) { - // Don't look at styles, so no need to flush. - Sci_Position pos = (Sci_Position) sc.currentPos; - Sci_Position currentLine = styler.GetLine(pos); - Sci_Position lineStartPos = styler.LineStart(currentLine); - while (--pos > lineStartPos) { - char ch = styler.SafeGetCharAt(pos); - if (ch != ' ' && ch != '\t') { - break; - } - } - const char *retBack = "nruter"; - const char *s = retBack; - while (*s - && pos >= lineStartPos - && styler.SafeGetCharAt(pos) == *s) { - s++; - pos--; - } - return !*s; -} - -bool IsSpaceOrTab(int ch) { - return ch == ' ' || ch == '\t'; -} - -bool OnlySpaceOrTab(const std::string &s) { - for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) { - if (!IsSpaceOrTab(*it)) - return false; - } - return true; -} - -std::vector StringSplit(const std::string &text, int separator) { - std::vector vs(text.empty() ? 0 : 1); - for (std::string::const_iterator it = text.begin(); it != text.end(); ++it) { - if (*it == separator) { - vs.push_back(std::string()); - } else { - vs.back() += *it; - } - } - return vs; -} - -struct BracketPair { - std::vector::iterator itBracket; - std::vector::iterator itEndBracket; -}; - -BracketPair FindBracketPair(std::vector &tokens) { - BracketPair bp; - std::vector::iterator itTok = std::find(tokens.begin(), tokens.end(), "("); - bp.itBracket = tokens.end(); - bp.itEndBracket = tokens.end(); - if (itTok != tokens.end()) { - bp.itBracket = itTok; - size_t nest = 0; - while (itTok != tokens.end()) { - if (*itTok == "(") { - nest++; - } else if (*itTok == ")") { - nest--; - if (nest == 0) { - bp.itEndBracket = itTok; - return bp; - } - } - ++itTok; - } - } - bp.itBracket = tokens.end(); - return bp; -} - -void highlightTaskMarker(StyleContext &sc, LexAccessor &styler, - int activity, WordList &markerList, bool caseSensitive){ - if ((isoperator(sc.chPrev) || IsASpace(sc.chPrev)) && markerList.Length()) { - const int lengthMarker = 50; - char marker[lengthMarker+1]; - Sci_Position currPos = (Sci_Position) sc.currentPos; - int i = 0; - while (i < lengthMarker) { - char ch = styler.SafeGetCharAt(currPos + i); - if (IsASpace(ch) || isoperator(ch)) { - break; - } - if (caseSensitive) - marker[i] = ch; - else - marker[i] = static_cast(tolower(ch)); - i++; - } - marker[i] = '\0'; - if (markerList.InList(marker)) { - sc.SetState(SCE_C_TASKMARKER|activity); - } - } -} - -struct EscapeSequence { - int digitsLeft; - CharacterSet setHexDigits; - CharacterSet setOctDigits; - CharacterSet setNoneNumeric; - CharacterSet *escapeSetValid; - EscapeSequence() { - digitsLeft = 0; - escapeSetValid = 0; - setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef"); - setOctDigits = CharacterSet(CharacterSet::setNone, "01234567"); - } - void resetEscapeState(int nextChar) { - digitsLeft = 0; - escapeSetValid = &setNoneNumeric; - if (nextChar == 'U') { - digitsLeft = 9; - escapeSetValid = &setHexDigits; - } else if (nextChar == 'u') { - digitsLeft = 5; - escapeSetValid = &setHexDigits; - } else if (nextChar == 'x') { - digitsLeft = 5; - escapeSetValid = &setHexDigits; - } else if (setOctDigits.Contains(nextChar)) { - digitsLeft = 3; - escapeSetValid = &setOctDigits; - } - } - bool atEscapeEnd(int currChar) const { - return (digitsLeft <= 0) || !escapeSetValid->Contains(currChar); - } -}; - -std::string GetRestOfLine(LexAccessor &styler, Sci_Position start, bool allowSpace) { - std::string restOfLine; - Sci_Position i =0; - char ch = styler.SafeGetCharAt(start, '\n'); - Sci_Position endLine = styler.LineEnd(styler.GetLine(start)); - while (((start+i) < endLine) && (ch != '\r')) { - char chNext = styler.SafeGetCharAt(start + i + 1, '\n'); - if (ch == '/' && (chNext == '/' || chNext == '*')) - break; - if (allowSpace || (ch != ' ')) - restOfLine += ch; - i++; - ch = chNext; - } - return restOfLine; -} - -bool IsStreamCommentStyle(int style) { - return style == SCE_C_COMMENT || - style == SCE_C_COMMENTDOC || - style == SCE_C_COMMENTDOCKEYWORD || - style == SCE_C_COMMENTDOCKEYWORDERROR; -} - -struct PPDefinition { - Sci_Position line; - std::string key; - std::string value; - bool isUndef; - std::string arguments; - PPDefinition(Sci_Position line_, const std::string &key_, const std::string &value_, bool isUndef_ = false, const std::string &arguments_="") : - line(line_), key(key_), value(value_), isUndef(isUndef_), arguments(arguments_) { - } -}; - -class LinePPState { - int state; - int ifTaken; - int level; - bool ValidLevel() const { - return level >= 0 && level < 32; - } - int maskLevel() const { - return 1 << level; - } -public: - LinePPState() : state(0), ifTaken(0), level(-1) { - } - bool IsInactive() const { - return state != 0; - } - bool CurrentIfTaken() const { - return (ifTaken & maskLevel()) != 0; - } - void StartSection(bool on) { - level++; - if (ValidLevel()) { - if (on) { - state &= ~maskLevel(); - ifTaken |= maskLevel(); - } else { - state |= maskLevel(); - ifTaken &= ~maskLevel(); - } - } - } - void EndSection() { - if (ValidLevel()) { - state &= ~maskLevel(); - ifTaken &= ~maskLevel(); - } - level--; - } - void InvertCurrentLevel() { - if (ValidLevel()) { - state ^= maskLevel(); - ifTaken |= maskLevel(); - } - } -}; - -// Hold the preprocessor state for each line seen. -// Currently one entry per line but could become sparse with just one entry per preprocessor line. -class PPStates { - std::vector vlls; -public: - LinePPState ForLine(Sci_Position line) const { - if ((line > 0) && (vlls.size() > static_cast(line))) { - return vlls[line]; - } else { - return LinePPState(); - } - } - void Add(Sci_Position line, LinePPState lls) { - vlls.resize(line+1); - vlls[line] = lls; - } -}; - -// An individual named option for use in an OptionSet - -// Options used for LexerCPP -struct OptionsCPP { - bool stylingWithinPreprocessor; - bool identifiersAllowDollars; - bool trackPreprocessor; - bool updatePreprocessor; - bool verbatimStringsAllowEscapes; - bool triplequotedStrings; - bool hashquotedStrings; - bool backQuotedStrings; - bool escapeSequence; - bool fold; - bool foldSyntaxBased; - bool foldComment; - bool foldCommentMultiline; - bool foldCommentExplicit; - std::string foldExplicitStart; - std::string foldExplicitEnd; - bool foldExplicitAnywhere; - bool foldPreprocessor; - bool foldPreprocessorAtElse; - bool foldCompact; - bool foldAtElse; - OptionsCPP() { - stylingWithinPreprocessor = false; - identifiersAllowDollars = true; - trackPreprocessor = true; - updatePreprocessor = true; - verbatimStringsAllowEscapes = false; - triplequotedStrings = false; - hashquotedStrings = false; - backQuotedStrings = false; - escapeSequence = false; - fold = false; - foldSyntaxBased = true; - foldComment = false; - foldCommentMultiline = true; - foldCommentExplicit = true; - foldExplicitStart = ""; - foldExplicitEnd = ""; - foldExplicitAnywhere = false; - foldPreprocessor = false; - foldPreprocessorAtElse = false; - foldCompact = false; - foldAtElse = false; - } -}; - -const char *const cppWordLists[] = { - "Primary keywords and identifiers", - "Secondary keywords and identifiers", - "Documentation comment keywords", - "Global classes and typedefs", - "Preprocessor definitions", - "Task marker and error marker keywords", - 0, -}; - -struct OptionSetCPP : public OptionSet { - OptionSetCPP() { - DefineProperty("styling.within.preprocessor", &OptionsCPP::stylingWithinPreprocessor, - "For C++ code, determines whether all preprocessor code is styled in the " - "preprocessor style (0, the default) or only from the initial # to the end " - "of the command word(1)."); - - DefineProperty("lexer.cpp.allow.dollars", &OptionsCPP::identifiersAllowDollars, - "Set to 0 to disallow the '$' character in identifiers with the cpp lexer."); - - DefineProperty("lexer.cpp.track.preprocessor", &OptionsCPP::trackPreprocessor, - "Set to 1 to interpret #if/#else/#endif to grey out code that is not active."); - - DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor, - "Set to 1 to update preprocessor definitions when #define found."); - - DefineProperty("lexer.cpp.verbatim.strings.allow.escapes", &OptionsCPP::verbatimStringsAllowEscapes, - "Set to 1 to allow verbatim strings to contain escape sequences."); - - DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings, - "Set to 1 to enable highlighting of triple-quoted strings."); - - DefineProperty("lexer.cpp.hashquoted.strings", &OptionsCPP::hashquotedStrings, - "Set to 1 to enable highlighting of hash-quoted strings."); - - DefineProperty("lexer.cpp.backquoted.strings", &OptionsCPP::backQuotedStrings, - "Set to 1 to enable highlighting of back-quoted raw strings ."); - - DefineProperty("lexer.cpp.escape.sequence", &OptionsCPP::escapeSequence, - "Set to 1 to enable highlighting of escape sequences in strings"); - - DefineProperty("fold", &OptionsCPP::fold); - - DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased, - "Set this property to 0 to disable syntax based folding."); - - DefineProperty("fold.comment", &OptionsCPP::foldComment, - "This option enables folding multi-line comments and explicit fold points when using the C++ lexer. " - "Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} " - "at the end of a section that should fold."); - - DefineProperty("fold.cpp.comment.multiline", &OptionsCPP::foldCommentMultiline, - "Set this property to 0 to disable folding multi-line comments when fold.comment=1."); - - DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit, - "Set this property to 0 to disable folding explicit fold points when fold.comment=1."); - - DefineProperty("fold.cpp.explicit.start", &OptionsCPP::foldExplicitStart, - "The string to use for explicit fold start points, replacing the standard //{."); - - DefineProperty("fold.cpp.explicit.end", &OptionsCPP::foldExplicitEnd, - "The string to use for explicit fold end points, replacing the standard //}."); - - DefineProperty("fold.cpp.explicit.anywhere", &OptionsCPP::foldExplicitAnywhere, - "Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); - - DefineProperty("fold.cpp.preprocessor.at.else", &OptionsCPP::foldPreprocessorAtElse, - "This option enables folding on a preprocessor #else or #endif line of an #if statement."); - - DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor, - "This option enables folding preprocessor directives when using the C++ lexer. " - "Includes C#'s explicit #region and #endregion folding directives."); - - DefineProperty("fold.compact", &OptionsCPP::foldCompact); - - DefineProperty("fold.at.else", &OptionsCPP::foldAtElse, - "This option enables C++ folding on a \"} else {\" line of an if statement."); - - DefineWordListSets(cppWordLists); - } -}; - -const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0}; - -} - -class LexerCPP : public ILexerWithSubStyles { - bool caseSensitive; - CharacterSet setWord; - CharacterSet setNegationOp; - CharacterSet setArithmethicOp; - CharacterSet setRelOp; - CharacterSet setLogicalOp; - CharacterSet setWordStart; - PPStates vlls; - std::vector ppDefineHistory; - WordList keywords; - WordList keywords2; - WordList keywords3; - WordList keywords4; - WordList ppDefinitions; - WordList markerList; - struct SymbolValue { - std::string value; - std::string arguments; - SymbolValue(const std::string &value_="", const std::string &arguments_="") : value(value_), arguments(arguments_) { - } - SymbolValue &operator = (const std::string &value_) { - value = value_; - arguments.clear(); - return *this; - } - bool IsMacro() const { - return !arguments.empty(); - } - }; - typedef std::map SymbolTable; - SymbolTable preprocessorDefinitionsStart; - OptionsCPP options; - OptionSetCPP osCPP; - EscapeSequence escapeSeq; - SparseState rawStringTerminators; - enum { activeFlag = 0x40 }; - enum { ssIdentifier, ssDocKeyword }; - SubStyles subStyles; -public: - explicit LexerCPP(bool caseSensitive_) : - caseSensitive(caseSensitive_), - setWord(CharacterSet::setAlphaNum, "._", 0x80, true), - setNegationOp(CharacterSet::setNone, "!"), - setArithmethicOp(CharacterSet::setNone, "+-/*%"), - setRelOp(CharacterSet::setNone, "=!<>"), - setLogicalOp(CharacterSet::setNone, "|&"), - subStyles(styleSubable, 0x80, 0x40, activeFlag) { - } - virtual ~LexerCPP() { - } - void SCI_METHOD Release() { - delete this; - } - int SCI_METHOD Version() const { - return lvSubStyles; - } - const char * SCI_METHOD PropertyNames() { - return osCPP.PropertyNames(); - } - int SCI_METHOD PropertyType(const char *name) { - return osCPP.PropertyType(name); - } - const char * SCI_METHOD DescribeProperty(const char *name) { - return osCPP.DescribeProperty(name); - } - Sci_Position SCI_METHOD PropertySet(const char *key, const char *val); - const char * SCI_METHOD DescribeWordListSets() { - return osCPP.DescribeWordListSets(); - } - Sci_Position SCI_METHOD WordListSet(int n, const char *wl); - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess); - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess); - - void * SCI_METHOD PrivateCall(int, void *) { - return 0; - } - - int SCI_METHOD LineEndTypesSupported() { - return SC_LINE_END_TYPE_UNICODE; - } - - int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) { - return subStyles.Allocate(styleBase, numberStyles); - } - int SCI_METHOD SubStylesStart(int styleBase) { - return subStyles.Start(styleBase); - } - int SCI_METHOD SubStylesLength(int styleBase) { - return subStyles.Length(styleBase); - } - int SCI_METHOD StyleFromSubStyle(int subStyle) { - int styleBase = subStyles.BaseStyle(MaskActive(subStyle)); - int active = subStyle & activeFlag; - return styleBase | active; - } - int SCI_METHOD PrimaryStyleFromStyle(int style) { - return MaskActive(style); - } - void SCI_METHOD FreeSubStyles() { - subStyles.Free(); - } - void SCI_METHOD SetIdentifiers(int style, const char *identifiers) { - subStyles.SetIdentifiers(style, identifiers); - } - int SCI_METHOD DistanceToSecondaryStyles() { - return activeFlag; - } - const char * SCI_METHOD GetSubStyleBases() { - return styleSubable; - } - - static ILexer *LexerFactoryCPP() { - return new LexerCPP(true); - } - static ILexer *LexerFactoryCPPInsensitive() { - return new LexerCPP(false); - } - static int MaskActive(int style) { - return style & ~activeFlag; - } - void EvaluateTokens(std::vector &tokens, const SymbolTable &preprocessorDefinitions); - std::vector Tokenize(const std::string &expr) const; - bool EvaluateExpression(const std::string &expr, const SymbolTable &preprocessorDefinitions); -}; - -Sci_Position SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) { - if (osCPP.PropertySet(&options, key, val)) { - if (strcmp(key, "lexer.cpp.allow.dollars") == 0) { - setWord = CharacterSet(CharacterSet::setAlphaNum, "._", 0x80, true); - if (options.identifiersAllowDollars) { - setWord.Add('$'); - } - } - return 0; - } - return -1; -} - -Sci_Position SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) { - WordList *wordListN = 0; - switch (n) { - case 0: - wordListN = &keywords; - break; - case 1: - wordListN = &keywords2; - break; - case 2: - wordListN = &keywords3; - break; - case 3: - wordListN = &keywords4; - break; - case 4: - wordListN = &ppDefinitions; - break; - case 5: - wordListN = &markerList; - break; - } - Sci_Position firstModification = -1; - if (wordListN) { - WordList wlNew; - wlNew.Set(wl); - if (*wordListN != wlNew) { - wordListN->Set(wl); - firstModification = 0; - if (n == 4) { - // Rebuild preprocessorDefinitions - preprocessorDefinitionsStart.clear(); - for (int nDefinition = 0; nDefinition < ppDefinitions.Length(); nDefinition++) { - const char *cpDefinition = ppDefinitions.WordAt(nDefinition); - const char *cpEquals = strchr(cpDefinition, '='); - if (cpEquals) { - std::string name(cpDefinition, cpEquals - cpDefinition); - std::string val(cpEquals+1); - size_t bracket = name.find('('); - size_t bracketEnd = name.find(')'); - if ((bracket != std::string::npos) && (bracketEnd != std::string::npos)) { - // Macro - std::string args = name.substr(bracket + 1, bracketEnd - bracket - 1); - name = name.substr(0, bracket); - preprocessorDefinitionsStart[name] = SymbolValue(val, args); - } else { - preprocessorDefinitionsStart[name] = val; - } - } else { - std::string name(cpDefinition); - std::string val("1"); - preprocessorDefinitionsStart[name] = val; - } - } - } - } - } - return firstModification; -} - -// Functor used to truncate history -struct After { - Sci_Position line; - explicit After(Sci_Position line_) : line(line_) {} - bool operator()(PPDefinition &p) const { - return p.line > line; - } -}; - -void SCI_METHOD LexerCPP::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - LexAccessor styler(pAccess); - - CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-"); - CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-"); - - CharacterSet setDoxygen(CharacterSet::setAlpha, "$@\\&<>#{}[]"); - - setWordStart = CharacterSet(CharacterSet::setAlpha, "_", 0x80, true); - - CharacterSet setInvalidRawFirst(CharacterSet::setNone, " )\\\t\v\f\n"); - - if (options.identifiersAllowDollars) { - setWordStart.Add('$'); - } - - int chPrevNonWhite = ' '; - int visibleChars = 0; - bool lastWordWasUUID = false; - int styleBeforeDCKeyword = SCE_C_DEFAULT; - int styleBeforeTaskMarker = SCE_C_DEFAULT; - bool continuationLine = false; - bool isIncludePreprocessor = false; - bool isStringInPreprocessor = false; - bool inRERange = false; - bool seenDocKeyBrace = false; - - Sci_Position lineCurrent = styler.GetLine(startPos); - if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) || - (MaskActive(initStyle) == SCE_C_COMMENTLINE) || - (MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) { - // Set continuationLine if last character of previous line is '\' - if (lineCurrent > 0) { - Sci_Position endLinePrevious = styler.LineEnd(lineCurrent - 1); - if (endLinePrevious > 0) { - continuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\'; - } - } - } - - // look back to set chPrevNonWhite properly for better regex colouring - if (startPos > 0) { - Sci_Position back = startPos; - while (--back && IsSpaceEquiv(MaskActive(styler.StyleAt(back)))) - ; - if (MaskActive(styler.StyleAt(back)) == SCE_C_OPERATOR) { - chPrevNonWhite = styler.SafeGetCharAt(back); - } - } - - StyleContext sc(startPos, length, initStyle, styler); - LinePPState preproc = vlls.ForLine(lineCurrent); - - bool definitionsChanged = false; - - // Truncate ppDefineHistory before current line - - if (!options.updatePreprocessor) - ppDefineHistory.clear(); - - std::vector::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(lineCurrent-1)); - if (itInvalid != ppDefineHistory.end()) { - ppDefineHistory.erase(itInvalid, ppDefineHistory.end()); - definitionsChanged = true; - } - - SymbolTable preprocessorDefinitions = preprocessorDefinitionsStart; - for (std::vector::iterator itDef = ppDefineHistory.begin(); itDef != ppDefineHistory.end(); ++itDef) { - if (itDef->isUndef) - preprocessorDefinitions.erase(itDef->key); - else - preprocessorDefinitions[itDef->key] = SymbolValue(itDef->value, itDef->arguments); - } - - std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1); - SparseState rawSTNew(lineCurrent); - - int activitySet = preproc.IsInactive() ? activeFlag : 0; - - const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER); - const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD); - - Sci_Position lineEndNext = styler.LineEnd(lineCurrent); - - for (; sc.More();) { - - if (sc.atLineStart) { - // Using MaskActive() is not needed in the following statement. - // Inside inactive preprocessor declaration, state will be reset anyway at the end of this block. - if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) { - // Prevent SCE_C_STRINGEOL from leaking back to previous line which - // ends with a line continuation by locking in the state up to this position. - sc.SetState(sc.state); - } - if ((MaskActive(sc.state) == SCE_C_PREPROCESSOR) && (!continuationLine)) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - // Reset states to beginning of colourise so no surprises - // if different sets of lines lexed. - visibleChars = 0; - lastWordWasUUID = false; - isIncludePreprocessor = false; - inRERange = false; - if (preproc.IsInactive()) { - activitySet = activeFlag; - sc.SetState(sc.state | activitySet); - } - } - - if (sc.atLineEnd) { - lineCurrent++; - lineEndNext = styler.LineEnd(lineCurrent); - vlls.Add(lineCurrent, preproc); - if (rawStringTerminator != "") { - rawSTNew.Set(lineCurrent-1, rawStringTerminator); - } - } - - // Handle line continuation generically. - if (sc.ch == '\\') { - if (static_cast((sc.currentPos+1)) >= lineEndNext) { - lineCurrent++; - lineEndNext = styler.LineEnd(lineCurrent); - vlls.Add(lineCurrent, preproc); - if (rawStringTerminator != "") { - rawSTNew.Set(lineCurrent-1, rawStringTerminator); - } - sc.Forward(); - if (sc.ch == '\r' && sc.chNext == '\n') { - // Even in UTF-8, \r and \n are separate - sc.Forward(); - } - continuationLine = true; - sc.Forward(); - continue; - } - } - - const bool atLineEndBeforeSwitch = sc.atLineEnd; - - // Determine if the current state should terminate. - switch (MaskActive(sc.state)) { - case SCE_C_OPERATOR: - sc.SetState(SCE_C_DEFAULT|activitySet); - break; - case SCE_C_NUMBER: - // We accept almost anything because of hex. and number suffixes - if (sc.ch == '_') { - sc.ChangeState(SCE_C_USERLITERAL|activitySet); - } else if (!(setWord.Contains(sc.ch) - || (sc.ch == '\'') - || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' || - sc.chPrev == 'p' || sc.chPrev == 'P')))) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - break; - case SCE_C_USERLITERAL: - if (!(setWord.Contains(sc.ch))) - sc.SetState(SCE_C_DEFAULT|activitySet); - break; - case SCE_C_IDENTIFIER: - if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch == '.')) { - char s[1000]; - if (caseSensitive) { - sc.GetCurrent(s, sizeof(s)); - } else { - sc.GetCurrentLowered(s, sizeof(s)); - } - if (keywords.InList(s)) { - lastWordWasUUID = strcmp(s, "uuid") == 0; - sc.ChangeState(SCE_C_WORD|activitySet); - } else if (keywords2.InList(s)) { - sc.ChangeState(SCE_C_WORD2|activitySet); - } else if (keywords4.InList(s)) { - sc.ChangeState(SCE_C_GLOBALCLASS|activitySet); - } else { - int subStyle = classifierIdentifiers.ValueFor(s); - if (subStyle >= 0) { - sc.ChangeState(subStyle|activitySet); - } - } - const bool literalString = sc.ch == '\"'; - if (literalString || sc.ch == '\'') { - size_t lenS = strlen(s); - const bool raw = literalString && sc.chPrev == 'R' && !setInvalidRawFirst.Contains(sc.chNext); - if (raw) - s[lenS--] = '\0'; - bool valid = - (lenS == 0) || - ((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) || - ((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8')); - if (valid) { - if (literalString) { - if (raw) { - // Set the style of the string prefix to SCE_C_STRINGRAW but then change to - // SCE_C_DEFAULT as that allows the raw string start code to run. - sc.ChangeState(SCE_C_STRINGRAW|activitySet); - sc.SetState(SCE_C_DEFAULT|activitySet); - } else { - sc.ChangeState(SCE_C_STRING|activitySet); - } - } else { - sc.ChangeState(SCE_C_CHARACTER|activitySet); - } - } else { - sc.SetState(SCE_C_DEFAULT | activitySet); - } - } else { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - } - break; - case SCE_C_PREPROCESSOR: - if (options.stylingWithinPreprocessor) { - if (IsASpace(sc.ch)) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"') || sc.atLineEnd)) { - isStringInPreprocessor = false; - } else if (!isStringInPreprocessor) { - if ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\"')) { - isStringInPreprocessor = true; - } else if (sc.Match('/', '*')) { - if (sc.Match("/**") || sc.Match("/*!")) { - sc.SetState(SCE_C_PREPROCESSORCOMMENTDOC|activitySet); - } else { - sc.SetState(SCE_C_PREPROCESSORCOMMENT|activitySet); - } - sc.Forward(); // Eat the * - } else if (sc.Match('/', '/')) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - } - break; - case SCE_C_PREPROCESSORCOMMENT: - case SCE_C_PREPROCESSORCOMMENTDOC: - if (sc.Match('*', '/')) { - sc.Forward(); - sc.ForwardSetState(SCE_C_PREPROCESSOR|activitySet); - continue; // Without advancing in case of '\'. - } - break; - case SCE_C_COMMENT: - if (sc.Match('*', '/')) { - sc.Forward(); - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } else { - styleBeforeTaskMarker = SCE_C_COMMENT; - highlightTaskMarker(sc, styler, activitySet, markerList, caseSensitive); - } - break; - case SCE_C_COMMENTDOC: - if (sc.Match('*', '/')) { - sc.Forward(); - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support - // Verify that we have the conditions to mark a comment-doc-keyword - if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) { - styleBeforeDCKeyword = SCE_C_COMMENTDOC; - sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); - } - } - break; - case SCE_C_COMMENTLINE: - if (sc.atLineStart && !continuationLine) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } else { - styleBeforeTaskMarker = SCE_C_COMMENTLINE; - highlightTaskMarker(sc, styler, activitySet, markerList, caseSensitive); - } - break; - case SCE_C_COMMENTLINEDOC: - if (sc.atLineStart && !continuationLine) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support - // Verify that we have the conditions to mark a comment-doc-keyword - if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) { - styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC; - sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet); - } - } - break; - case SCE_C_COMMENTDOCKEYWORD: - if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) { - sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR); - sc.Forward(); - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - seenDocKeyBrace = false; - } else if (sc.ch == '[' || sc.ch == '{') { - seenDocKeyBrace = true; - } else if (!setDoxygen.Contains(sc.ch) - && !(seenDocKeyBrace && (sc.ch == ',' || sc.ch == '.'))) { - char s[100]; - if (caseSensitive) { - sc.GetCurrent(s, sizeof(s)); - } else { - sc.GetCurrentLowered(s, sizeof(s)); - } - if (!(IsASpace(sc.ch) || (sc.ch == 0))) { - sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); - } else if (!keywords3.InList(s + 1)) { - int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1); - if (subStyleCDKW >= 0) { - sc.ChangeState(subStyleCDKW|activitySet); - } else { - sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet); - } - } - sc.SetState(styleBeforeDCKeyword|activitySet); - seenDocKeyBrace = false; - } - break; - case SCE_C_STRING: - if (sc.atLineEnd) { - sc.ChangeState(SCE_C_STRINGEOL|activitySet); - } else if (isIncludePreprocessor) { - if (sc.ch == '>') { - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - isIncludePreprocessor = false; - } - } else if (sc.ch == '\\') { - if (options.escapeSequence) { - sc.SetState(SCE_C_ESCAPESEQUENCE|activitySet); - escapeSeq.resetEscapeState(sc.chNext); - } - sc.Forward(); // Skip all characters after the backslash - } else if (sc.ch == '\"') { - if (sc.chNext == '_') { - sc.ChangeState(SCE_C_USERLITERAL|activitySet); - } else { - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } - } - break; - case SCE_C_ESCAPESEQUENCE: - escapeSeq.digitsLeft--; - if (!escapeSeq.atEscapeEnd(sc.ch)) { - break; - } - if (sc.ch == '"') { - sc.SetState(SCE_C_STRING|activitySet); - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } else if (sc.ch == '\\') { - escapeSeq.resetEscapeState(sc.chNext); - sc.Forward(); - } else { - sc.SetState(SCE_C_STRING|activitySet); - if (sc.atLineEnd) { - sc.ChangeState(SCE_C_STRINGEOL|activitySet); - } - } - break; - case SCE_C_HASHQUOTEDSTRING: - if (sc.ch == '\\') { - if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { - sc.Forward(); - } - } else if (sc.ch == '\"') { - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } - break; - case SCE_C_STRINGRAW: - if (sc.Match(rawStringTerminator.c_str())) { - for (size_t termPos=rawStringTerminator.size(); termPos; termPos--) - sc.Forward(); - sc.SetState(SCE_C_DEFAULT|activitySet); - rawStringTerminator = ""; - } - break; - case SCE_C_CHARACTER: - if (sc.atLineEnd) { - sc.ChangeState(SCE_C_STRINGEOL|activitySet); - } else if (sc.ch == '\\') { - if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { - sc.Forward(); - } - } else if (sc.ch == '\'') { - if (sc.chNext == '_') { - sc.ChangeState(SCE_C_USERLITERAL|activitySet); - } else { - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } - } - break; - case SCE_C_REGEX: - if (sc.atLineStart) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (! inRERange && sc.ch == '/') { - sc.Forward(); - while ((sc.ch < 0x80) && islower(sc.ch)) - sc.Forward(); // gobble regex flags - sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (sc.ch == '\\' && (static_cast(sc.currentPos+1) < lineEndNext)) { - // Gobble up the escaped character - sc.Forward(); - } else if (sc.ch == '[') { - inRERange = true; - } else if (sc.ch == ']') { - inRERange = false; - } - break; - case SCE_C_STRINGEOL: - if (sc.atLineStart) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - break; - case SCE_C_VERBATIM: - if (options.verbatimStringsAllowEscapes && (sc.ch == '\\')) { - sc.Forward(); // Skip all characters after the backslash - } else if (sc.ch == '\"') { - if (sc.chNext == '\"') { - sc.Forward(); - } else { - sc.ForwardSetState(SCE_C_DEFAULT|activitySet); - } - } - break; - case SCE_C_TRIPLEVERBATIM: - if (sc.Match("\"\"\"")) { - while (sc.Match('"')) { - sc.Forward(); - } - sc.SetState(SCE_C_DEFAULT|activitySet); - } - break; - case SCE_C_UUID: - if (sc.atLineEnd || sc.ch == ')') { - sc.SetState(SCE_C_DEFAULT|activitySet); - } - break; - case SCE_C_TASKMARKER: - if (isoperator(sc.ch) || IsASpace(sc.ch)) { - sc.SetState(styleBeforeTaskMarker|activitySet); - styleBeforeTaskMarker = SCE_C_DEFAULT; - } - } - - if (sc.atLineEnd && !atLineEndBeforeSwitch) { - // State exit processing consumed characters up to end of line. - lineCurrent++; - lineEndNext = styler.LineEnd(lineCurrent); - vlls.Add(lineCurrent, preproc); - } - - // Determine if a new state should be entered. - if (MaskActive(sc.state) == SCE_C_DEFAULT) { - if (sc.Match('@', '\"')) { - sc.SetState(SCE_C_VERBATIM|activitySet); - sc.Forward(); - } else if (options.triplequotedStrings && sc.Match("\"\"\"")) { - sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet); - sc.Forward(2); - } else if (options.hashquotedStrings && sc.Match('#', '\"')) { - sc.SetState(SCE_C_HASHQUOTEDSTRING|activitySet); - sc.Forward(); - } else if (options.backQuotedStrings && sc.Match('`')) { - sc.SetState(SCE_C_STRINGRAW|activitySet); - rawStringTerminator = "`"; - } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { - if (lastWordWasUUID) { - sc.SetState(SCE_C_UUID|activitySet); - lastWordWasUUID = false; - } else { - sc.SetState(SCE_C_NUMBER|activitySet); - } - } else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch) || (sc.ch == '@'))) { - if (lastWordWasUUID) { - sc.SetState(SCE_C_UUID|activitySet); - lastWordWasUUID = false; - } else { - sc.SetState(SCE_C_IDENTIFIER|activitySet); - } - } else if (sc.Match('/', '*')) { - if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style - sc.SetState(SCE_C_COMMENTDOC|activitySet); - } else { - sc.SetState(SCE_C_COMMENT|activitySet); - } - sc.Forward(); // Eat the * so it isn't used for the end of the comment - } else if (sc.Match('/', '/')) { - if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!")) - // Support of Qt/Doxygen doc. style - sc.SetState(SCE_C_COMMENTLINEDOC|activitySet); - else - sc.SetState(SCE_C_COMMENTLINE|activitySet); - } else if (sc.ch == '/' - && (setOKBeforeRE.Contains(chPrevNonWhite) - || followsReturnKeyword(sc, styler)) - && (!setCouldBePostOp.Contains(chPrevNonWhite) - || !FollowsPostfixOperator(sc, styler))) { - sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx - inRERange = false; - } else if (sc.ch == '\"') { - if (sc.chPrev == 'R') { - styler.Flush(); - if (MaskActive(styler.StyleAt(sc.currentPos - 1)) == SCE_C_STRINGRAW) { - sc.SetState(SCE_C_STRINGRAW|activitySet); - rawStringTerminator = ")"; - for (Sci_Position termPos = sc.currentPos + 1;; termPos++) { - char chTerminator = styler.SafeGetCharAt(termPos, '('); - if (chTerminator == '(') - break; - rawStringTerminator += chTerminator; - } - rawStringTerminator += '\"'; - } else { - sc.SetState(SCE_C_STRING|activitySet); - } - } else { - sc.SetState(SCE_C_STRING|activitySet); - } - isIncludePreprocessor = false; // ensure that '>' won't end the string - } else if (isIncludePreprocessor && sc.ch == '<') { - sc.SetState(SCE_C_STRING|activitySet); - } else if (sc.ch == '\'') { - sc.SetState(SCE_C_CHARACTER|activitySet); - } else if (sc.ch == '#' && visibleChars == 0) { - // Preprocessor commands are alone on their line - sc.SetState(SCE_C_PREPROCESSOR|activitySet); - // Skip whitespace between # and preprocessor word - do { - sc.Forward(); - } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More()); - if (sc.atLineEnd) { - sc.SetState(SCE_C_DEFAULT|activitySet); - } else if (sc.Match("include")) { - isIncludePreprocessor = true; - } else { - if (options.trackPreprocessor) { - if (sc.Match("ifdef") || sc.Match("ifndef")) { - bool isIfDef = sc.Match("ifdef"); - int i = isIfDef ? 5 : 6; - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false); - bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end(); - preproc.StartSection(isIfDef == foundDef); - } else if (sc.Match("if")) { - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true); - bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); - preproc.StartSection(ifGood); - } else if (sc.Match("else")) { - if (!preproc.CurrentIfTaken()) { - preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); - } else if (!preproc.IsInactive()) { - preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); - } - } else if (sc.Match("elif")) { - // Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif - if (!preproc.CurrentIfTaken()) { - // Similar to #if - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true); - bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions); - if (ifGood) { - preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); - } - } else if (!preproc.IsInactive()) { - preproc.InvertCurrentLevel(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - if (!activitySet) - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); - } - } else if (sc.Match("endif")) { - preproc.EndSection(); - activitySet = preproc.IsInactive() ? activeFlag : 0; - sc.ChangeState(SCE_C_PREPROCESSOR|activitySet); - } else if (sc.Match("define")) { - if (options.updatePreprocessor && !preproc.IsInactive()) { - std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true); - size_t startName = 0; - while ((startName < restOfLine.length()) && IsSpaceOrTab(restOfLine[startName])) - startName++; - size_t endName = startName; - while ((endName < restOfLine.length()) && setWord.Contains(static_cast(restOfLine[endName]))) - endName++; - std::string key = restOfLine.substr(startName, endName-startName); - if ((endName < restOfLine.length()) && (restOfLine.at(endName) == '(')) { - // Macro - size_t endArgs = endName; - while ((endArgs < restOfLine.length()) && (restOfLine[endArgs] != ')')) - endArgs++; - std::string args = restOfLine.substr(endName + 1, endArgs - endName - 1); - size_t startValue = endArgs+1; - while ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue])) - startValue++; - std::string value; - if (startValue < restOfLine.length()) - value = restOfLine.substr(startValue); - preprocessorDefinitions[key] = SymbolValue(value, args); - ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value, false, args)); - definitionsChanged = true; - } else { - // Value - size_t startValue = endName; - while ((startValue < restOfLine.length()) && IsSpaceOrTab(restOfLine[startValue])) - startValue++; - std::string value = restOfLine.substr(startValue); - preprocessorDefinitions[key] = value; - ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value)); - definitionsChanged = true; - } - } - } else if (sc.Match("undef")) { - if (options.updatePreprocessor && !preproc.IsInactive()) { - const std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 5, false); - std::vector tokens = Tokenize(restOfLine); - if (tokens.size() >= 1) { - const std::string key = tokens[0]; - preprocessorDefinitions.erase(key); - ppDefineHistory.push_back(PPDefinition(lineCurrent, key, "", true)); - definitionsChanged = true; - } - } - } - } - } - } else if (isoperator(sc.ch)) { - sc.SetState(SCE_C_OPERATOR|activitySet); - } - } - - if (!IsASpace(sc.ch) && !IsSpaceEquiv(MaskActive(sc.state))) { - chPrevNonWhite = sc.ch; - visibleChars++; - } - continuationLine = false; - sc.Forward(); - } - const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent); - if (definitionsChanged || rawStringsChanged) - styler.ChangeLexerState(startPos, startPos + length); - sc.Complete(); -} - -// Store both the current line's fold level and the next lines in the -// level store to make it easy to pick up with each increment -// and to make it possible to fiddle the current level for "} else {". - -void SCI_METHOD LexerCPP::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - - if (!options.fold) - return; - - LexAccessor styler(pAccess); - - Sci_PositionU endPos = startPos + length; - int visibleChars = 0; - bool inLineComment = false; - Sci_Position lineCurrent = styler.GetLine(startPos); - int levelCurrent = SC_FOLDLEVELBASE; - if (lineCurrent > 0) - levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; - Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1); - int levelMinCurrent = levelCurrent; - int levelNext = levelCurrent; - char chNext = styler[startPos]; - int styleNext = MaskActive(styler.StyleAt(startPos)); - int style = MaskActive(initStyle); - const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); - for (Sci_PositionU i = startPos; i < endPos; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - int stylePrev = style; - style = styleNext; - styleNext = MaskActive(styler.StyleAt(i + 1)); - bool atEOL = i == (lineStartNext-1); - if ((style == SCE_C_COMMENTLINE) || (style == SCE_C_COMMENTLINEDOC)) - inLineComment = true; - if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) { - if (!IsStreamCommentStyle(stylePrev)) { - levelNext++; - } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { - // Comments don't end at end of line and the next character may be unstyled. - levelNext--; - } - } - if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) { - if (userDefinedFoldMarkers) { - if (styler.Match(i, options.foldExplicitStart.c_str())) { - levelNext++; - } else if (styler.Match(i, options.foldExplicitEnd.c_str())) { - levelNext--; - } - } else { - if ((ch == '/') && (chNext == '/')) { - char chNext2 = styler.SafeGetCharAt(i + 2); - if (chNext2 == '{') { - levelNext++; - } else if (chNext2 == '}') { - levelNext--; - } - } - } - } - if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) { - if (ch == '#') { - Sci_PositionU j = i + 1; - while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { - j++; - } - if (styler.Match(j, "region") || styler.Match(j, "if")) { - levelNext++; - } else if (styler.Match(j, "end")) { - levelNext--; - } - - if (options.foldPreprocessorAtElse && (styler.Match(j, "else") || styler.Match(j, "elif"))) { - levelMinCurrent--; - } - } - } - if (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) { - if (ch == '{' || ch == '[' || ch == '(') { - // Measure the minimum before a '{' to allow - // folding on "} else {" - if (options.foldAtElse && levelMinCurrent > levelNext) { - levelMinCurrent = levelNext; - } - levelNext++; - } else if (ch == '}' || ch == ']' || ch == ')') { - levelNext--; - } - } - if (!IsASpace(ch)) - visibleChars++; - if (atEOL || (i == endPos-1)) { - int levelUse = levelCurrent; - if ((options.foldSyntaxBased && options.foldAtElse) || - (options.foldPreprocessor && options.foldPreprocessorAtElse) - ) { - levelUse = levelMinCurrent; - } - int lev = levelUse | levelNext << 16; - if (visibleChars == 0 && options.foldCompact) - lev |= SC_FOLDLEVELWHITEFLAG; - if (levelUse < levelNext) - lev |= SC_FOLDLEVELHEADERFLAG; - if (lev != styler.LevelAt(lineCurrent)) { - styler.SetLevel(lineCurrent, lev); - } - lineCurrent++; - lineStartNext = styler.LineStart(lineCurrent+1); - levelCurrent = levelNext; - levelMinCurrent = levelCurrent; - if (atEOL && (i == static_cast(styler.Length()-1))) { - // There is an empty line at end of file so give it same level and empty - styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); - } - visibleChars = 0; - inLineComment = false; - } - } -} - -void LexerCPP::EvaluateTokens(std::vector &tokens, const SymbolTable &preprocessorDefinitions) { - - // Remove whitespace tokens - tokens.erase(std::remove_if(tokens.begin(), tokens.end(), OnlySpaceOrTab), tokens.end()); - - // Evaluate defined statements to either 0 or 1 - for (size_t i=0; (i+1)) - SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i+2]); - if (it != preprocessorDefinitions.end()) { - val = "1"; - } - tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 4); - } else { - // Spurious '(' so erase as more likely to result in false - tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 2); - } - } else { - // defined - SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i+1]); - if (it != preprocessorDefinitions.end()) { - val = "1"; - } - } - tokens[i] = val; - } else { - i++; - } - } - - // Evaluate identifiers - const size_t maxIterations = 100; - size_t iterations = 0; // Limit number of iterations in case there is a recursive macro. - for (size_t i = 0; (i(tokens[i][0]))) { - SymbolTable::const_iterator it = preprocessorDefinitions.find(tokens[i]); - if (it != preprocessorDefinitions.end()) { - // Tokenize value - std::vector macroTokens = Tokenize(it->second.value); - if (it->second.IsMacro()) { - if ((i + 1 < tokens.size()) && (tokens.at(i + 1) == "(")) { - // Create map of argument name to value - std::vector argumentNames = StringSplit(it->second.arguments, ','); - std::map arguments; - size_t arg = 0; - size_t tok = i+2; - while ((tok < tokens.size()) && (arg < argumentNames.size()) && (tokens.at(tok) != ")")) { - if (tokens.at(tok) != ",") { - arguments[argumentNames.at(arg)] = tokens.at(tok); - arg++; - } - tok++; - } - - // Remove invocation - tokens.erase(tokens.begin() + i, tokens.begin() + tok + 1); - - // Substitute values into macro - macroTokens.erase(std::remove_if(macroTokens.begin(), macroTokens.end(), OnlySpaceOrTab), macroTokens.end()); - - for (size_t iMacro = 0; iMacro < macroTokens.size();) { - if (setWordStart.Contains(static_cast(macroTokens[iMacro][0]))) { - std::map::const_iterator itFind = arguments.find(macroTokens[iMacro]); - if (itFind != arguments.end()) { - // TODO: Possible that value will be expression so should insert tokenized form - macroTokens[iMacro] = itFind->second; - } - } - iMacro++; - } - - // Insert results back into tokens - tokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end()); - - } else { - i++; - } - } else { - // Remove invocation - tokens.erase(tokens.begin() + i); - // Insert results back into tokens - tokens.insert(tokens.begin() + i, macroTokens.begin(), macroTokens.end()); - } - } else { - // Identifier not found - tokens.erase(tokens.begin() + i); - } - } else { - i++; - } - } - - // Find bracketed subexpressions and recurse on them - BracketPair bracketPair = FindBracketPair(tokens); - while (bracketPair.itBracket != tokens.end()) { - std::vector inBracket(bracketPair.itBracket + 1, bracketPair.itEndBracket); - EvaluateTokens(inBracket, preprocessorDefinitions); - - // The insertion is done before the removal because there were failures with the opposite approach - tokens.insert(bracketPair.itBracket, inBracket.begin(), inBracket.end()); - - bracketPair = FindBracketPair(tokens); - tokens.erase(bracketPair.itBracket, bracketPair.itEndBracket + 1); - - bracketPair = FindBracketPair(tokens); - } - - // Evaluate logical negations - for (size_t j=0; (j+1)::iterator itInsert = - tokens.erase(tokens.begin() + j, tokens.begin() + j + 2); - tokens.insert(itInsert, isTrue ? "1" : "0"); - } else { - j++; - } - } - - // Evaluate expressions in precedence order - enum precedence { precArithmetic, precRelative, precLogical }; - for (int prec=precArithmetic; prec <= precLogical; prec++) { - // Looking at 3 tokens at a time so end at 2 before end - for (size_t k=0; (k+2)") - result = valA > valB; - else if (tokens[k+1] == ">=") - result = valA >= valB; - else if (tokens[k+1] == "==") - result = valA == valB; - else if (tokens[k+1] == "!=") - result = valA != valB; - else if (tokens[k+1] == "||") - result = valA || valB; - else if (tokens[k+1] == "&&") - result = valA && valB; - char sResult[30]; - sprintf(sResult, "%d", result); - std::vector::iterator itInsert = - tokens.erase(tokens.begin() + k, tokens.begin() + k + 3); - tokens.insert(itInsert, sResult); - } else { - k++; - } - } - } -} - -std::vector LexerCPP::Tokenize(const std::string &expr) const { - // Break into tokens - std::vector tokens; - const char *cp = expr.c_str(); - while (*cp) { - std::string word; - if (setWord.Contains(static_cast(*cp))) { - // Identifiers and numbers - while (setWord.Contains(static_cast(*cp))) { - word += *cp; - cp++; - } - } else if (IsSpaceOrTab(*cp)) { - while (IsSpaceOrTab(*cp)) { - word += *cp; - cp++; - } - } else if (setRelOp.Contains(static_cast(*cp))) { - word += *cp; - cp++; - if (setRelOp.Contains(static_cast(*cp))) { - word += *cp; - cp++; - } - } else if (setLogicalOp.Contains(static_cast(*cp))) { - word += *cp; - cp++; - if (setLogicalOp.Contains(static_cast(*cp))) { - word += *cp; - cp++; - } - } else { - // Should handle strings, characters, and comments here - word += *cp; - cp++; - } - tokens.push_back(word); - } - return tokens; -} - -bool LexerCPP::EvaluateExpression(const std::string &expr, const SymbolTable &preprocessorDefinitions) { - std::vector tokens = Tokenize(expr); - - EvaluateTokens(tokens, preprocessorDefinitions); - - // "0" or "" -> false else true - bool isFalse = tokens.empty() || - ((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0")); - return !isFalse; -} - -LexerModule lmCPP(SCLEX_CPP, LexerCPP::LexerFactoryCPP, "cpp", cppWordLists); -LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, LexerCPP::LexerFactoryCPPInsensitive, "cppnocase", cppWordLists); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexDiff.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexDiff.cxx deleted file mode 100644 index baa8368f6..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexDiff.cxx +++ /dev/null @@ -1,153 +0,0 @@ -// Scintilla source code edit control -/** @file LexDiff.cxx - ** Lexer for diff results. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { - return (styler[i] == '\n') || - ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); -} - -#define DIFF_BUFFER_START_SIZE 16 -// Note that ColouriseDiffLine analyzes only the first DIFF_BUFFER_START_SIZE -// characters of each line to classify the line. - -static void ColouriseDiffLine(char *lineBuffer, Sci_Position endLine, Accessor &styler) { - // It is needed to remember the current state to recognize starting - // comment lines before the first "diff " or "--- ". If a real - // difference starts then each line starting with ' ' is a whitespace - // otherwise it is considered a comment (Only in..., Binary file...) - if (0 == strncmp(lineBuffer, "diff ", 5)) { - styler.ColourTo(endLine, SCE_DIFF_COMMAND); - } else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff - styler.ColourTo(endLine, SCE_DIFF_COMMAND); - } else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') { - // In a context diff, --- appears in both the header and the position markers - if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/')) - styler.ColourTo(endLine, SCE_DIFF_POSITION); - else if (lineBuffer[3] == '\r' || lineBuffer[3] == '\n') - styler.ColourTo(endLine, SCE_DIFF_POSITION); - else - styler.ColourTo(endLine, SCE_DIFF_HEADER); - } else if (0 == strncmp(lineBuffer, "+++ ", 4)) { - // I don't know of any diff where "+++ " is a position marker, but for - // consistency, do the same as with "--- " and "*** ". - if (atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) - styler.ColourTo(endLine, SCE_DIFF_POSITION); - else - styler.ColourTo(endLine, SCE_DIFF_HEADER); - } else if (0 == strncmp(lineBuffer, "====", 4)) { // For p4's diff - styler.ColourTo(endLine, SCE_DIFF_HEADER); - } else if (0 == strncmp(lineBuffer, "***", 3)) { - // In a context diff, *** appears in both the header and the position markers. - // Also ******** is a chunk header, but here it's treated as part of the - // position marker since there is no separate style for a chunk header. - if (lineBuffer[3] == ' ' && atoi(lineBuffer+4) && !strchr(lineBuffer, '/')) - styler.ColourTo(endLine, SCE_DIFF_POSITION); - else if (lineBuffer[3] == '*') - styler.ColourTo(endLine, SCE_DIFF_POSITION); - else - styler.ColourTo(endLine, SCE_DIFF_HEADER); - } else if (0 == strncmp(lineBuffer, "? ", 2)) { // For difflib - styler.ColourTo(endLine, SCE_DIFF_HEADER); - } else if (lineBuffer[0] == '@') { - styler.ColourTo(endLine, SCE_DIFF_POSITION); - } else if (lineBuffer[0] >= '0' && lineBuffer[0] <= '9') { - styler.ColourTo(endLine, SCE_DIFF_POSITION); - } else if (lineBuffer[0] == '-' || lineBuffer[0] == '<') { - styler.ColourTo(endLine, SCE_DIFF_DELETED); - } else if (lineBuffer[0] == '+' || lineBuffer[0] == '>') { - styler.ColourTo(endLine, SCE_DIFF_ADDED); - } else if (lineBuffer[0] == '!') { - styler.ColourTo(endLine, SCE_DIFF_CHANGED); - } else if (lineBuffer[0] != ' ') { - styler.ColourTo(endLine, SCE_DIFF_COMMENT); - } else { - styler.ColourTo(endLine, SCE_DIFF_DEFAULT); - } -} - -static void ColouriseDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { - char lineBuffer[DIFF_BUFFER_START_SIZE] = ""; - styler.StartAt(startPos); - styler.StartSegment(startPos); - Sci_PositionU linePos = 0; - for (Sci_PositionU i = startPos; i < startPos + length; i++) { - if (AtEOL(styler, i)) { - if (linePos < DIFF_BUFFER_START_SIZE) { - lineBuffer[linePos] = 0; - } - ColouriseDiffLine(lineBuffer, i, styler); - linePos = 0; - } else if (linePos < DIFF_BUFFER_START_SIZE - 1) { - lineBuffer[linePos++] = styler[i]; - } else if (linePos == DIFF_BUFFER_START_SIZE - 1) { - lineBuffer[linePos++] = 0; - } - } - if (linePos > 0) { // Last line does not have ending characters - if (linePos < DIFF_BUFFER_START_SIZE) { - lineBuffer[linePos] = 0; - } - ColouriseDiffLine(lineBuffer, startPos + length - 1, styler); - } -} - -static void FoldDiffDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { - Sci_Position curLine = styler.GetLine(startPos); - Sci_Position curLineStart = styler.LineStart(curLine); - int prevLevel = curLine > 0 ? styler.LevelAt(curLine - 1) : SC_FOLDLEVELBASE; - int nextLevel; - - do { - int lineType = styler.StyleAt(curLineStart); - if (lineType == SCE_DIFF_COMMAND) - nextLevel = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG; - else if (lineType == SCE_DIFF_HEADER) - nextLevel = (SC_FOLDLEVELBASE + 1) | SC_FOLDLEVELHEADERFLAG; - else if (lineType == SCE_DIFF_POSITION && styler[curLineStart] != '-') - nextLevel = (SC_FOLDLEVELBASE + 2) | SC_FOLDLEVELHEADERFLAG; - else if (prevLevel & SC_FOLDLEVELHEADERFLAG) - nextLevel = (prevLevel & SC_FOLDLEVELNUMBERMASK) + 1; - else - nextLevel = prevLevel; - - if ((nextLevel & SC_FOLDLEVELHEADERFLAG) && (nextLevel == prevLevel)) - styler.SetLevel(curLine-1, prevLevel & ~SC_FOLDLEVELHEADERFLAG); - - styler.SetLevel(curLine, nextLevel); - prevLevel = nextLevel; - - curLineStart = styler.LineStart(++curLine); - } while (static_cast(startPos)+length > curLineStart); -} - -static const char *const emptyWordListDesc[] = { - 0 -}; - -LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexErrorList.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexErrorList.cxx deleted file mode 100644 index 6dc6b025e..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexErrorList.cxx +++ /dev/null @@ -1,394 +0,0 @@ -// Scintilla source code edit control -/** @file LexErrorList.cxx - ** Lexer for error lists. Used for the output pane in SciTE. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static bool strstart(const char *haystack, const char *needle) { - return strncmp(haystack, needle, strlen(needle)) == 0; -} - -static bool Is0To9(char ch) { - return (ch >= '0') && (ch <= '9'); -} - -static bool Is1To9(char ch) { - return (ch >= '1') && (ch <= '9'); -} - -static bool IsAlphabetic(int ch) { - return IsASCII(ch) && isalpha(ch); -} - -static inline bool AtEOL(Accessor &styler, Sci_PositionU i) { - return (styler[i] == '\n') || - ((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n')); -} - -static int RecogniseErrorListLine(const char *lineBuffer, Sci_PositionU lengthLine, Sci_Position &startValue) { - if (lineBuffer[0] == '>') { - // Command or return status - return SCE_ERR_CMD; - } else if (lineBuffer[0] == '<') { - // Diff removal. - return SCE_ERR_DIFF_DELETION; - } else if (lineBuffer[0] == '!') { - return SCE_ERR_DIFF_CHANGED; - } else if (lineBuffer[0] == '+') { - if (strstart(lineBuffer, "+++ ")) { - return SCE_ERR_DIFF_MESSAGE; - } else { - return SCE_ERR_DIFF_ADDITION; - } - } else if (lineBuffer[0] == '-') { - if (strstart(lineBuffer, "--- ")) { - return SCE_ERR_DIFF_MESSAGE; - } else { - return SCE_ERR_DIFF_DELETION; - } - } else if (strstart(lineBuffer, "cf90-")) { - // Absoft Pro Fortran 90/95 v8.2 error and/or warning message - return SCE_ERR_ABSF; - } else if (strstart(lineBuffer, "fortcom:")) { - // Intel Fortran Compiler v8.0 error/warning message - return SCE_ERR_IFORT; - } else if (strstr(lineBuffer, "File \"") && strstr(lineBuffer, ", line ")) { - return SCE_ERR_PYTHON; - } else if (strstr(lineBuffer, " in ") && strstr(lineBuffer, " on line ")) { - return SCE_ERR_PHP; - } else if ((strstart(lineBuffer, "Error ") || - strstart(lineBuffer, "Warning ")) && - strstr(lineBuffer, " at (") && - strstr(lineBuffer, ") : ") && - (strstr(lineBuffer, " at (") < strstr(lineBuffer, ") : "))) { - // Intel Fortran Compiler error/warning message - return SCE_ERR_IFC; - } else if (strstart(lineBuffer, "Error ")) { - // Borland error message - return SCE_ERR_BORLAND; - } else if (strstart(lineBuffer, "Warning ")) { - // Borland warning message - return SCE_ERR_BORLAND; - } else if (strstr(lineBuffer, "at line ") && - (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) && - strstr(lineBuffer, "file ") && - (strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) { - // Lua 4 error message - return SCE_ERR_LUA; - } else if (strstr(lineBuffer, " at ") && - (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) && - strstr(lineBuffer, " line ") && - (strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) && - (strstr(lineBuffer, " at ") + 4 < (strstr(lineBuffer, " line ")))) { - // perl error message: - // at line - return SCE_ERR_PERL; - } else if ((memcmp(lineBuffer, " at ", 6) == 0) && - strstr(lineBuffer, ":line ")) { - // A .NET traceback - return SCE_ERR_NET; - } else if (strstart(lineBuffer, "Line ") && - strstr(lineBuffer, ", file ")) { - // Essential Lahey Fortran error message - return SCE_ERR_ELF; - } else if (strstart(lineBuffer, "line ") && - strstr(lineBuffer, " column ")) { - // HTML tidy style: line 42 column 1 - return SCE_ERR_TIDY; - } else if (strstart(lineBuffer, "\tat ") && - strstr(lineBuffer, "(") && - strstr(lineBuffer, ".java:")) { - // Java stack back trace - return SCE_ERR_JAVA_STACK; - } else if (strstart(lineBuffer, "In file included from ") || - strstart(lineBuffer, " from ")) { - // GCC showing include path to following error - return SCE_ERR_GCC_INCLUDED_FROM; - } else if (strstr(lineBuffer, "warning LNK")) { - // Microsoft linker warning: - // { : } warning LNK9999 - return SCE_ERR_MS; - } else { - // Look for one of the following formats: - // GCC: :: - // Microsoft: () : - // Common: (): warning|error|note|remark|catastrophic|fatal - // Common: () warning|error|note|remark|catastrophic|fatal - // Microsoft: (,) - // CTags: \t\t - // Lua 5 traceback: \t:: - // Lua 5.1: : :: - bool initialTab = (lineBuffer[0] == '\t'); - bool initialColonPart = false; - bool canBeCtags = !initialTab; // For ctags must have an identifier with no spaces then a tab - enum { stInitial, - stGccStart, stGccDigit, stGccColumn, stGcc, - stMsStart, stMsDigit, stMsBracket, stMsVc, stMsDigitComma, stMsDotNet, - stCtagsStart, stCtagsFile, stCtagsStartString, stCtagsStringDollar, stCtags, - stUnrecognized - } state = stInitial; - for (Sci_PositionU i = 0; i < lengthLine; i++) { - char ch = lineBuffer[i]; - char chNext = ' '; - if ((i + 1) < lengthLine) - chNext = lineBuffer[i + 1]; - if (state == stInitial) { - if (ch == ':') { - // May be GCC, or might be Lua 5 (Lua traceback same but with tab prefix) - if ((chNext != '\\') && (chNext != '/') && (chNext != ' ')) { - // This check is not completely accurate as may be on - // GTK+ with a file name that includes ':'. - state = stGccStart; - } else if (chNext == ' ') { // indicates a Lua 5.1 error message - initialColonPart = true; - } - } else if ((ch == '(') && Is1To9(chNext) && (!initialTab)) { - // May be Microsoft - // Check against '0' often removes phone numbers - state = stMsStart; - } else if ((ch == '\t') && canBeCtags) { - // May be CTags - state = stCtagsStart; - } else if (ch == ' ') { - canBeCtags = false; - } - } else if (state == stGccStart) { // : - state = Is0To9(ch) ? stGccDigit : stUnrecognized; - } else if (state == stGccDigit) { // : - if (ch == ':') { - state = stGccColumn; // :9.*: is GCC - startValue = i + 1; - } else if (!Is0To9(ch)) { - state = stUnrecognized; - } - } else if (state == stGccColumn) { // :: - if (!Is0To9(ch)) { - state = stGcc; - if (ch == ':') - startValue = i + 1; - break; - } - } else if (state == stMsStart) { // ( - state = Is0To9(ch) ? stMsDigit : stUnrecognized; - } else if (state == stMsDigit) { // ( - if (ch == ',') { - state = stMsDigitComma; - } else if (ch == ')') { - state = stMsBracket; - } else if ((ch != ' ') && !Is0To9(ch)) { - state = stUnrecognized; - } - } else if (state == stMsBracket) { // () - if ((ch == ' ') && (chNext == ':')) { - state = stMsVc; - } else if ((ch == ':' && chNext == ' ') || (ch == ' ')) { - // Possibly Delphi.. don't test against chNext as it's one of the strings below. - char word[512]; - Sci_PositionU j, chPos; - unsigned numstep; - chPos = 0; - if (ch == ' ') - numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i. - else - numstep = 2; // otherwise add 2. - for (j = i + numstep; j < lengthLine && IsAlphabetic(lineBuffer[j]) && chPos < sizeof(word) - 1; j++) - word[chPos++] = lineBuffer[j]; - word[chPos] = 0; - if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") || - !CompareCaseInsensitive(word, "fatal") || !CompareCaseInsensitive(word, "catastrophic") || - !CompareCaseInsensitive(word, "note") || !CompareCaseInsensitive(word, "remark")) { - state = stMsVc; - } else { - state = stUnrecognized; - } - } else { - state = stUnrecognized; - } - } else if (state == stMsDigitComma) { // (, - if (ch == ')') { - state = stMsDotNet; - break; - } else if ((ch != ' ') && !Is0To9(ch)) { - state = stUnrecognized; - } - } else if (state == stCtagsStart) { - if (ch == '\t') { - state = stCtagsFile; - } - } else if (state == stCtagsFile) { - if ((lineBuffer[i - 1] == '\t') && - ((ch == '/' && chNext == '^') || Is0To9(ch))) { - state = stCtags; - break; - } else if ((ch == '/') && (chNext == '^')) { - state = stCtagsStartString; - } - } else if ((state == stCtagsStartString) && ((lineBuffer[i] == '$') && (lineBuffer[i + 1] == '/'))) { - state = stCtagsStringDollar; - break; - } - } - if (state == stGcc) { - return initialColonPart ? SCE_ERR_LUA : SCE_ERR_GCC; - } else if ((state == stMsVc) || (state == stMsDotNet)) { - return SCE_ERR_MS; - } else if ((state == stCtagsStringDollar) || (state == stCtags)) { - return SCE_ERR_CTAG; - } else if (initialColonPart && strstr(lineBuffer, ": warning C")) { - // Microsoft warning without line number - // : warning C9999 - return SCE_ERR_MS; - } else { - return SCE_ERR_DEFAULT; - } - } -} - -#define CSI "\033[" - -namespace { - -bool SequenceEnd(int ch) { - return (ch == 0) || ((ch >= '@') && (ch <= '~')); -} - -int StyleFromSequence(const char *seq) { - int bold = 0; - int colour = 0; - while (!SequenceEnd(*seq)) { - if (Is0To9(*seq)) { - int base = *seq - '0'; - if (Is0To9(seq[1])) { - base = base * 10; - base += seq[1] - '0'; - seq++; - } - if (base == 0) { - colour = 0; - bold = 0; - } - else if (base == 1) { - bold = 1; - } - else if (base >= 30 && base <= 37) { - colour = base - 30; - } - } - seq++; - } - return SCE_ERR_ES_BLACK + bold * 8 + colour; -} - -} - -static void ColouriseErrorListLine( - char *lineBuffer, - Sci_PositionU lengthLine, - Sci_PositionU endPos, - Accessor &styler, - bool valueSeparate, - bool escapeSequences) { - Sci_Position startValue = -1; - int style = RecogniseErrorListLine(lineBuffer, lengthLine, startValue); - if (escapeSequences && strstr(lineBuffer, CSI)) { - const int startPos = endPos - lengthLine; - const char *linePortion = lineBuffer; - int startPortion = startPos; - int portionStyle = style; - while (const char *startSeq = strstr(linePortion, CSI)) { - if (startSeq > linePortion) { - styler.ColourTo(startPortion + static_cast(startSeq - linePortion), portionStyle); - } - const char *endSeq = startSeq + 2; - while (!SequenceEnd(*endSeq)) - endSeq++; - const int endSeqPosition = startPortion + static_cast(endSeq - linePortion) + 1; - switch (*endSeq) { - case 0: - styler.ColourTo(endPos, SCE_ERR_ESCSEQ_UNKNOWN); - return; - case 'm': // Colour command - styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ); - portionStyle = StyleFromSequence(startSeq+2); - break; - case 'K': // Erase to end of line -> ignore - styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ); - break; - default: - styler.ColourTo(endSeqPosition, SCE_ERR_ESCSEQ_UNKNOWN); - portionStyle = style; - } - startPortion = endSeqPosition; - linePortion = endSeq + 1; - } - styler.ColourTo(endPos, portionStyle); - } else { - if (valueSeparate && (startValue >= 0)) { - styler.ColourTo(endPos - (lengthLine - startValue), style); - styler.ColourTo(endPos, SCE_ERR_VALUE); - } else { - styler.ColourTo(endPos, style); - } - } -} - -static void ColouriseErrorListDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) { - char lineBuffer[10000]; - styler.StartAt(startPos); - styler.StartSegment(startPos); - Sci_PositionU linePos = 0; - - // property lexer.errorlist.value.separate - // For lines in the output pane that are matches from Find in Files or GCC-style - // diagnostics, style the path and line number separately from the rest of the - // line with style 21 used for the rest of the line. - // This allows matched text to be more easily distinguished from its location. - bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0; - - // property lexer.errorlist.escape.sequences - // Set to 1 to interpret escape sequences. - const bool escapeSequences = styler.GetPropertyInt("lexer.errorlist.escape.sequences") != 0; - - for (Sci_PositionU i = startPos; i < startPos + length; i++) { - lineBuffer[linePos++] = styler[i]; - if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { - // End of line (or of line buffer) met, colourise it - lineBuffer[linePos] = '\0'; - ColouriseErrorListLine(lineBuffer, linePos, i, styler, valueSeparate, escapeSequences); - linePos = 0; - } - } - if (linePos > 0) { // Last line does not have ending characters - lineBuffer[linePos] = '\0'; - ColouriseErrorListLine(lineBuffer, linePos, startPos + length - 1, styler, valueSeparate, escapeSequences); - } -} - -static const char *const emptyWordListDesc[] = { - 0 -}; - -LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexHTML.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexHTML.cxx deleted file mode 100644 index bd14534d4..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexHTML.cxx +++ /dev/null @@ -1,2203 +0,0 @@ -// Scintilla source code edit control -/** @file LexHTML.cxx - ** Lexer for HTML. - **/ -// Copyright 1998-2005 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "StringCopy.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -#define SCE_HA_JS (SCE_HJA_START - SCE_HJ_START) -#define SCE_HA_VBS (SCE_HBA_START - SCE_HB_START) -#define SCE_HA_PYTHON (SCE_HPA_START - SCE_HP_START) - -enum script_type { eScriptNone = 0, eScriptJS, eScriptVBS, eScriptPython, eScriptPHP, eScriptXML, eScriptSGML, eScriptSGMLblock, eScriptComment }; -enum script_mode { eHtml = 0, eNonHtmlScript, eNonHtmlPreProc, eNonHtmlScriptPreProc }; - -static inline bool IsAWordChar(const int ch) { - return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); -} - -static inline bool IsAWordStart(const int ch) { - return (ch < 0x80) && (isalnum(ch) || ch == '_'); -} - -inline bool IsOperator(int ch) { - if (IsASCII(ch) && isalnum(ch)) - return false; - // '.' left out as it is used to make up numbers - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; -} - -static void GetTextSegment(Accessor &styler, Sci_PositionU start, Sci_PositionU end, char *s, size_t len) { - Sci_PositionU i = 0; - for (; (i < end - start + 1) && (i < len-1); i++) { - s[i] = static_cast(MakeLowerCase(styler[start + i])); - } - s[i] = '\0'; -} - -static const char *GetNextWord(Accessor &styler, Sci_PositionU start, char *s, size_t sLen) { - - Sci_PositionU i = 0; - for (; i < sLen-1; i++) { - char ch = static_cast(styler.SafeGetCharAt(start + i)); - if ((i == 0) && !IsAWordStart(ch)) - break; - if ((i > 0) && !IsAWordChar(ch)) - break; - s[i] = ch; - } - s[i] = '\0'; - - return s; -} - -static script_type segIsScriptingIndicator(Accessor &styler, Sci_PositionU start, Sci_PositionU end, script_type prevValue) { - char s[100]; - GetTextSegment(styler, start, end, s, sizeof(s)); - //Platform::DebugPrintf("Scripting indicator [%s]\n", s); - if (strstr(s, "src")) // External script - return eScriptNone; - if (strstr(s, "vbs")) - return eScriptVBS; - if (strstr(s, "pyth")) - return eScriptPython; - if (strstr(s, "javas")) - return eScriptJS; - if (strstr(s, "jscr")) - return eScriptJS; - if (strstr(s, "php")) - return eScriptPHP; - if (strstr(s, "xml")) { - const char *xml = strstr(s, "xml"); - for (const char *t=s; t= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { - return eScriptPython; - } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { - return eScriptVBS; - } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { - return eScriptJS; - } else if ((state >= SCE_HPHP_DEFAULT) && (state <= SCE_HPHP_COMMENTLINE)) { - return eScriptPHP; - } else if ((state >= SCE_H_SGML_DEFAULT) && (state < SCE_H_SGML_BLOCK_DEFAULT)) { - return eScriptSGML; - } else if (state == SCE_H_SGML_BLOCK_DEFAULT) { - return eScriptSGMLblock; - } else { - return eScriptNone; - } -} - -static int statePrintForState(int state, script_mode inScriptType) { - int StateToPrint = state; - - if (state >= SCE_HJ_START) { - if ((state >= SCE_HP_START) && (state <= SCE_HP_IDENTIFIER)) { - StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_PYTHON); - } else if ((state >= SCE_HB_START) && (state <= SCE_HB_STRINGEOL)) { - StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_VBS); - } else if ((state >= SCE_HJ_START) && (state <= SCE_HJ_REGEX)) { - StateToPrint = state + ((inScriptType == eNonHtmlScript) ? 0 : SCE_HA_JS); - } - } - - return StateToPrint; -} - -static int stateForPrintState(int StateToPrint) { - int state; - - if ((StateToPrint >= SCE_HPA_START) && (StateToPrint <= SCE_HPA_IDENTIFIER)) { - state = StateToPrint - SCE_HA_PYTHON; - } else if ((StateToPrint >= SCE_HBA_START) && (StateToPrint <= SCE_HBA_STRINGEOL)) { - state = StateToPrint - SCE_HA_VBS; - } else if ((StateToPrint >= SCE_HJA_START) && (StateToPrint <= SCE_HJA_REGEX)) { - state = StateToPrint - SCE_HA_JS; - } else { - state = StateToPrint; - } - - return state; -} - -static inline bool IsNumber(Sci_PositionU start, Accessor &styler) { - return IsADigit(styler[start]) || (styler[start] == '.') || - (styler[start] == '-') || (styler[start] == '#'); -} - -static inline bool isStringState(int state) { - bool bResult; - - switch (state) { - case SCE_HJ_DOUBLESTRING: - case SCE_HJ_SINGLESTRING: - case SCE_HJA_DOUBLESTRING: - case SCE_HJA_SINGLESTRING: - case SCE_HB_STRING: - case SCE_HBA_STRING: - case SCE_HP_STRING: - case SCE_HP_CHARACTER: - case SCE_HP_TRIPLE: - case SCE_HP_TRIPLEDOUBLE: - case SCE_HPA_STRING: - case SCE_HPA_CHARACTER: - case SCE_HPA_TRIPLE: - case SCE_HPA_TRIPLEDOUBLE: - case SCE_HPHP_HSTRING: - case SCE_HPHP_SIMPLESTRING: - case SCE_HPHP_HSTRING_VARIABLE: - case SCE_HPHP_COMPLEX_VARIABLE: - bResult = true; - break; - default : - bResult = false; - break; - } - return bResult; -} - -static inline bool stateAllowsTermination(int state) { - bool allowTermination = !isStringState(state); - if (allowTermination) { - switch (state) { - case SCE_HB_COMMENTLINE: - case SCE_HPHP_COMMENT: - case SCE_HP_COMMENTLINE: - case SCE_HPA_COMMENTLINE: - allowTermination = false; - } - } - return allowTermination; -} - -// not really well done, since it's only comments that should lex the %> and <% -static inline bool isCommentASPState(int state) { - bool bResult; - - switch (state) { - case SCE_HJ_COMMENT: - case SCE_HJ_COMMENTLINE: - case SCE_HJ_COMMENTDOC: - case SCE_HB_COMMENTLINE: - case SCE_HP_COMMENTLINE: - case SCE_HPHP_COMMENT: - case SCE_HPHP_COMMENTLINE: - bResult = true; - break; - default : - bResult = false; - break; - } - return bResult; -} - -static void classifyAttribHTML(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler) { - bool wordIsNumber = IsNumber(start, styler); - char chAttr = SCE_H_ATTRIBUTEUNKNOWN; - if (wordIsNumber) { - chAttr = SCE_H_NUMBER; - } else { - char s[100]; - GetTextSegment(styler, start, end, s, sizeof(s)); - if (keywords.InList(s)) - chAttr = SCE_H_ATTRIBUTE; - } - if ((chAttr == SCE_H_ATTRIBUTEUNKNOWN) && !keywords) - // No keywords -> all are known - chAttr = SCE_H_ATTRIBUTE; - styler.ColourTo(end, chAttr); -} - -static int classifyTagHTML(Sci_PositionU start, Sci_PositionU end, - WordList &keywords, Accessor &styler, bool &tagDontFold, - bool caseSensitive, bool isXml, bool allowScripts) { - char withSpace[30 + 2] = " "; - const char *s = withSpace + 1; - // Copy after the '<' - Sci_PositionU i = 1; - for (Sci_PositionU cPos = start; cPos <= end && i < 30; cPos++) { - char ch = styler[cPos]; - if ((ch != '<') && (ch != '/')) { - withSpace[i++] = caseSensitive ? ch : static_cast(MakeLowerCase(ch)); - } - } - - //The following is only a quick hack, to see if this whole thing would work - //we first need the tagname with a trailing space... - withSpace[i] = ' '; - withSpace[i+1] = '\0'; - - // if the current language is XML, I can fold any tag - // if the current language is HTML, I don't want to fold certain tags (input, meta, etc.) - //...to find it in the list of no-container-tags - tagDontFold = (!isXml) && (NULL != strstr(" area base basefont br col command embed frame hr img input isindex keygen link meta param source track wbr ", withSpace)); - - //now we can remove the trailing space - withSpace[i] = '\0'; - - // No keywords -> all are known - char chAttr = SCE_H_TAGUNKNOWN; - if (s[0] == '!') { - chAttr = SCE_H_SGML_DEFAULT; - } else if (!keywords || keywords.InList(s)) { - chAttr = SCE_H_TAG; - } - styler.ColourTo(end, chAttr); - if (chAttr == SCE_H_TAG) { - if (allowScripts && 0 == strcmp(s, "script")) { - // check to see if this is a self-closing tag by sniffing ahead - bool isSelfClose = false; - for (Sci_PositionU cPos = end; cPos <= end + 200; cPos++) { - char ch = styler.SafeGetCharAt(cPos, '\0'); - if (ch == '\0' || ch == '>') - break; - else if (ch == '/' && styler.SafeGetCharAt(cPos + 1, '\0') == '>') { - isSelfClose = true; - break; - } - } - - // do not enter a script state if the tag self-closed - if (!isSelfClose) - chAttr = SCE_H_SCRIPT; - } else if (!isXml && 0 == strcmp(s, "comment")) { - chAttr = SCE_H_COMMENT; - } - } - return chAttr; -} - -static void classifyWordHTJS(Sci_PositionU start, Sci_PositionU end, - WordList &keywords, Accessor &styler, script_mode inScriptType) { - char s[30 + 1]; - Sci_PositionU i = 0; - for (; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - } - s[i] = '\0'; - - char chAttr = SCE_HJ_WORD; - bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1])); - if (wordIsNumber) { - chAttr = SCE_HJ_NUMBER; - } else if (keywords.InList(s)) { - chAttr = SCE_HJ_KEYWORD; - } - styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); -} - -static int classifyWordHTVB(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler, script_mode inScriptType) { - char chAttr = SCE_HB_IDENTIFIER; - bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.'); - if (wordIsNumber) { - chAttr = SCE_HB_NUMBER; - } else { - char s[100]; - GetTextSegment(styler, start, end, s, sizeof(s)); - if (keywords.InList(s)) { - chAttr = SCE_HB_WORD; - if (strcmp(s, "rem") == 0) - chAttr = SCE_HB_COMMENTLINE; - } - } - styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); - if (chAttr == SCE_HB_COMMENTLINE) - return SCE_HB_COMMENTLINE; - else - return SCE_HB_DEFAULT; -} - -static void classifyWordHTPy(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler, char *prevWord, script_mode inScriptType, bool isMako) { - bool wordIsNumber = IsADigit(styler[start]); - char s[30 + 1]; - Sci_PositionU i = 0; - for (; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - } - s[i] = '\0'; - char chAttr = SCE_HP_IDENTIFIER; - if (0 == strcmp(prevWord, "class")) - chAttr = SCE_HP_CLASSNAME; - else if (0 == strcmp(prevWord, "def")) - chAttr = SCE_HP_DEFNAME; - else if (wordIsNumber) - chAttr = SCE_HP_NUMBER; - else if (keywords.InList(s)) - chAttr = SCE_HP_WORD; - else if (isMako && 0 == strcmp(s, "block")) - chAttr = SCE_HP_WORD; - styler.ColourTo(end, statePrintForState(chAttr, inScriptType)); - strcpy(prevWord, s); -} - -// Update the word colour to default or keyword -// Called when in a PHP word -static void classifyWordHTPHP(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler) { - char chAttr = SCE_HPHP_DEFAULT; - bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.' && start+1 <= end && IsADigit(styler[start+1])); - if (wordIsNumber) { - chAttr = SCE_HPHP_NUMBER; - } else { - char s[100]; - GetTextSegment(styler, start, end, s, sizeof(s)); - if (keywords.InList(s)) - chAttr = SCE_HPHP_WORD; - } - styler.ColourTo(end, chAttr); -} - -static bool isWordHSGML(Sci_PositionU start, Sci_PositionU end, WordList &keywords, Accessor &styler) { - char s[30 + 1]; - Sci_PositionU i = 0; - for (; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - } - s[i] = '\0'; - return keywords.InList(s); -} - -static bool isWordCdata(Sci_PositionU start, Sci_PositionU end, Accessor &styler) { - char s[30 + 1]; - Sci_PositionU i = 0; - for (; i < end - start + 1 && i < 30; i++) { - s[i] = styler[start + i]; - } - s[i] = '\0'; - return (0 == strcmp(s, "[CDATA[")); -} - -// Return the first state to reach when entering a scripting language -static int StateForScript(script_type scriptLanguage) { - int Result; - switch (scriptLanguage) { - case eScriptVBS: - Result = SCE_HB_START; - break; - case eScriptPython: - Result = SCE_HP_START; - break; - case eScriptPHP: - Result = SCE_HPHP_DEFAULT; - break; - case eScriptXML: - Result = SCE_H_TAGUNKNOWN; - break; - case eScriptSGML: - Result = SCE_H_SGML_DEFAULT; - break; - case eScriptComment: - Result = SCE_H_COMMENT; - break; - default : - Result = SCE_HJ_START; - break; - } - return Result; -} - -static inline bool issgmlwordchar(int ch) { - return !IsASCII(ch) || - (isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '['); -} - -static inline bool IsPhpWordStart(int ch) { - return (IsASCII(ch) && (isalpha(ch) || (ch == '_'))) || (ch >= 0x7f); -} - -static inline bool IsPhpWordChar(int ch) { - return IsADigit(ch) || IsPhpWordStart(ch); -} - -static bool InTagState(int state) { - return state == SCE_H_TAG || state == SCE_H_TAGUNKNOWN || - state == SCE_H_SCRIPT || - state == SCE_H_ATTRIBUTE || state == SCE_H_ATTRIBUTEUNKNOWN || - state == SCE_H_NUMBER || state == SCE_H_OTHER || - state == SCE_H_DOUBLESTRING || state == SCE_H_SINGLESTRING; -} - -static bool IsCommentState(const int state) { - return state == SCE_H_COMMENT || state == SCE_H_SGML_COMMENT; -} - -static bool IsScriptCommentState(const int state) { - return state == SCE_HJ_COMMENT || state == SCE_HJ_COMMENTLINE || state == SCE_HJA_COMMENT || - state == SCE_HJA_COMMENTLINE || state == SCE_HB_COMMENTLINE || state == SCE_HBA_COMMENTLINE; -} - -static bool isLineEnd(int ch) { - return ch == '\r' || ch == '\n'; -} - -static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) { - if (strlen(blockType) == 0) { - return ((ch == '%') && (chNext == '>')); - } else if ((0 == strcmp(blockType, "inherit")) || - (0 == strcmp(blockType, "namespace")) || - (0 == strcmp(blockType, "include")) || - (0 == strcmp(blockType, "page"))) { - return ((ch == '/') && (chNext == '>')); - } else if (0 == strcmp(blockType, "%")) { - if (ch == '/' && isLineEnd(chNext)) - return 1; - else - return isLineEnd(ch); - } else if (0 == strcmp(blockType, "{")) { - return ch == '}'; - } else { - return (ch == '>'); - } -} - -static bool isDjangoBlockEnd(const int ch, const int chNext, const char *blockType) { - if (strlen(blockType) == 0) { - return 0; - } else if (0 == strcmp(blockType, "%")) { - return ((ch == '%') && (chNext == '}')); - } else if (0 == strcmp(blockType, "{")) { - return ((ch == '}') && (chNext == '}')); - } else { - return 0; - } -} - -static bool isPHPStringState(int state) { - return - (state == SCE_HPHP_HSTRING) || - (state == SCE_HPHP_SIMPLESTRING) || - (state == SCE_HPHP_HSTRING_VARIABLE) || - (state == SCE_HPHP_COMPLEX_VARIABLE); -} - -static Sci_Position FindPhpStringDelimiter(char *phpStringDelimiter, const int phpStringDelimiterSize, Sci_Position i, const Sci_Position lengthDoc, Accessor &styler, bool &isSimpleString) { - Sci_Position j; - const Sci_Position beginning = i - 1; - bool isValidSimpleString = false; - - while (i < lengthDoc && (styler[i] == ' ' || styler[i] == '\t')) - i++; - - char ch = styler.SafeGetCharAt(i); - const char chNext = styler.SafeGetCharAt(i + 1); - if (!IsPhpWordStart(ch)) { - if (ch == '\'' && IsPhpWordStart(chNext)) { - i++; - ch = chNext; - isSimpleString = true; - } else { - phpStringDelimiter[0] = '\0'; - return beginning; - } - } - phpStringDelimiter[0] = ch; - i++; - - for (j = i; j < lengthDoc && !isLineEnd(styler[j]); j++) { - if (!IsPhpWordChar(styler[j])) { - if (isSimpleString && (styler[j] == '\'') && isLineEnd(styler.SafeGetCharAt(j + 1))) { - isValidSimpleString = true; - j++; - break; - } else { - phpStringDelimiter[0] = '\0'; - return beginning; - } - } - if (j - i < phpStringDelimiterSize - 2) - phpStringDelimiter[j-i+1] = styler[j]; - else - i++; - } - if (isSimpleString && !isValidSimpleString) { - phpStringDelimiter[0] = '\0'; - return beginning; - } - phpStringDelimiter[j-i+1 - (isSimpleString ? 1 : 0)] = '\0'; - return j - 1; -} - -static void ColouriseHyperTextDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], - Accessor &styler, bool isXml) { - WordList &keywords = *keywordlists[0]; - WordList &keywords2 = *keywordlists[1]; - WordList &keywords3 = *keywordlists[2]; - WordList &keywords4 = *keywordlists[3]; - WordList &keywords5 = *keywordlists[4]; - WordList &keywords6 = *keywordlists[5]; // SGML (DTD) keywords - - styler.StartAt(startPos); - char prevWord[200]; - prevWord[0] = '\0'; - char phpStringDelimiter[200]; // PHP is not limited in length, we are - phpStringDelimiter[0] = '\0'; - int StateToPrint = initStyle; - int state = stateForPrintState(StateToPrint); - char makoBlockType[200]; - makoBlockType[0] = '\0'; - int makoComment = 0; - char djangoBlockType[2]; - djangoBlockType[0] = '\0'; - - // If inside a tag, it may be a script tag, so reread from the start of line starting tag to ensure any language tags are seen - if (InTagState(state)) { - while ((startPos > 0) && (InTagState(styler.StyleAt(startPos - 1)))) { - Sci_Position backLineStart = styler.LineStart(styler.GetLine(startPos-1)); - length += startPos - backLineStart; - startPos = backLineStart; - } - state = SCE_H_DEFAULT; - } - // String can be heredoc, must find a delimiter first. Reread from beginning of line containing the string, to get the correct lineState - if (isPHPStringState(state)) { - while (startPos > 0 && (isPHPStringState(state) || !isLineEnd(styler[startPos - 1]))) { - startPos--; - length++; - state = styler.StyleAt(startPos); - } - if (startPos == 0) - state = SCE_H_DEFAULT; - } - styler.StartAt(startPos); - - /* Nothing handles getting out of these, so we need not start in any of them. - * As we're at line start and they can't span lines, we'll re-detect them anyway */ - switch (state) { - case SCE_H_QUESTION: - case SCE_H_XMLSTART: - case SCE_H_XMLEND: - case SCE_H_ASP: - state = SCE_H_DEFAULT; - break; - } - - Sci_Position lineCurrent = styler.GetLine(startPos); - int lineState; - if (lineCurrent > 0) { - lineState = styler.GetLineState(lineCurrent-1); - } else { - // Default client and ASP scripting language is JavaScript - lineState = eScriptJS << 8; - - // property asp.default.language - // Script in ASP code is initially assumed to be in JavaScript. - // To change this to VBScript set asp.default.language to 2. Python is 3. - lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4; - } - script_mode inScriptType = script_mode((lineState >> 0) & 0x03); // 2 bits of scripting mode - bool tagOpened = (lineState >> 2) & 0x01; // 1 bit to know if we are in an opened tag - bool tagClosing = (lineState >> 3) & 0x01; // 1 bit to know if we are in a closing tag - bool tagDontFold = false; //some HTML tags should not be folded - script_type aspScript = script_type((lineState >> 4) & 0x0F); // 4 bits of script name - script_type clientScript = script_type((lineState >> 8) & 0x0F); // 4 bits of script name - int beforePreProc = (lineState >> 12) & 0xFF; // 8 bits of state - - script_type scriptLanguage = ScriptOfState(state); - // If eNonHtmlScript coincides with SCE_H_COMMENT, assume eScriptComment - if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) { - scriptLanguage = eScriptComment; - } - script_type beforeLanguage = ScriptOfState(beforePreProc); - - // property fold.html - // Folding is turned on or off for HTML and XML files with this option. - // The fold option must also be on for folding to occur. - const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0; - - const bool fold = foldHTML && styler.GetPropertyInt("fold", 0); - - // property fold.html.preprocessor - // Folding is turned on or off for scripts embedded in HTML files with this option. - // The default is on. - const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1); - - const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; - - // property fold.hypertext.comment - // Allow folding for comments in scripts embedded in HTML. - // The default is off. - const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0; - - // property fold.hypertext.heredoc - // Allow folding for heredocs in scripts embedded in HTML. - // The default is off. - const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0; - - // property html.tags.case.sensitive - // For XML and HTML, setting this property to 1 will make tags match in a case - // sensitive way which is the expected behaviour for XML and XHTML. - const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0; - - // property lexer.xml.allow.scripts - // Set to 0 to disable scripts in XML. - const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0; - - // property lexer.html.mako - // Set to 1 to enable the mako template language. - const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0; - - // property lexer.html.django - // Set to 1 to enable the django template language. - const bool isDjango = styler.GetPropertyInt("lexer.html.django", 0) != 0; - - const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true); - const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true); - const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true); - // TODO: also handle + and - (except if they're part of ++ or --) and return keywords - const CharacterSet setOKBeforeJSRE(CharacterSet::setNone, "([{=,:;!%^&*|?~"); - - int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; - int levelCurrent = levelPrev; - int visibleChars = 0; - int lineStartVisibleChars = 0; - - int chPrev = ' '; - int ch = ' '; - int chPrevNonWhite = ' '; - // look back to set chPrevNonWhite properly for better regex colouring - if (scriptLanguage == eScriptJS && startPos > 0) { - Sci_Position back = startPos; - int style = 0; - while (--back) { - style = styler.StyleAt(back); - if (style < SCE_HJ_DEFAULT || style > SCE_HJ_COMMENTDOC) - // includes SCE_HJ_COMMENT & SCE_HJ_COMMENTLINE - break; - } - if (style == SCE_HJ_SYMBOLS) { - chPrevNonWhite = static_cast(styler.SafeGetCharAt(back)); - } - } - - styler.StartSegment(startPos); - const Sci_Position lengthDoc = startPos + length; - for (Sci_Position i = startPos; i < lengthDoc; i++) { - const int chPrev2 = chPrev; - chPrev = ch; - if (!IsASpace(ch) && state != SCE_HJ_COMMENT && - state != SCE_HJ_COMMENTLINE && state != SCE_HJ_COMMENTDOC) - chPrevNonWhite = ch; - ch = static_cast(styler[i]); - int chNext = static_cast(styler.SafeGetCharAt(i + 1)); - const int chNext2 = static_cast(styler.SafeGetCharAt(i + 2)); - - // Handle DBCS codepages - if (styler.IsLeadByte(static_cast(ch))) { - chPrev = ' '; - i += 1; - continue; - } - - if ((!IsASpace(ch) || !foldCompact) && fold) - visibleChars++; - if (!IsASpace(ch)) - lineStartVisibleChars++; - - // decide what is the current state to print (depending of the script tag) - StateToPrint = statePrintForState(state, inScriptType); - - // handle script folding - if (fold) { - switch (scriptLanguage) { - case eScriptJS: - case eScriptPHP: - //not currently supported case eScriptVBS: - - if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) { - //Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle); - //if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) { - if (ch == '#') { - Sci_Position j = i + 1; - while ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) { - j++; - } - if (styler.Match(j, "region") || styler.Match(j, "if")) { - levelCurrent++; - } else if (styler.Match(j, "end")) { - levelCurrent--; - } - } else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) { - levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1); - } - } else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) { - levelCurrent--; - } - break; - case eScriptPython: - if (state != SCE_HP_COMMENTLINE && !isMako) { - if ((ch == ':') && ((chNext == '\n') || (chNext == '\r' && chNext2 == '\n'))) { - levelCurrent++; - } else if ((ch == '\n') && !((chNext == '\r') && (chNext2 == '\n')) && (chNext != '\n')) { - // check if the number of tabs is lower than the level - int Findlevel = (levelCurrent & ~SC_FOLDLEVELBASE) * 8; - for (Sci_Position j = 0; Findlevel > 0; j++) { - char chTmp = styler.SafeGetCharAt(i + j + 1); - if (chTmp == '\t') { - Findlevel -= 8; - } else if (chTmp == ' ') { - Findlevel--; - } else { - break; - } - } - - if (Findlevel > 0) { - levelCurrent -= Findlevel / 8; - if (Findlevel % 8) - levelCurrent--; - } - } - } - break; - default: - break; - } - } - - if ((ch == '\r' && chNext != '\n') || (ch == '\n')) { - // Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix) - // Avoid triggering two times on Dos/Win - // New line -> record any line state onto /next/ line - if (fold) { - int lev = levelPrev; - if (visibleChars == 0) - lev |= SC_FOLDLEVELWHITEFLAG; - if ((levelCurrent > levelPrev) && (visibleChars > 0)) - lev |= SC_FOLDLEVELHEADERFLAG; - - styler.SetLevel(lineCurrent, lev); - visibleChars = 0; - levelPrev = levelCurrent; - } - styler.SetLineState(lineCurrent, - ((inScriptType & 0x03) << 0) | - ((tagOpened ? 1 : 0) << 2) | - ((tagClosing ? 1 : 0) << 3) | - ((aspScript & 0x0F) << 4) | - ((clientScript & 0x0F) << 8) | - ((beforePreProc & 0xFF) << 12)); - lineCurrent++; - lineStartVisibleChars = 0; - } - - // handle start of Mako comment line - if (isMako && ch == '#' && chNext == '#') { - makoComment = 1; - state = SCE_HP_COMMENTLINE; - } - - // handle end of Mako comment line - else if (isMako && makoComment && (ch == '\r' || ch == '\n')) { - makoComment = 0; - styler.ColourTo(i - 1, StateToPrint); - if (scriptLanguage == eScriptPython) { - state = SCE_HP_DEFAULT; - } else { - state = SCE_H_DEFAULT; - } - } - - // Allow falling through to mako handling code if newline is going to end a block - if (((ch == '\r' && chNext != '\n') || (ch == '\n')) && - (!isMako || (0 != strcmp(makoBlockType, "%")))) { - } - // Ignore everything in mako comment until the line ends - else if (isMako && makoComment) { - } - - // generic end of script processing - else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) { - // Check if it's the end of the script tag (or any other HTML tag) - switch (state) { - // in these cases, you can embed HTML tags (to confirm !!!!!!!!!!!!!!!!!!!!!!) - case SCE_H_DOUBLESTRING: - case SCE_H_SINGLESTRING: - case SCE_HJ_COMMENT: - case SCE_HJ_COMMENTDOC: - //case SCE_HJ_COMMENTLINE: // removed as this is a common thing done to hide - // the end of script marker from some JS interpreters. - case SCE_HB_COMMENTLINE: - case SCE_HBA_COMMENTLINE: - case SCE_HJ_DOUBLESTRING: - case SCE_HJ_SINGLESTRING: - case SCE_HJ_REGEX: - case SCE_HB_STRING: - case SCE_HBA_STRING: - case SCE_HP_STRING: - case SCE_HP_TRIPLE: - case SCE_HP_TRIPLEDOUBLE: - case SCE_HPHP_HSTRING: - case SCE_HPHP_SIMPLESTRING: - case SCE_HPHP_COMMENT: - case SCE_HPHP_COMMENTLINE: - break; - default : - // check if the closing tag is a script tag - if (const char *tag = - state == SCE_HJ_COMMENTLINE || isXml ? "script" : - state == SCE_H_COMMENT ? "comment" : 0) { - Sci_Position j = i + 2; - int chr; - do { - chr = static_cast(*tag++); - } while (chr != 0 && chr == MakeLowerCase(styler.SafeGetCharAt(j++))); - if (chr != 0) break; - } - // closing tag of the script (it's a closing HTML tag anyway) - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_TAGUNKNOWN; - inScriptType = eHtml; - scriptLanguage = eScriptNone; - clientScript = eScriptJS; - i += 2; - visibleChars += 2; - tagClosing = true; - continue; - } - } - - ///////////////////////////////////// - // handle the start of PHP pre-processor = Non-HTML - else if ((state != SCE_H_ASPAT) && - !isStringState(state) && - (state != SCE_HPHP_COMMENT) && - (state != SCE_HPHP_COMMENTLINE) && - (ch == '<') && - (chNext == '?') && - !IsScriptCommentState(state)) { - beforeLanguage = scriptLanguage; - scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML : eScriptPHP); - if ((scriptLanguage != eScriptPHP) && (isStringState(state) || (state==SCE_H_COMMENT))) continue; - styler.ColourTo(i - 1, StateToPrint); - beforePreProc = state; - i++; - visibleChars++; - i += PrintScriptingIndicatorOffset(styler, styler.GetStartSegment() + 2, i + 6); - if (scriptLanguage == eScriptXML) - styler.ColourTo(i, SCE_H_XMLSTART); - else - styler.ColourTo(i, SCE_H_QUESTION); - state = StateForScript(scriptLanguage); - if (inScriptType == eNonHtmlScript) - inScriptType = eNonHtmlScriptPreProc; - else - inScriptType = eNonHtmlPreProc; - // Fold whole script, but not if the XML first tag (all XML-like tags in this case) - if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { - levelCurrent++; - } - // should be better - ch = static_cast(styler.SafeGetCharAt(i)); - continue; - } - - // handle the start Mako template Python code - else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') || - (lineStartVisibleChars == 1 && ch == '%') || - (lineStartVisibleChars == 1 && ch == '/' && chNext == '%') || - (ch == '$' && chNext == '{') || - (ch == '<' && chNext == '/' && chNext2 == '%'))) { - if (ch == '%' || ch == '/') - StringCopy(makoBlockType, "%"); - else if (ch == '$') - StringCopy(makoBlockType, "{"); - else if (chNext == '/') - GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType)); - else - GetNextWord(styler, i+2, makoBlockType, sizeof(makoBlockType)); - styler.ColourTo(i - 1, StateToPrint); - beforePreProc = state; - if (inScriptType == eNonHtmlScript) - inScriptType = eNonHtmlScriptPreProc; - else - inScriptType = eNonHtmlPreProc; - - if (chNext == '/') { - i += 2; - visibleChars += 2; - } else if (ch != '%') { - i++; - visibleChars++; - } - state = SCE_HP_START; - scriptLanguage = eScriptPython; - styler.ColourTo(i, SCE_H_ASP); - - if (ch != '%' && ch != '$' && ch != '/') { - i += static_cast(strlen(makoBlockType)); - visibleChars += static_cast(strlen(makoBlockType)); - if (keywords4.InList(makoBlockType)) - styler.ColourTo(i, SCE_HP_WORD); - else - styler.ColourTo(i, SCE_H_TAGUNKNOWN); - } - - ch = static_cast(styler.SafeGetCharAt(i)); - continue; - } - - // handle the start/end of Django comment - else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) { - styler.ColourTo(i - 1, StateToPrint); - beforePreProc = state; - beforeLanguage = scriptLanguage; - if (inScriptType == eNonHtmlScript) - inScriptType = eNonHtmlScriptPreProc; - else - inScriptType = eNonHtmlPreProc; - i += 1; - visibleChars += 1; - scriptLanguage = eScriptComment; - state = SCE_H_COMMENT; - styler.ColourTo(i, SCE_H_ASP); - ch = static_cast(styler.SafeGetCharAt(i)); - continue; - } else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) { - styler.ColourTo(i - 1, StateToPrint); - i += 1; - visibleChars += 1; - styler.ColourTo(i, SCE_H_ASP); - state = beforePreProc; - if (inScriptType == eNonHtmlScriptPreProc) - inScriptType = eNonHtmlScript; - else - inScriptType = eHtml; - scriptLanguage = beforeLanguage; - continue; - } - - // handle the start Django template code - else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) { - if (chNext == '%') - StringCopy(djangoBlockType, "%"); - else - StringCopy(djangoBlockType, "{"); - styler.ColourTo(i - 1, StateToPrint); - beforePreProc = state; - if (inScriptType == eNonHtmlScript) - inScriptType = eNonHtmlScriptPreProc; - else - inScriptType = eNonHtmlPreProc; - - i += 1; - visibleChars += 1; - state = SCE_HP_START; - beforeLanguage = scriptLanguage; - scriptLanguage = eScriptPython; - styler.ColourTo(i, SCE_H_ASP); - - ch = static_cast(styler.SafeGetCharAt(i)); - continue; - } - - // handle the start of ASP pre-processor = Non-HTML - else if (!isMako && !isDjango && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) { - styler.ColourTo(i - 1, StateToPrint); - beforePreProc = state; - if (inScriptType == eNonHtmlScript) - inScriptType = eNonHtmlScriptPreProc; - else - inScriptType = eNonHtmlPreProc; - - if (chNext2 == '@') { - i += 2; // place as if it was the second next char treated - visibleChars += 2; - state = SCE_H_ASPAT; - } else if ((chNext2 == '-') && (styler.SafeGetCharAt(i + 3) == '-')) { - styler.ColourTo(i + 3, SCE_H_ASP); - state = SCE_H_XCCOMMENT; - scriptLanguage = eScriptVBS; - continue; - } else { - if (chNext2 == '=') { - i += 2; // place as if it was the second next char treated - visibleChars += 2; - } else { - i++; // place as if it was the next char treated - visibleChars++; - } - - state = StateForScript(aspScript); - } - scriptLanguage = eScriptVBS; - styler.ColourTo(i, SCE_H_ASP); - // fold whole script - if (foldHTMLPreprocessor) - levelCurrent++; - // should be better - ch = static_cast(styler.SafeGetCharAt(i)); - continue; - } - - ///////////////////////////////////// - // handle the start of SGML language (DTD) - else if (((scriptLanguage == eScriptNone) || (scriptLanguage == eScriptXML)) && - (chPrev == '<') && - (ch == '!') && - (StateToPrint != SCE_H_CDATA) && - (!IsCommentState(StateToPrint)) && - (!IsScriptCommentState(StateToPrint))) { - beforePreProc = state; - styler.ColourTo(i - 2, StateToPrint); - if ((chNext == '-') && (chNext2 == '-')) { - state = SCE_H_COMMENT; // wait for a pending command - styler.ColourTo(i + 2, SCE_H_COMMENT); - i += 2; // follow styling after the -- - } else if (isWordCdata(i + 1, i + 7, styler)) { - state = SCE_H_CDATA; - } else { - styler.ColourTo(i, SCE_H_SGML_DEFAULT); // ') { - i++; - visibleChars++; - } - else if (0 == strcmp(makoBlockType, "%") && ch == '/') { - i++; - visibleChars++; - } - if (0 != strcmp(makoBlockType, "%") || ch == '/') { - styler.ColourTo(i, SCE_H_ASP); - } - state = beforePreProc; - if (inScriptType == eNonHtmlScriptPreProc) - inScriptType = eNonHtmlScript; - else - inScriptType = eHtml; - scriptLanguage = eScriptNone; - continue; - } - - // handle the end of Django template code - else if (isDjango && - ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && - (scriptLanguage != eScriptNone) && stateAllowsTermination(state) && - isDjangoBlockEnd(ch, chNext, djangoBlockType)) { - if (state == SCE_H_ASPAT) { - aspScript = segIsScriptingIndicator(styler, - styler.GetStartSegment(), i - 1, aspScript); - } - if (state == SCE_HP_WORD) { - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); - } else { - styler.ColourTo(i - 1, StateToPrint); - } - i += 1; - visibleChars += 1; - styler.ColourTo(i, SCE_H_ASP); - state = beforePreProc; - if (inScriptType == eNonHtmlScriptPreProc) - inScriptType = eNonHtmlScript; - else - inScriptType = eHtml; - scriptLanguage = beforeLanguage; - continue; - } - - // handle the end of a pre-processor = Non-HTML - else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) && - (((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) && - (((ch == '%') || (ch == '?')) && (chNext == '>'))) || - ((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) { - if (state == SCE_H_ASPAT) { - aspScript = segIsScriptingIndicator(styler, - styler.GetStartSegment(), i - 1, aspScript); - } - // Bounce out of any ASP mode - switch (state) { - case SCE_HJ_WORD: - classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); - break; - case SCE_HB_WORD: - classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); - break; - case SCE_HP_WORD: - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); - break; - case SCE_HPHP_WORD: - classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); - break; - case SCE_H_XCCOMMENT: - styler.ColourTo(i - 1, state); - break; - default : - styler.ColourTo(i - 1, StateToPrint); - break; - } - if (scriptLanguage != eScriptSGML) { - i++; - visibleChars++; - } - if (ch == '%') - styler.ColourTo(i, SCE_H_ASP); - else if (scriptLanguage == eScriptXML) - styler.ColourTo(i, SCE_H_XMLEND); - else if (scriptLanguage == eScriptSGML) - styler.ColourTo(i, SCE_H_SGML_DEFAULT); - else - styler.ColourTo(i, SCE_H_QUESTION); - state = beforePreProc; - if (inScriptType == eNonHtmlScriptPreProc) - inScriptType = eNonHtmlScript; - else - inScriptType = eHtml; - // Unfold all scripting languages, except for XML tag - if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) { - levelCurrent--; - } - scriptLanguage = beforeLanguage; - continue; - } - ///////////////////////////////////// - - switch (state) { - case SCE_H_DEFAULT: - if (ch == '<') { - // in HTML, fold on tag open and unfold on tag close - tagOpened = true; - tagClosing = (chNext == '/'); - styler.ColourTo(i - 1, StateToPrint); - if (chNext != '!') - state = SCE_H_TAGUNKNOWN; - } else if (ch == '&') { - styler.ColourTo(i - 1, SCE_H_DEFAULT); - state = SCE_H_ENTITY; - } - break; - case SCE_H_SGML_DEFAULT: - case SCE_H_SGML_BLOCK_DEFAULT: -// if (scriptLanguage == eScriptSGMLblock) -// StateToPrint = SCE_H_SGML_BLOCK_DEFAULT; - - if (ch == '\"') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_SGML_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_SGML_SIMPLESTRING; - } else if ((ch == '-') && (chPrev == '-')) { - if (static_cast(styler.GetStartSegment()) <= (i - 2)) { - styler.ColourTo(i - 2, StateToPrint); - } - state = SCE_H_SGML_COMMENT; - } else if (IsASCII(ch) && isalpha(ch) && (chPrev == '%')) { - styler.ColourTo(i - 2, StateToPrint); - state = SCE_H_SGML_ENTITY; - } else if (ch == '#') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_SGML_SPECIAL; - } else if (ch == '[') { - styler.ColourTo(i - 1, StateToPrint); - scriptLanguage = eScriptSGMLblock; - state = SCE_H_SGML_BLOCK_DEFAULT; - } else if (ch == ']') { - if (scriptLanguage == eScriptSGMLblock) { - styler.ColourTo(i, StateToPrint); - scriptLanguage = eScriptSGML; - } else { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i, SCE_H_SGML_ERROR); - } - state = SCE_H_SGML_DEFAULT; - } else if (scriptLanguage == eScriptSGMLblock) { - if ((ch == '!') && (chPrev == '<')) { - styler.ColourTo(i - 2, StateToPrint); - styler.ColourTo(i, SCE_H_SGML_DEFAULT); - state = SCE_H_SGML_COMMAND; - } else if (ch == '>') { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i, SCE_H_SGML_DEFAULT); - } - } - break; - case SCE_H_SGML_COMMAND: - if ((ch == '-') && (chPrev == '-')) { - styler.ColourTo(i - 2, StateToPrint); - state = SCE_H_SGML_COMMENT; - } else if (!issgmlwordchar(ch)) { - if (isWordHSGML(styler.GetStartSegment(), i - 1, keywords6, styler)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_SGML_1ST_PARAM; - } else { - state = SCE_H_SGML_ERROR; - } - } - break; - case SCE_H_SGML_1ST_PARAM: - // wait for the beginning of the word - if ((ch == '-') && (chPrev == '-')) { - if (scriptLanguage == eScriptSGMLblock) { - styler.ColourTo(i - 2, SCE_H_SGML_BLOCK_DEFAULT); - } else { - styler.ColourTo(i - 2, SCE_H_SGML_DEFAULT); - } - state = SCE_H_SGML_1ST_PARAM_COMMENT; - } else if (issgmlwordchar(ch)) { - if (scriptLanguage == eScriptSGMLblock) { - styler.ColourTo(i - 1, SCE_H_SGML_BLOCK_DEFAULT); - } else { - styler.ColourTo(i - 1, SCE_H_SGML_DEFAULT); - } - // find the length of the word - int size = 1; - while (setHTMLWord.Contains(static_cast(styler.SafeGetCharAt(i + size)))) - size++; - styler.ColourTo(i + size - 1, StateToPrint); - i += size - 1; - visibleChars += size - 1; - ch = static_cast(styler.SafeGetCharAt(i)); - if (scriptLanguage == eScriptSGMLblock) { - state = SCE_H_SGML_BLOCK_DEFAULT; - } else { - state = SCE_H_SGML_DEFAULT; - } - continue; - } - break; - case SCE_H_SGML_ERROR: - if ((ch == '-') && (chPrev == '-')) { - styler.ColourTo(i - 2, StateToPrint); - state = SCE_H_SGML_COMMENT; - } - break; - case SCE_H_SGML_DOUBLESTRING: - if (ch == '\"') { - styler.ColourTo(i, StateToPrint); - state = SCE_H_SGML_DEFAULT; - } - break; - case SCE_H_SGML_SIMPLESTRING: - if (ch == '\'') { - styler.ColourTo(i, StateToPrint); - state = SCE_H_SGML_DEFAULT; - } - break; - case SCE_H_SGML_COMMENT: - if ((ch == '-') && (chPrev == '-')) { - styler.ColourTo(i, StateToPrint); - state = SCE_H_SGML_DEFAULT; - } - break; - case SCE_H_CDATA: - if ((chPrev2 == ']') && (chPrev == ']') && (ch == '>')) { - styler.ColourTo(i, StateToPrint); - state = SCE_H_DEFAULT; - levelCurrent--; - } - break; - case SCE_H_COMMENT: - if ((scriptLanguage != eScriptComment) && (chPrev2 == '-') && (chPrev == '-') && (ch == '>')) { - styler.ColourTo(i, StateToPrint); - state = SCE_H_DEFAULT; - levelCurrent--; - } - break; - case SCE_H_SGML_1ST_PARAM_COMMENT: - if ((ch == '-') && (chPrev == '-')) { - styler.ColourTo(i, SCE_H_SGML_COMMENT); - state = SCE_H_SGML_1ST_PARAM; - } - break; - case SCE_H_SGML_SPECIAL: - if (!(IsASCII(ch) && isupper(ch))) { - styler.ColourTo(i - 1, StateToPrint); - if (isalnum(ch)) { - state = SCE_H_SGML_ERROR; - } else { - state = SCE_H_SGML_DEFAULT; - } - } - break; - case SCE_H_SGML_ENTITY: - if (ch == ';') { - styler.ColourTo(i, StateToPrint); - state = SCE_H_SGML_DEFAULT; - } else if (!(IsASCII(ch) && isalnum(ch)) && ch != '-' && ch != '.') { - styler.ColourTo(i, SCE_H_SGML_ERROR); - state = SCE_H_SGML_DEFAULT; - } - break; - case SCE_H_ENTITY: - if (ch == ';') { - styler.ColourTo(i, StateToPrint); - state = SCE_H_DEFAULT; - } - if (ch != '#' && !(IsASCII(ch) && isalnum(ch)) // Should check that '#' follows '&', but it is unlikely anyway... - && ch != '.' && ch != '-' && ch != '_' && ch != ':') { // valid in XML - if (!IsASCII(ch)) // Possibly start of a multibyte character so don't allow this byte to be in entity style - styler.ColourTo(i-1, SCE_H_TAGUNKNOWN); - else - styler.ColourTo(i, SCE_H_TAGUNKNOWN); - state = SCE_H_DEFAULT; - } - break; - case SCE_H_TAGUNKNOWN: - if (!setTagContinue.Contains(ch) && !((ch == '/') && (chPrev == '<'))) { - int eClass = classifyTagHTML(styler.GetStartSegment(), - i - 1, keywords, styler, tagDontFold, caseSensitive, isXml, allowScripts); - if (eClass == SCE_H_SCRIPT || eClass == SCE_H_COMMENT) { - if (!tagClosing) { - inScriptType = eNonHtmlScript; - scriptLanguage = eClass == SCE_H_SCRIPT ? clientScript : eScriptComment; - } else { - scriptLanguage = eScriptNone; - } - eClass = SCE_H_TAG; - } - if (ch == '>') { - styler.ColourTo(i, eClass); - if (inScriptType == eNonHtmlScript) { - state = StateForScript(scriptLanguage); - } else { - state = SCE_H_DEFAULT; - } - tagOpened = false; - if (!tagDontFold) { - if (tagClosing) { - levelCurrent--; - } else { - levelCurrent++; - } - } - tagClosing = false; - } else if (ch == '/' && chNext == '>') { - if (eClass == SCE_H_TAGUNKNOWN) { - styler.ColourTo(i + 1, SCE_H_TAGUNKNOWN); - } else { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i + 1, SCE_H_TAGEND); - } - i++; - ch = chNext; - state = SCE_H_DEFAULT; - tagOpened = false; - } else { - if (eClass != SCE_H_TAGUNKNOWN) { - if (eClass == SCE_H_SGML_DEFAULT) { - state = SCE_H_SGML_DEFAULT; - } else { - state = SCE_H_OTHER; - } - } - } - } - break; - case SCE_H_ATTRIBUTE: - if (!setAttributeContinue.Contains(ch)) { - if (inScriptType == eNonHtmlScript) { - int scriptLanguagePrev = scriptLanguage; - clientScript = segIsScriptingIndicator(styler, styler.GetStartSegment(), i - 1, scriptLanguage); - scriptLanguage = clientScript; - if ((scriptLanguagePrev != scriptLanguage) && (scriptLanguage == eScriptNone)) - inScriptType = eHtml; - } - classifyAttribHTML(styler.GetStartSegment(), i - 1, keywords, styler); - if (ch == '>') { - styler.ColourTo(i, SCE_H_TAG); - if (inScriptType == eNonHtmlScript) { - state = StateForScript(scriptLanguage); - } else { - state = SCE_H_DEFAULT; - } - tagOpened = false; - if (!tagDontFold) { - if (tagClosing) { - levelCurrent--; - } else { - levelCurrent++; - } - } - tagClosing = false; - } else if (ch == '=') { - styler.ColourTo(i, SCE_H_OTHER); - state = SCE_H_VALUE; - } else { - state = SCE_H_OTHER; - } - } - break; - case SCE_H_OTHER: - if (ch == '>') { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i, SCE_H_TAG); - if (inScriptType == eNonHtmlScript) { - state = StateForScript(scriptLanguage); - } else { - state = SCE_H_DEFAULT; - } - tagOpened = false; - if (!tagDontFold) { - if (tagClosing) { - levelCurrent--; - } else { - levelCurrent++; - } - } - tagClosing = false; - } else if (ch == '\"') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_SINGLESTRING; - } else if (ch == '=') { - styler.ColourTo(i, StateToPrint); - state = SCE_H_VALUE; - } else if (ch == '/' && chNext == '>') { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i + 1, SCE_H_TAGEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - tagOpened = false; - } else if (ch == '?' && chNext == '>') { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i + 1, SCE_H_XMLEND); - i++; - ch = chNext; - state = SCE_H_DEFAULT; - } else if (setHTMLWord.Contains(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_H_ATTRIBUTE; - } - break; - case SCE_H_DOUBLESTRING: - if (ch == '\"') { - if (inScriptType == eNonHtmlScript) { - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); - } - styler.ColourTo(i, SCE_H_DOUBLESTRING); - state = SCE_H_OTHER; - } - break; - case SCE_H_SINGLESTRING: - if (ch == '\'') { - if (inScriptType == eNonHtmlScript) { - scriptLanguage = segIsScriptingIndicator(styler, styler.GetStartSegment(), i, scriptLanguage); - } - styler.ColourTo(i, SCE_H_SINGLESTRING); - state = SCE_H_OTHER; - } - break; - case SCE_H_VALUE: - if (!setHTMLWord.Contains(ch)) { - if (ch == '\"' && chPrev == '=') { - // Should really test for being first character - state = SCE_H_DOUBLESTRING; - } else if (ch == '\'' && chPrev == '=') { - state = SCE_H_SINGLESTRING; - } else { - if (IsNumber(styler.GetStartSegment(), styler)) { - styler.ColourTo(i - 1, SCE_H_NUMBER); - } else { - styler.ColourTo(i - 1, StateToPrint); - } - if (ch == '>') { - styler.ColourTo(i, SCE_H_TAG); - if (inScriptType == eNonHtmlScript) { - state = StateForScript(scriptLanguage); - } else { - state = SCE_H_DEFAULT; - } - tagOpened = false; - if (!tagDontFold) { - if (tagClosing) { - levelCurrent--; - } else { - levelCurrent++; - } - } - tagClosing = false; - } else { - state = SCE_H_OTHER; - } - } - } - break; - case SCE_HJ_DEFAULT: - case SCE_HJ_START: - case SCE_HJ_SYMBOLS: - if (IsAWordStart(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_WORD; - } else if (ch == '/' && chNext == '*') { - styler.ColourTo(i - 1, StateToPrint); - if (chNext2 == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - if (chNext2 == '/') { - // Eat the * so it isn't used for the end of the comment - i++; - } - } else if (ch == '/' && chNext == '/') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - } else if (ch == '/' && setOKBeforeJSRE.Contains(chPrevNonWhite)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_REGEX; - } else if (ch == '\"') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_SINGLESTRING; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - i += 2; - } else if (IsOperator(ch)) { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); - state = SCE_HJ_DEFAULT; - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HJ_START) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_DEFAULT; - } - } - break; - case SCE_HJ_WORD: - if (!IsAWordChar(ch)) { - classifyWordHTJS(styler.GetStartSegment(), i - 1, keywords2, styler, inScriptType); - //styler.ColourTo(i - 1, eHTJSKeyword); - state = SCE_HJ_DEFAULT; - if (ch == '/' && chNext == '*') { - if (chNext2 == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_HJ_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HJ_DOUBLESTRING; - } else if (ch == '\'') { - state = SCE_HJ_SINGLESTRING; - } else if ((ch == '-') && (chNext == '-') && (chNext2 == '>')) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - i += 2; - } else if (IsOperator(ch)) { - styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); - state = SCE_HJ_DEFAULT; - } - } - break; - case SCE_HJ_COMMENT: - case SCE_HJ_COMMENTDOC: - if (ch == '/' && chPrev == '*') { - styler.ColourTo(i, StateToPrint); - state = SCE_HJ_DEFAULT; - ch = ' '; - } - break; - case SCE_HJ_COMMENTLINE: - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, statePrintForState(SCE_HJ_COMMENTLINE, inScriptType)); - state = SCE_HJ_DEFAULT; - ch = ' '; - } - break; - case SCE_HJ_DOUBLESTRING: - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - } - } else if (ch == '\"') { - styler.ColourTo(i, statePrintForState(SCE_HJ_DOUBLESTRING, inScriptType)); - state = SCE_HJ_DEFAULT; - } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - i += 2; - } else if (isLineEnd(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_STRINGEOL; - } - break; - case SCE_HJ_SINGLESTRING: - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - } - } else if (ch == '\'') { - styler.ColourTo(i, statePrintForState(SCE_HJ_SINGLESTRING, inScriptType)); - state = SCE_HJ_DEFAULT; - } else if ((inScriptType == eNonHtmlScript) && (ch == '-') && (chNext == '-') && (chNext2 == '>')) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_COMMENTLINE; - i += 2; - } else if (isLineEnd(ch)) { - styler.ColourTo(i - 1, StateToPrint); - if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) { - state = SCE_HJ_STRINGEOL; - } - } - break; - case SCE_HJ_STRINGEOL: - if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HJ_DEFAULT; - } else if (!isLineEnd(chNext)) { - styler.ColourTo(i, StateToPrint); - state = SCE_HJ_DEFAULT; - } - break; - case SCE_HJ_REGEX: - if (ch == '\r' || ch == '\n' || ch == '/') { - if (ch == '/') { - while (IsASCII(chNext) && islower(chNext)) { // gobble regex flags - i++; - ch = chNext; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } - } - styler.ColourTo(i, StateToPrint); - state = SCE_HJ_DEFAULT; - } else if (ch == '\\') { - // Gobble up the quoted character - if (chNext == '\\' || chNext == '/') { - i++; - ch = chNext; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } - } - break; - case SCE_HB_DEFAULT: - case SCE_HB_START: - if (IsAWordStart(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_WORD; - } else if (ch == '\'') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_STRING; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_COMMENTLINE; - } else if (IsOperator(ch)) { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType)); - state = SCE_HB_DEFAULT; - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HB_START) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_DEFAULT; - } - } - break; - case SCE_HB_WORD: - if (!IsAWordChar(ch)) { - state = classifyWordHTVB(styler.GetStartSegment(), i - 1, keywords3, styler, inScriptType); - if (state == SCE_HB_DEFAULT) { - if (ch == '\"') { - state = SCE_HB_STRING; - } else if (ch == '\'') { - state = SCE_HB_COMMENTLINE; - } else if (IsOperator(ch)) { - styler.ColourTo(i, statePrintForState(SCE_HB_DEFAULT, inScriptType)); - state = SCE_HB_DEFAULT; - } - } - } - break; - case SCE_HB_STRING: - if (ch == '\"') { - styler.ColourTo(i, StateToPrint); - state = SCE_HB_DEFAULT; - } else if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_STRINGEOL; - } - break; - case SCE_HB_COMMENTLINE: - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_DEFAULT; - } - break; - case SCE_HB_STRINGEOL: - if (!isLineEnd(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HB_DEFAULT; - } else if (!isLineEnd(chNext)) { - styler.ColourTo(i, StateToPrint); - state = SCE_HB_DEFAULT; - } - break; - case SCE_HP_DEFAULT: - case SCE_HP_START: - if (IsAWordStart(ch)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HP_WORD; - } else if ((ch == '<') && (chNext == '!') && (chNext2 == '-') && - styler.SafeGetCharAt(i + 3) == '-') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HP_COMMENTLINE; - } else if (ch == '#') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HP_COMMENTLINE; - } else if (ch == '\"') { - styler.ColourTo(i - 1, StateToPrint); - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_HP_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } else { - // state = statePrintForState(SCE_HP_STRING,inScriptType); - state = SCE_HP_STRING; - } - } else if (ch == '\'') { - styler.ColourTo(i - 1, StateToPrint); - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_HP_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } else { - state = SCE_HP_CHARACTER; - } - } else if (IsOperator(ch)) { - styler.ColourTo(i - 1, StateToPrint); - styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); - } else if ((ch == ' ') || (ch == '\t')) { - if (state == SCE_HP_START) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HP_DEFAULT; - } - } - break; - case SCE_HP_WORD: - if (!IsAWordChar(ch)) { - classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType, isMako); - state = SCE_HP_DEFAULT; - if (ch == '#') { - state = SCE_HP_COMMENTLINE; - } else if (ch == '\"') { - if (chNext == '\"' && chNext2 == '\"') { - i += 2; - state = SCE_HP_TRIPLEDOUBLE; - ch = ' '; - chPrev = ' '; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } else { - state = SCE_HP_STRING; - } - } else if (ch == '\'') { - if (chNext == '\'' && chNext2 == '\'') { - i += 2; - state = SCE_HP_TRIPLE; - ch = ' '; - chPrev = ' '; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } else { - state = SCE_HP_CHARACTER; - } - } else if (IsOperator(ch)) { - styler.ColourTo(i, statePrintForState(SCE_HP_OPERATOR, inScriptType)); - } - } - break; - case SCE_HP_COMMENTLINE: - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HP_DEFAULT; - } - break; - case SCE_HP_STRING: - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } - } else if (ch == '\"') { - styler.ColourTo(i, StateToPrint); - state = SCE_HP_DEFAULT; - } - break; - case SCE_HP_CHARACTER: - if (ch == '\\') { - if (chNext == '\"' || chNext == '\'' || chNext == '\\') { - i++; - ch = chNext; - chNext = static_cast(styler.SafeGetCharAt(i + 1)); - } - } else if (ch == '\'') { - styler.ColourTo(i, StateToPrint); - state = SCE_HP_DEFAULT; - } - break; - case SCE_HP_TRIPLE: - if (ch == '\'' && chPrev == '\'' && chPrev2 == '\'') { - styler.ColourTo(i, StateToPrint); - state = SCE_HP_DEFAULT; - } - break; - case SCE_HP_TRIPLEDOUBLE: - if (ch == '\"' && chPrev == '\"' && chPrev2 == '\"') { - styler.ColourTo(i, StateToPrint); - state = SCE_HP_DEFAULT; - } - break; - ///////////// start - PHP state handling - case SCE_HPHP_WORD: - if (!IsAWordChar(ch)) { - classifyWordHTPHP(styler.GetStartSegment(), i - 1, keywords5, styler); - if (ch == '/' && chNext == '*') { - i++; - state = SCE_HPHP_COMMENT; - } else if (ch == '/' && chNext == '/') { - i++; - state = SCE_HPHP_COMMENTLINE; - } else if (ch == '#') { - state = SCE_HPHP_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HPHP_HSTRING; - StringCopy(phpStringDelimiter, "\""); - } else if (styler.Match(i, "<<<")) { - bool isSimpleString = false; - i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString); - if (strlen(phpStringDelimiter)) { - state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING); - if (foldHeredoc) levelCurrent++; - } - } else if (ch == '\'') { - state = SCE_HPHP_SIMPLESTRING; - StringCopy(phpStringDelimiter, "\'"); - } else if (ch == '$' && IsPhpWordStart(chNext)) { - state = SCE_HPHP_VARIABLE; - } else if (IsOperator(ch)) { - state = SCE_HPHP_OPERATOR; - } else { - state = SCE_HPHP_DEFAULT; - } - } - break; - case SCE_HPHP_NUMBER: - // recognize bases 8,10 or 16 integers OR floating-point numbers - if (!IsADigit(ch) - && strchr(".xXabcdefABCDEF", ch) == NULL - && ((ch != '-' && ch != '+') || (chPrev != 'e' && chPrev != 'E'))) { - styler.ColourTo(i - 1, SCE_HPHP_NUMBER); - if (IsOperator(ch)) - state = SCE_HPHP_OPERATOR; - else - state = SCE_HPHP_DEFAULT; - } - break; - case SCE_HPHP_VARIABLE: - if (!IsPhpWordChar(chNext)) { - styler.ColourTo(i, SCE_HPHP_VARIABLE); - state = SCE_HPHP_DEFAULT; - } - break; - case SCE_HPHP_COMMENT: - if (ch == '/' && chPrev == '*') { - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_DEFAULT; - } - break; - case SCE_HPHP_COMMENTLINE: - if (ch == '\r' || ch == '\n') { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HPHP_DEFAULT; - } - break; - case SCE_HPHP_HSTRING: - if (ch == '\\' && (phpStringDelimiter[0] == '\"' || chNext == '$' || chNext == '{')) { - // skip the next char - i++; - } else if (((ch == '{' && chNext == '$') || (ch == '$' && chNext == '{')) - && IsPhpWordStart(chNext2)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HPHP_COMPLEX_VARIABLE; - } else if (ch == '$' && IsPhpWordStart(chNext)) { - styler.ColourTo(i - 1, StateToPrint); - state = SCE_HPHP_HSTRING_VARIABLE; - } else if (styler.Match(i, phpStringDelimiter)) { - if (phpStringDelimiter[0] == '\"') { - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_DEFAULT; - } else if (isLineEnd(chPrev)) { - const int psdLength = static_cast(strlen(phpStringDelimiter)); - const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); - const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); - if (isLineEnd(chAfterPsd) || - (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) { - i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_DEFAULT; - if (foldHeredoc) levelCurrent--; - } - } - } - break; - case SCE_HPHP_SIMPLESTRING: - if (phpStringDelimiter[0] == '\'') { - if (ch == '\\') { - // skip the next char - i++; - } else if (ch == '\'') { - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_DEFAULT; - } - } else if (isLineEnd(chPrev) && styler.Match(i, phpStringDelimiter)) { - const int psdLength = static_cast(strlen(phpStringDelimiter)); - const char chAfterPsd = styler.SafeGetCharAt(i + psdLength); - const char chAfterPsd2 = styler.SafeGetCharAt(i + psdLength + 1); - if (isLineEnd(chAfterPsd) || - (chAfterPsd == ';' && isLineEnd(chAfterPsd2))) { - i += (((i + psdLength) < lengthDoc) ? psdLength : lengthDoc) - 1; - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_DEFAULT; - if (foldHeredoc) levelCurrent--; - } - } - break; - case SCE_HPHP_HSTRING_VARIABLE: - if (!IsPhpWordChar(chNext)) { - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_HSTRING; - } - break; - case SCE_HPHP_COMPLEX_VARIABLE: - if (ch == '}') { - styler.ColourTo(i, StateToPrint); - state = SCE_HPHP_HSTRING; - } - break; - case SCE_HPHP_OPERATOR: - case SCE_HPHP_DEFAULT: - styler.ColourTo(i - 1, StateToPrint); - if (IsADigit(ch) || (ch == '.' && IsADigit(chNext))) { - state = SCE_HPHP_NUMBER; - } else if (IsAWordStart(ch)) { - state = SCE_HPHP_WORD; - } else if (ch == '/' && chNext == '*') { - i++; - state = SCE_HPHP_COMMENT; - } else if (ch == '/' && chNext == '/') { - i++; - state = SCE_HPHP_COMMENTLINE; - } else if (ch == '#') { - state = SCE_HPHP_COMMENTLINE; - } else if (ch == '\"') { - state = SCE_HPHP_HSTRING; - StringCopy(phpStringDelimiter, "\""); - } else if (styler.Match(i, "<<<")) { - bool isSimpleString = false; - i = FindPhpStringDelimiter(phpStringDelimiter, sizeof(phpStringDelimiter), i + 3, lengthDoc, styler, isSimpleString); - if (strlen(phpStringDelimiter)) { - state = (isSimpleString ? SCE_HPHP_SIMPLESTRING : SCE_HPHP_HSTRING); - if (foldHeredoc) levelCurrent++; - } - } else if (ch == '\'') { - state = SCE_HPHP_SIMPLESTRING; - StringCopy(phpStringDelimiter, "\'"); - } else if (ch == '$' && IsPhpWordStart(chNext)) { - state = SCE_HPHP_VARIABLE; - } else if (IsOperator(ch)) { - state = SCE_HPHP_OPERATOR; - } else if ((state == SCE_HPHP_OPERATOR) && (IsASpace(ch))) { - state = SCE_HPHP_DEFAULT; - } - break; - ///////////// end - PHP state handling - } - - // Some of the above terminated their lexeme but since the same character starts - // the same class again, only reenter if non empty segment. - - bool nonEmptySegment = i >= static_cast(styler.GetStartSegment()); - if (state == SCE_HB_DEFAULT) { // One of the above succeeded - if ((ch == '\"') && (nonEmptySegment)) { - state = SCE_HB_STRING; - } else if (ch == '\'') { - state = SCE_HB_COMMENTLINE; - } else if (IsAWordStart(ch)) { - state = SCE_HB_WORD; - } else if (IsOperator(ch)) { - styler.ColourTo(i, SCE_HB_DEFAULT); - } - } else if (state == SCE_HBA_DEFAULT) { // One of the above succeeded - if ((ch == '\"') && (nonEmptySegment)) { - state = SCE_HBA_STRING; - } else if (ch == '\'') { - state = SCE_HBA_COMMENTLINE; - } else if (IsAWordStart(ch)) { - state = SCE_HBA_WORD; - } else if (IsOperator(ch)) { - styler.ColourTo(i, SCE_HBA_DEFAULT); - } - } else if (state == SCE_HJ_DEFAULT) { // One of the above succeeded - if (ch == '/' && chNext == '*') { - if (styler.SafeGetCharAt(i + 2) == '*') - state = SCE_HJ_COMMENTDOC; - else - state = SCE_HJ_COMMENT; - } else if (ch == '/' && chNext == '/') { - state = SCE_HJ_COMMENTLINE; - } else if ((ch == '\"') && (nonEmptySegment)) { - state = SCE_HJ_DOUBLESTRING; - } else if ((ch == '\'') && (nonEmptySegment)) { - state = SCE_HJ_SINGLESTRING; - } else if (IsAWordStart(ch)) { - state = SCE_HJ_WORD; - } else if (IsOperator(ch)) { - styler.ColourTo(i, statePrintForState(SCE_HJ_SYMBOLS, inScriptType)); - } - } - } - - switch (state) { - case SCE_HJ_WORD: - classifyWordHTJS(styler.GetStartSegment(), lengthDoc - 1, keywords2, styler, inScriptType); - break; - case SCE_HB_WORD: - classifyWordHTVB(styler.GetStartSegment(), lengthDoc - 1, keywords3, styler, inScriptType); - break; - case SCE_HP_WORD: - classifyWordHTPy(styler.GetStartSegment(), lengthDoc - 1, keywords4, styler, prevWord, inScriptType, isMako); - break; - case SCE_HPHP_WORD: - classifyWordHTPHP(styler.GetStartSegment(), lengthDoc - 1, keywords5, styler); - break; - default: - StateToPrint = statePrintForState(state, inScriptType); - if (static_cast(styler.GetStartSegment()) < lengthDoc) - styler.ColourTo(lengthDoc - 1, StateToPrint); - break; - } - - // Fill in the real level of the next line, keeping the current flags as they will be filled in later - if (fold) { - int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; - styler.SetLevel(lineCurrent, levelPrev | flagsNext); - } -} - -static void ColouriseXMLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], - Accessor &styler) { - // Passing in true because we're lexing XML - ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, true); -} - -static void ColouriseHTMLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], - Accessor &styler) { - // Passing in false because we're notlexing XML - ColouriseHyperTextDoc(startPos, length, initStyle, keywordlists, styler, false); -} - -static void ColourisePHPScriptDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], - Accessor &styler) { - if (startPos == 0) - initStyle = SCE_HPHP_DEFAULT; - ColouriseHTMLDoc(startPos, length, initStyle, keywordlists, styler); -} - -static const char * const htmlWordListDesc[] = { - "HTML elements and attributes", - "JavaScript keywords", - "VBScript keywords", - "Python keywords", - "PHP keywords", - "SGML and DTD keywords", - 0, -}; - -static const char * const phpscriptWordListDesc[] = { - "", //Unused - "", //Unused - "", //Unused - "", //Unused - "PHP keywords", - "", //Unused - 0, -}; - -LexerModule lmHTML(SCLEX_HTML, ColouriseHTMLDoc, "hypertext", 0, htmlWordListDesc); -LexerModule lmXML(SCLEX_XML, ColouriseXMLDoc, "xml", 0, htmlWordListDesc); -LexerModule lmPHPSCRIPT(SCLEX_PHPSCRIPT, ColourisePHPScriptDoc, "phpscript", 0, phpscriptWordListDesc); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexJSON.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexJSON.cxx deleted file mode 100644 index 6c060611f..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexJSON.cxx +++ /dev/null @@ -1,499 +0,0 @@ -// Scintilla source code edit control -/** - * @file LexJSON.cxx - * @date February 19, 2016 - * @brief Lexer for JSON and JSON-LD formats - * @author nkmathew - * - * The License.txt file describes the conditions under which this software may - * be distributed. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" -#include "OptionSet.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static const char *const JSONWordListDesc[] = { - "JSON Keywords", - "JSON-LD Keywords", - 0 -}; - -/** - * Used to detect compact IRI/URLs in JSON-LD without first looking ahead for the - * colon separating the prefix and suffix - * - * https://www.w3.org/TR/json-ld/#dfn-compact-iri - */ -struct CompactIRI { - int colonCount; - bool foundInvalidChar; - CharacterSet setCompactIRI; - CompactIRI() { - colonCount = 0; - foundInvalidChar = false; - setCompactIRI = CharacterSet(CharacterSet::setAlpha, "$_-"); - } - void resetState() { - colonCount = 0; - foundInvalidChar = false; - } - void checkChar(int ch) { - if (ch == ':') { - colonCount++; - } else { - foundInvalidChar |= !setCompactIRI.Contains(ch); - } - } - bool shouldHighlight() const { - return !foundInvalidChar && colonCount == 1; - } -}; - -/** - * Keeps track of escaped characters in strings as per: - * - * https://tools.ietf.org/html/rfc7159#section-7 - */ -struct EscapeSequence { - int digitsLeft; - CharacterSet setHexDigits; - CharacterSet setEscapeChars; - EscapeSequence() { - digitsLeft = 0; - setHexDigits = CharacterSet(CharacterSet::setDigits, "ABCDEFabcdef"); - setEscapeChars = CharacterSet(CharacterSet::setNone, "\\\"tnbfru/"); - } - // Returns true if the following character is a valid escaped character - bool newSequence(int nextChar) { - digitsLeft = 0; - if (nextChar == 'u') { - digitsLeft = 5; - } else if (!setEscapeChars.Contains(nextChar)) { - return false; - } - return true; - } - bool atEscapeEnd() const { - return digitsLeft <= 0; - } - bool isInvalidChar(int currChar) const { - return !setHexDigits.Contains(currChar); - } -}; - -struct OptionsJSON { - bool foldCompact; - bool fold; - bool allowComments; - bool escapeSequence; - OptionsJSON() { - foldCompact = false; - fold = false; - allowComments = false; - escapeSequence = false; - } -}; - -struct OptionSetJSON : public OptionSet { - OptionSetJSON() { - DefineProperty("lexer.json.escape.sequence", &OptionsJSON::escapeSequence, - "Set to 1 to enable highlighting of escape sequences in strings"); - - DefineProperty("lexer.json.allow.comments", &OptionsJSON::allowComments, - "Set to 1 to enable highlighting of line/block comments in JSON"); - - DefineProperty("fold.compact", &OptionsJSON::foldCompact); - DefineProperty("fold", &OptionsJSON::fold); - DefineWordListSets(JSONWordListDesc); - } -}; - -class LexerJSON : public ILexer { - OptionsJSON options; - OptionSetJSON optSetJSON; - EscapeSequence escapeSeq; - WordList keywordsJSON; - WordList keywordsJSONLD; - CharacterSet setOperators; - CharacterSet setURL; - CharacterSet setKeywordJSONLD; - CharacterSet setKeywordJSON; - CompactIRI compactIRI; - - static bool IsNextNonWhitespace(LexAccessor &styler, Sci_Position start, char ch) { - Sci_Position i = 0; - while (i < 50) { - i++; - char curr = styler.SafeGetCharAt(start+i, '\0'); - char next = styler.SafeGetCharAt(start+i+1, '\0'); - bool atEOL = (curr == '\r' && next != '\n') || (curr == '\n'); - if (curr == ch) { - return true; - } else if (!isspacechar(curr) || atEOL) { - return false; - } - } - return false; - } - - /** - * Looks for the colon following the end quote - * - * Assumes property names of lengths no longer than a 100 characters. - * The colon is also expected to be less than 50 spaces after the end - * quote for the string to be considered a property name - */ - static bool AtPropertyName(LexAccessor &styler, Sci_Position start) { - Sci_Position i = 0; - bool escaped = false; - while (i < 100) { - i++; - char curr = styler.SafeGetCharAt(start+i, '\0'); - if (escaped) { - escaped = false; - continue; - } - escaped = curr == '\\'; - if (curr == '"') { - return IsNextNonWhitespace(styler, start+i, ':'); - } else if (!curr) { - return false; - } - } - return false; - } - - static bool IsNextWordInList(WordList &keywordList, CharacterSet wordSet, - StyleContext &context, LexAccessor &styler) { - char word[51]; - Sci_Position currPos = (Sci_Position) context.currentPos; - int i = 0; - while (i < 50) { - char ch = styler.SafeGetCharAt(currPos + i); - if (!wordSet.Contains(ch)) { - break; - } - word[i] = ch; - i++; - } - word[i] = '\0'; - return keywordList.InList(word); - } - - public: - LexerJSON() : - setOperators(CharacterSet::setNone, "[{}]:,"), - setURL(CharacterSet::setAlphaNum, "-._~:/?#[]@!$&'()*+,),="), - setKeywordJSONLD(CharacterSet::setAlpha, ":@"), - setKeywordJSON(CharacterSet::setAlpha, "$_") { - } - virtual ~LexerJSON() {} - virtual int SCI_METHOD Version() const { - return lvOriginal; - } - virtual void SCI_METHOD Release() { - delete this; - } - virtual const char *SCI_METHOD PropertyNames() { - return optSetJSON.PropertyNames(); - } - virtual int SCI_METHOD PropertyType(const char *name) { - return optSetJSON.PropertyType(name); - } - virtual const char *SCI_METHOD DescribeProperty(const char *name) { - return optSetJSON.DescribeProperty(name); - } - virtual Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) { - if (optSetJSON.PropertySet(&options, key, val)) { - return 0; - } - return -1; - } - virtual Sci_Position SCI_METHOD WordListSet(int n, const char *wl) { - WordList *wordListN = 0; - switch (n) { - case 0: - wordListN = &keywordsJSON; - break; - case 1: - wordListN = &keywordsJSONLD; - break; - } - Sci_Position firstModification = -1; - if (wordListN) { - WordList wlNew; - wlNew.Set(wl); - if (*wordListN != wlNew) { - wordListN->Set(wl); - firstModification = 0; - } - } - return firstModification; - } - virtual void *SCI_METHOD PrivateCall(int, void *) { - return 0; - } - static ILexer *LexerFactoryJSON() { - return new LexerJSON; - } - virtual const char *SCI_METHOD DescribeWordListSets() { - return optSetJSON.DescribeWordListSets(); - } - virtual void SCI_METHOD Lex(Sci_PositionU startPos, - Sci_Position length, - int initStyle, - IDocument *pAccess); - virtual void SCI_METHOD Fold(Sci_PositionU startPos, - Sci_Position length, - int initStyle, - IDocument *pAccess); -}; - -void SCI_METHOD LexerJSON::Lex(Sci_PositionU startPos, - Sci_Position length, - int initStyle, - IDocument *pAccess) { - LexAccessor styler(pAccess); - StyleContext context(startPos, length, initStyle, styler); - int stringStyleBefore = SCE_JSON_STRING; - while (context.More()) { - switch (context.state) { - case SCE_JSON_BLOCKCOMMENT: - if (context.Match("*/")) { - context.Forward(); - context.ForwardSetState(SCE_JSON_DEFAULT); - } - break; - case SCE_JSON_LINECOMMENT: - if (context.atLineEnd) { - context.SetState(SCE_JSON_DEFAULT); - } - break; - case SCE_JSON_STRINGEOL: - if (context.atLineStart) { - context.SetState(SCE_JSON_DEFAULT); - } - break; - case SCE_JSON_ESCAPESEQUENCE: - escapeSeq.digitsLeft--; - if (!escapeSeq.atEscapeEnd()) { - if (escapeSeq.isInvalidChar(context.ch)) { - context.SetState(SCE_JSON_ERROR); - } - break; - } - if (context.ch == '"') { - context.SetState(stringStyleBefore); - context.ForwardSetState(SCE_C_DEFAULT); - } else if (context.ch == '\\') { - if (!escapeSeq.newSequence(context.chNext)) { - context.SetState(SCE_JSON_ERROR); - } - context.Forward(); - } else { - context.SetState(stringStyleBefore); - if (context.atLineEnd) { - context.ChangeState(SCE_JSON_STRINGEOL); - } - } - break; - case SCE_JSON_PROPERTYNAME: - case SCE_JSON_STRING: - if (context.ch == '"') { - if (compactIRI.shouldHighlight()) { - context.ChangeState(SCE_JSON_COMPACTIRI); - context.ForwardSetState(SCE_JSON_DEFAULT); - compactIRI.resetState(); - } else { - context.ForwardSetState(SCE_JSON_DEFAULT); - } - } else if (context.atLineEnd) { - context.ChangeState(SCE_JSON_STRINGEOL); - } else if (context.ch == '\\') { - stringStyleBefore = context.state; - if (options.escapeSequence) { - context.SetState(SCE_JSON_ESCAPESEQUENCE); - if (!escapeSeq.newSequence(context.chNext)) { - context.SetState(SCE_JSON_ERROR); - } - } - context.Forward(); - } else if (context.Match("https://") || - context.Match("http://") || - context.Match("ssh://") || - context.Match("git://") || - context.Match("svn://") || - context.Match("ftp://") || - context.Match("mailto:")) { - // Handle most common URI schemes only - stringStyleBefore = context.state; - context.SetState(SCE_JSON_URI); - } else if (context.ch == '@') { - // https://www.w3.org/TR/json-ld/#dfn-keyword - if (IsNextWordInList(keywordsJSONLD, setKeywordJSONLD, context, styler)) { - stringStyleBefore = context.state; - context.SetState(SCE_JSON_LDKEYWORD); - } - } else { - compactIRI.checkChar(context.ch); - } - break; - case SCE_JSON_LDKEYWORD: - case SCE_JSON_URI: - if ((!setKeywordJSONLD.Contains(context.ch) && - (context.state == SCE_JSON_LDKEYWORD)) || - (!setURL.Contains(context.ch))) { - context.SetState(stringStyleBefore); - } - if (context.ch == '"') { - context.ForwardSetState(SCE_JSON_DEFAULT); - } else if (context.atLineEnd) { - context.ChangeState(SCE_JSON_STRINGEOL); - } - break; - case SCE_JSON_OPERATOR: - case SCE_JSON_NUMBER: - context.SetState(SCE_JSON_DEFAULT); - break; - case SCE_JSON_ERROR: - if (context.atLineEnd) { - context.SetState(SCE_JSON_DEFAULT); - } - break; - case SCE_JSON_KEYWORD: - if (!setKeywordJSON.Contains(context.ch)) { - context.SetState(SCE_JSON_DEFAULT); - } - break; - } - if (context.state == SCE_JSON_DEFAULT) { - if (context.ch == '"') { - compactIRI.resetState(); - context.SetState(SCE_JSON_STRING); - Sci_Position currPos = static_cast(context.currentPos); - if (AtPropertyName(styler, currPos)) { - context.SetState(SCE_JSON_PROPERTYNAME); - } - } else if (setOperators.Contains(context.ch)) { - context.SetState(SCE_JSON_OPERATOR); - } else if (options.allowComments && context.Match("/*")) { - context.SetState(SCE_JSON_BLOCKCOMMENT); - context.Forward(); - } else if (options.allowComments && context.Match("//")) { - context.SetState(SCE_JSON_LINECOMMENT); - } else if (setKeywordJSON.Contains(context.ch)) { - if (IsNextWordInList(keywordsJSON, setKeywordJSON, context, styler)) { - context.SetState(SCE_JSON_KEYWORD); - } - } - bool numberStart = - IsADigit(context.ch) && (context.chPrev == '+'|| - context.chPrev == '-' || - context.atLineStart || - IsASpace(context.chPrev) || - setOperators.Contains(context.chPrev)); - bool exponentPart = - tolower(context.ch) == 'e' && - IsADigit(context.chPrev) && - (IsADigit(context.chNext) || - context.chNext == '+' || - context.chNext == '-'); - bool signPart = - (context.ch == '-' || context.ch == '+') && - ((tolower(context.chPrev) == 'e' && IsADigit(context.chNext)) || - ((IsASpace(context.chPrev) || setOperators.Contains(context.chPrev)) - && IsADigit(context.chNext))); - bool adjacentDigit = - IsADigit(context.ch) && IsADigit(context.chPrev); - bool afterExponent = IsADigit(context.ch) && tolower(context.chPrev) == 'e'; - bool dotPart = context.ch == '.' && - IsADigit(context.chPrev) && - IsADigit(context.chNext); - bool afterDot = IsADigit(context.ch) && context.chPrev == '.'; - if (numberStart || - exponentPart || - signPart || - adjacentDigit || - dotPart || - afterExponent || - afterDot) { - context.SetState(SCE_JSON_NUMBER); - } else if (context.state == SCE_JSON_DEFAULT && !IsASpace(context.ch)) { - context.SetState(SCE_JSON_ERROR); - } - } - context.Forward(); - } - context.Complete(); -} - -void SCI_METHOD LexerJSON::Fold(Sci_PositionU startPos, - Sci_Position length, - int, - IDocument *pAccess) { - if (!options.fold) { - return; - } - LexAccessor styler(pAccess); - Sci_PositionU currLine = styler.GetLine(startPos); - Sci_PositionU endPos = startPos + length; - int currLevel = SC_FOLDLEVELBASE; - if (currLine > 0) - currLevel = styler.LevelAt(currLine - 1) >> 16; - int nextLevel = currLevel; - int visibleChars = 0; - for (Sci_PositionU i = startPos; i < endPos; i++) { - char curr = styler.SafeGetCharAt(i); - char next = styler.SafeGetCharAt(i+1); - bool atEOL = (curr == '\r' && next != '\n') || (curr == '\n'); - if (styler.StyleAt(i) == SCE_JSON_OPERATOR) { - if (curr == '{' || curr == '[') { - nextLevel++; - } else if (curr == '}' || curr == ']') { - nextLevel--; - } - } - if (atEOL || i == (endPos-1)) { - int level = currLevel | nextLevel << 16; - if (!visibleChars && options.foldCompact) { - level |= SC_FOLDLEVELWHITEFLAG; - } else if (nextLevel > currLevel) { - level |= SC_FOLDLEVELHEADERFLAG; - } - if (level != styler.LevelAt(currLine)) { - styler.SetLevel(currLine, level); - } - currLine++; - currLevel = nextLevel; - visibleChars = 0; - } - if (!isspacechar(curr)) { - visibleChars++; - } - } -} - -LexerModule lmJSON(SCLEX_JSON, - LexerJSON::LexerFactoryJSON, - "json", - JSONWordListDesc); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexNull.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexNull.cxx deleted file mode 100644 index 34876775d..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexNull.cxx +++ /dev/null @@ -1,40 +0,0 @@ -// Scintilla source code edit control -/** @file LexNull.cxx - ** Lexer for no language. Used for plain text and unrecognized files. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static void ColouriseNullDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], - Accessor &styler) { - // Null language means all style bytes are 0 so just mark the end - no need to fill in. - if (length > 0) { - styler.StartAt(startPos + length - 1); - styler.StartSegment(startPos + length - 1); - styler.ColourTo(startPos + length - 1, 0); - } -} - -LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null"); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexPython.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexPython.cxx deleted file mode 100644 index 19dd0ca3b..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexPython.cxx +++ /dev/null @@ -1,746 +0,0 @@ -// Scintilla source code edit control -/** @file LexPython.cxx - ** Lexer for Python. - **/ -// Copyright 1998-2002 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" -#include "OptionSet.h" -#include "SubStyles.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -namespace { - // Use an unnamed namespace to protect the functions and classes from name conflicts - -/* kwCDef, kwCTypeName only used for Cython */ -enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef }; - -enum literalsAllowed { litNone = 0, litU = 1, litB = 2 }; - -const int indicatorWhitespace = 1; - -bool IsPyComment(Accessor &styler, Sci_Position pos, Sci_Position len) { - return len > 0 && styler[pos] == '#'; -} - -bool IsPyStringTypeChar(int ch, literalsAllowed allowed) { - return - ((allowed & litB) && (ch == 'b' || ch == 'B')) || - ((allowed & litU) && (ch == 'u' || ch == 'U')); -} - -bool IsPyStringStart(int ch, int chNext, int chNext2, literalsAllowed allowed) { - if (ch == '\'' || ch == '"') - return true; - if (IsPyStringTypeChar(ch, allowed)) { - if (chNext == '"' || chNext == '\'') - return true; - if ((chNext == 'r' || chNext == 'R') && (chNext2 == '"' || chNext2 == '\'')) - return true; - } - if ((ch == 'r' || ch == 'R') && (chNext == '"' || chNext == '\'')) - return true; - - return false; -} - -/* Return the state to use for the string starting at i; *nextIndex will be set to the first index following the quote(s) */ -int GetPyStringState(Accessor &styler, Sci_Position i, Sci_PositionU *nextIndex, literalsAllowed allowed) { - char ch = styler.SafeGetCharAt(i); - char chNext = styler.SafeGetCharAt(i + 1); - - // Advance beyond r, u, or ur prefix (or r, b, or br in Python 3.0), but bail if there are any unexpected chars - if (ch == 'r' || ch == 'R') { - i++; - ch = styler.SafeGetCharAt(i); - chNext = styler.SafeGetCharAt(i + 1); - } else if (IsPyStringTypeChar(ch, allowed)) { - if (chNext == 'r' || chNext == 'R') - i += 2; - else - i += 1; - ch = styler.SafeGetCharAt(i); - chNext = styler.SafeGetCharAt(i + 1); - } - - if (ch != '"' && ch != '\'') { - *nextIndex = i + 1; - return SCE_P_DEFAULT; - } - - if (ch == chNext && ch == styler.SafeGetCharAt(i + 2)) { - *nextIndex = i + 3; - - if (ch == '"') - return SCE_P_TRIPLEDOUBLE; - else - return SCE_P_TRIPLE; - } else { - *nextIndex = i + 1; - - if (ch == '"') - return SCE_P_STRING; - else - return SCE_P_CHARACTER; - } -} - -inline bool IsAWordChar(int ch) { - return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_'); -} - -inline bool IsAWordStart(int ch) { - return (ch < 0x80) && (isalnum(ch) || ch == '_'); -} - -static bool IsFirstNonWhitespace(Sci_Position pos, Accessor &styler) { - Sci_Position line = styler.GetLine(pos); - Sci_Position start_pos = styler.LineStart(line); - for (Sci_Position i = start_pos; i < pos; i++) { - char ch = styler[i]; - if (!(ch == ' ' || ch == '\t')) - return false; - } - return true; -} - -// Options used for LexerPython -struct OptionsPython { - int whingeLevel; - bool base2or8Literals; - bool stringsU; - bool stringsB; - bool stringsOverNewline; - bool keywords2NoSubIdentifiers; - bool fold; - bool foldQuotes; - bool foldCompact; - - OptionsPython() { - whingeLevel = 0; - base2or8Literals = true; - stringsU = true; - stringsB = true; - stringsOverNewline = false; - keywords2NoSubIdentifiers = false; - fold = false; - foldQuotes = false; - foldCompact = false; - } - - literalsAllowed AllowedLiterals() const { - literalsAllowed allowedLiterals = stringsU ? litU : litNone; - if (stringsB) - allowedLiterals = static_cast(allowedLiterals | litB); - return allowedLiterals; - } -}; - -static const char *const pythonWordListDesc[] = { - "Keywords", - "Highlighted identifiers", - 0 -}; - -struct OptionSetPython : public OptionSet { - OptionSetPython() { - DefineProperty("tab.timmy.whinge.level", &OptionsPython::whingeLevel, - "For Python code, checks whether indenting is consistent. " - "The default, 0 turns off indentation checking, " - "1 checks whether each line is potentially inconsistent with the previous line, " - "2 checks whether any space characters occur before a tab character in the indentation, " - "3 checks whether any spaces are in the indentation, and " - "4 checks for any tab characters in the indentation. " - "1 is a good level to use."); - - DefineProperty("lexer.python.literals.binary", &OptionsPython::base2or8Literals, - "Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712."); - - DefineProperty("lexer.python.strings.u", &OptionsPython::stringsU, - "Set to 0 to not recognise Python Unicode literals u\"x\" as used before Python 3."); - - DefineProperty("lexer.python.strings.b", &OptionsPython::stringsB, - "Set to 0 to not recognise Python 3 bytes literals b\"x\"."); - - DefineProperty("lexer.python.strings.over.newline", &OptionsPython::stringsOverNewline, - "Set to 1 to allow strings to span newline characters."); - - DefineProperty("lexer.python.keywords2.no.sub.identifiers", &OptionsPython::keywords2NoSubIdentifiers, - "When enabled, it will not style keywords2 items that are used as a sub-identifier. " - "Example: when set, will not highlight \"foo.open\" when \"open\" is a keywords2 item."); - - DefineProperty("fold", &OptionsPython::fold); - - DefineProperty("fold.quotes.python", &OptionsPython::foldQuotes, - "This option enables folding multi-line quoted strings when using the Python lexer."); - - DefineProperty("fold.compact", &OptionsPython::foldCompact); - - DefineWordListSets(pythonWordListDesc); - } -}; - -const char styleSubable[] = { SCE_P_IDENTIFIER, 0 }; - -} - -class LexerPython : public ILexerWithSubStyles { - WordList keywords; - WordList keywords2; - OptionsPython options; - OptionSetPython osPython; - enum { ssIdentifier }; - SubStyles subStyles; -public: - explicit LexerPython() : - subStyles(styleSubable, 0x80, 0x40, 0) { - } - virtual ~LexerPython() { - } - void SCI_METHOD Release() { - delete this; - } - int SCI_METHOD Version() const { - return lvSubStyles; - } - const char * SCI_METHOD PropertyNames() { - return osPython.PropertyNames(); - } - int SCI_METHOD PropertyType(const char *name) { - return osPython.PropertyType(name); - } - const char * SCI_METHOD DescribeProperty(const char *name) { - return osPython.DescribeProperty(name); - } - Sci_Position SCI_METHOD PropertySet(const char *key, const char *val); - const char * SCI_METHOD DescribeWordListSets() { - return osPython.DescribeWordListSets(); - } - Sci_Position SCI_METHOD WordListSet(int n, const char *wl); - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess); - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess); - - void * SCI_METHOD PrivateCall(int, void *) { - return 0; - } - - int SCI_METHOD LineEndTypesSupported() { - return SC_LINE_END_TYPE_UNICODE; - } - - int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) { - return subStyles.Allocate(styleBase, numberStyles); - } - int SCI_METHOD SubStylesStart(int styleBase) { - return subStyles.Start(styleBase); - } - int SCI_METHOD SubStylesLength(int styleBase) { - return subStyles.Length(styleBase); - } - int SCI_METHOD StyleFromSubStyle(int subStyle) { - int styleBase = subStyles.BaseStyle(subStyle); - return styleBase; - } - int SCI_METHOD PrimaryStyleFromStyle(int style) { - return style; - } - void SCI_METHOD FreeSubStyles() { - subStyles.Free(); - } - void SCI_METHOD SetIdentifiers(int style, const char *identifiers) { - subStyles.SetIdentifiers(style, identifiers); - } - int SCI_METHOD DistanceToSecondaryStyles() { - return 0; - } - const char * SCI_METHOD GetSubStyleBases() { - return styleSubable; - } - - static ILexer *LexerFactoryPython() { - return new LexerPython(); - } -}; - -Sci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *val) { - if (osPython.PropertySet(&options, key, val)) { - return 0; - } - return -1; -} - -Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) { - WordList *wordListN = 0; - switch (n) { - case 0: - wordListN = &keywords; - break; - case 1: - wordListN = &keywords2; - break; - } - Sci_Position firstModification = -1; - if (wordListN) { - WordList wlNew; - wlNew.Set(wl); - if (*wordListN != wlNew) { - wordListN->Set(wl); - firstModification = 0; - } - } - return firstModification; -} - -void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - Accessor styler(pAccess, NULL); - - const Sci_Position endPos = startPos + length; - - // Backtrack to previous line in case need to fix its tab whinging - Sci_Position lineCurrent = styler.GetLine(startPos); - if (startPos > 0) { - if (lineCurrent > 0) { - lineCurrent--; - // Look for backslash-continued lines - while (lineCurrent > 0) { - Sci_Position eolPos = styler.LineStart(lineCurrent) - 1; - int eolStyle = styler.StyleAt(eolPos); - if (eolStyle == SCE_P_STRING - || eolStyle == SCE_P_CHARACTER - || eolStyle == SCE_P_STRINGEOL) { - lineCurrent -= 1; - } else { - break; - } - } - startPos = styler.LineStart(lineCurrent); - } - initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1); - } - - const literalsAllowed allowedLiterals = options.AllowedLiterals(); - - initStyle = initStyle & 31; - if (initStyle == SCE_P_STRINGEOL) { - initStyle = SCE_P_DEFAULT; - } - - kwType kwLast = kwOther; - int spaceFlags = 0; - styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); - bool base_n_number = false; - - const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_P_IDENTIFIER); - - StyleContext sc(startPos, endPos - startPos, initStyle, styler); - - bool indentGood = true; - Sci_Position startIndicator = sc.currentPos; - bool inContinuedString = false; - - for (; sc.More(); sc.Forward()) { - - if (sc.atLineStart) { - styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); - indentGood = true; - if (options.whingeLevel == 1) { - indentGood = (spaceFlags & wsInconsistent) == 0; - } else if (options.whingeLevel == 2) { - indentGood = (spaceFlags & wsSpaceTab) == 0; - } else if (options.whingeLevel == 3) { - indentGood = (spaceFlags & wsSpace) == 0; - } else if (options.whingeLevel == 4) { - indentGood = (spaceFlags & wsTab) == 0; - } - if (!indentGood) { - styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0); - startIndicator = sc.currentPos; - } - } - - if (sc.atLineEnd) { - if ((sc.state == SCE_P_DEFAULT) || - (sc.state == SCE_P_TRIPLE) || - (sc.state == SCE_P_TRIPLEDOUBLE)) { - // Perform colourisation of white space and triple quoted strings at end of each line to allow - // tab marking to work inside white space and triple quoted strings - sc.SetState(sc.state); - } - lineCurrent++; - if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) { - if (inContinuedString || options.stringsOverNewline) { - inContinuedString = false; - } else { - sc.ChangeState(SCE_P_STRINGEOL); - sc.ForwardSetState(SCE_P_DEFAULT); - } - } - if (!sc.More()) - break; - } - - bool needEOLCheck = false; - - // Check for a state end - if (sc.state == SCE_P_OPERATOR) { - kwLast = kwOther; - sc.SetState(SCE_P_DEFAULT); - } else if (sc.state == SCE_P_NUMBER) { - if (!IsAWordChar(sc.ch) && - !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) { - sc.SetState(SCE_P_DEFAULT); - } - } else if (sc.state == SCE_P_IDENTIFIER) { - if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) { - char s[100]; - sc.GetCurrent(s, sizeof(s)); - int style = SCE_P_IDENTIFIER; - if ((kwLast == kwImport) && (strcmp(s, "as") == 0)) { - style = SCE_P_WORD; - } else if (keywords.InList(s)) { - style = SCE_P_WORD; - } else if (kwLast == kwClass) { - style = SCE_P_CLASSNAME; - } else if (kwLast == kwDef) { - style = SCE_P_DEFNAME; - } else if (kwLast == kwCDef || kwLast == kwCPDef) { - Sci_Position pos = sc.currentPos; - unsigned char ch = styler.SafeGetCharAt(pos, '\0'); - while (ch != '\0') { - if (ch == '(') { - style = SCE_P_DEFNAME; - break; - } else if (ch == ':') { - style = SCE_P_CLASSNAME; - break; - } else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') { - pos++; - ch = styler.SafeGetCharAt(pos, '\0'); - } else { - break; - } - } - } else if (keywords2.InList(s)) { - if (options.keywords2NoSubIdentifiers) { - // We don't want to highlight keywords2 - // that are used as a sub-identifier, - // i.e. not open in "foo.open". - Sci_Position pos = styler.GetStartSegment() - 1; - if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.')) - style = SCE_P_WORD2; - } else { - style = SCE_P_WORD2; - } - } else { - int subStyle = classifierIdentifiers.ValueFor(s); - if (subStyle >= 0) { - style = subStyle; - } - } - sc.ChangeState(style); - sc.SetState(SCE_P_DEFAULT); - if (style == SCE_P_WORD) { - if (0 == strcmp(s, "class")) - kwLast = kwClass; - else if (0 == strcmp(s, "def")) - kwLast = kwDef; - else if (0 == strcmp(s, "import")) - kwLast = kwImport; - else if (0 == strcmp(s, "cdef")) - kwLast = kwCDef; - else if (0 == strcmp(s, "cpdef")) - kwLast = kwCPDef; - else if (0 == strcmp(s, "cimport")) - kwLast = kwImport; - else if (kwLast != kwCDef && kwLast != kwCPDef) - kwLast = kwOther; - } else if (kwLast != kwCDef && kwLast != kwCPDef) { - kwLast = kwOther; - } - } - } else if ((sc.state == SCE_P_COMMENTLINE) || (sc.state == SCE_P_COMMENTBLOCK)) { - if (sc.ch == '\r' || sc.ch == '\n') { - sc.SetState(SCE_P_DEFAULT); - } - } else if (sc.state == SCE_P_DECORATOR) { - if (!IsAWordChar(sc.ch)) { - sc.SetState(SCE_P_DEFAULT); - } - } else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) { - if (sc.ch == '\\') { - if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) { - sc.Forward(); - } - if (sc.chNext == '\n' || sc.chNext == '\r') { - inContinuedString = true; - } else { - // Don't roll over the newline. - sc.Forward(); - } - } else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) { - sc.ForwardSetState(SCE_P_DEFAULT); - needEOLCheck = true; - } else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) { - sc.ForwardSetState(SCE_P_DEFAULT); - needEOLCheck = true; - } - } else if (sc.state == SCE_P_TRIPLE) { - if (sc.ch == '\\') { - sc.Forward(); - } else if (sc.Match("\'\'\'")) { - sc.Forward(); - sc.Forward(); - sc.ForwardSetState(SCE_P_DEFAULT); - needEOLCheck = true; - } - } else if (sc.state == SCE_P_TRIPLEDOUBLE) { - if (sc.ch == '\\') { - sc.Forward(); - } else if (sc.Match("\"\"\"")) { - sc.Forward(); - sc.Forward(); - sc.ForwardSetState(SCE_P_DEFAULT); - needEOLCheck = true; - } - } - - if (!indentGood && !IsASpaceOrTab(sc.ch)) { - styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1); - startIndicator = sc.currentPos; - indentGood = true; - } - - // One cdef or cpdef line, clear kwLast only at end of line - if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) { - kwLast = kwOther; - } - - // State exit code may have moved on to end of line - if (needEOLCheck && sc.atLineEnd) { - lineCurrent++; - styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment); - if (!sc.More()) - break; - } - - // Check for a new state starting character - if (sc.state == SCE_P_DEFAULT) { - if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { - if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) { - base_n_number = true; - sc.SetState(SCE_P_NUMBER); - } else if (sc.ch == '0' && - (sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) { - if (options.base2or8Literals) { - base_n_number = true; - sc.SetState(SCE_P_NUMBER); - } else { - sc.SetState(SCE_P_NUMBER); - sc.ForwardSetState(SCE_P_IDENTIFIER); - } - } else { - base_n_number = false; - sc.SetState(SCE_P_NUMBER); - } - } else if ((IsASCII(sc.ch) && isoperator(static_cast(sc.ch))) || sc.ch == '`') { - sc.SetState(SCE_P_OPERATOR); - } else if (sc.ch == '#') { - sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE); - } else if (sc.ch == '@') { - if (IsFirstNonWhitespace(sc.currentPos, styler)) - sc.SetState(SCE_P_DECORATOR); - else - sc.SetState(SCE_P_OPERATOR); - } else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) { - Sci_PositionU nextIndex = 0; - sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals)); - while (nextIndex > (sc.currentPos + 1) && sc.More()) { - sc.Forward(); - } - } else if (IsAWordStart(sc.ch)) { - sc.SetState(SCE_P_IDENTIFIER); - } - } - } - styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0); - sc.Complete(); -} - -static bool IsCommentLine(Sci_Position line, Accessor &styler) { - Sci_Position pos = styler.LineStart(line); - Sci_Position eol_pos = styler.LineStart(line + 1) - 1; - for (Sci_Position i = pos; i < eol_pos; i++) { - char ch = styler[i]; - if (ch == '#') - return true; - else if (ch != ' ' && ch != '\t') - return false; - } - return false; -} - -static bool IsQuoteLine(Sci_Position line, Accessor &styler) { - int style = styler.StyleAt(styler.LineStart(line)) & 31; - return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); -} - - -void SCI_METHOD LexerPython::Fold(Sci_PositionU startPos, Sci_Position length, int /*initStyle - unused*/, IDocument *pAccess) { - if (!options.fold) - return; - - Accessor styler(pAccess, NULL); - - const Sci_Position maxPos = startPos + length; - const Sci_Position maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1); // Requested last line - const Sci_Position docLines = styler.GetLine(styler.Length()); // Available last line - - // Backtrack to previous non-blank line so we can determine indent level - // for any white space lines (needed esp. within triple quoted strings) - // and so we can fix any preceding fold level (which is why we go back - // at least one line in all cases) - int spaceFlags = 0; - Sci_Position lineCurrent = styler.GetLine(startPos); - int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); - while (lineCurrent > 0) { - lineCurrent--; - indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL); - if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) && - (!IsCommentLine(lineCurrent, styler)) && - (!IsQuoteLine(lineCurrent, styler))) - break; - } - int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; - - // Set up initial loop state - startPos = styler.LineStart(lineCurrent); - int prev_state = SCE_P_DEFAULT & 31; - if (lineCurrent >= 1) - prev_state = styler.StyleAt(startPos - 1) & 31; - int prevQuote = options.foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE)); - - // Process all characters to end of requested range or end of any triple quote - //that hangs over the end of the range. Cap processing in all cases - // to end of document (in case of unclosed quote at end). - while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) { - - // Gather info - int lev = indentCurrent; - Sci_Position lineNext = lineCurrent + 1; - int indentNext = indentCurrent; - int quote = false; - if (lineNext <= docLines) { - // Information about next line is only available if not at end of document - indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); - Sci_Position lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext); - int style = styler.StyleAt(lookAtPos) & 31; - quote = options.foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE)); - } - const int quote_start = (quote && !prevQuote); - const int quote_continue = (quote && prevQuote); - if (!quote || !prevQuote) - indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK; - if (quote) - indentNext = indentCurrentLevel; - if (indentNext & SC_FOLDLEVELWHITEFLAG) - indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel; - - if (quote_start) { - // Place fold point at start of triple quoted string - lev |= SC_FOLDLEVELHEADERFLAG; - } else if (quote_continue || prevQuote) { - // Add level to rest of lines in the string - lev = lev + 1; - } - - // Skip past any blank lines for next indent level info; we skip also - // comments (all comments, not just those starting in column 0) - // which effectively folds them into surrounding code rather - // than screwing up folding. - - while (!quote && - (lineNext < docLines) && - ((indentNext & SC_FOLDLEVELWHITEFLAG) || - (lineNext <= docLines && IsCommentLine(lineNext, styler)))) { - - lineNext++; - indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL); - } - - const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK; - const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments); - - // Now set all the indent levels on the lines we skipped - // Do this from end to start. Once we encounter one line - // which is indented more than the line after the end of - // the comment-block, use the level of the block before - - Sci_Position skipLine = lineNext; - int skipLevel = levelAfterComments; - - while (--skipLine > lineCurrent) { - int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL); - - if (options.foldCompact) { - if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments) - skipLevel = levelBeforeComments; - - int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG; - - styler.SetLevel(skipLine, skipLevel | whiteFlag); - } else { - if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments && - !(skipLineIndent & SC_FOLDLEVELWHITEFLAG) && - !IsCommentLine(skipLine, styler)) - skipLevel = levelBeforeComments; - - styler.SetLevel(skipLine, skipLevel); - } - } - - // Set fold header on non-quote line - if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) { - if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) - lev |= SC_FOLDLEVELHEADERFLAG; - } - - // Keep track of triple quote state of previous line - prevQuote = quote; - - // Set fold level for this line and move to next line - styler.SetLevel(lineCurrent, options.foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG); - indentCurrent = indentNext; - lineCurrent = lineNext; - } - - // NOTE: Cannot set level of last line here because indentCurrent doesn't have - // header flag set; the loop above is crafted to take care of this case! - //styler.SetLevel(lineCurrent, indentCurrent); -} - -LexerModule lmPython(SCLEX_PYTHON, LexerPython::LexerFactoryPython, "python", - pythonWordListDesc); diff --git a/qrenderdoc/3rdparty/scintilla/lexers/LexRust.cxx b/qrenderdoc/3rdparty/scintilla/lexers/LexRust.cxx deleted file mode 100644 index a834e32f4..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexers/LexRust.cxx +++ /dev/null @@ -1,838 +0,0 @@ -/** @file LexRust.cxx - ** Lexer for Rust. - ** - ** Copyright (c) 2013 by SiegeLord - ** Converted to lexer object and added further folding features/properties by "Udo Lechner" - **/ -// Copyright 1998-2005 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" -#include "OptionSet.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static const int NUM_RUST_KEYWORD_LISTS = 7; -static const int MAX_RUST_IDENT_CHARS = 1023; - -static bool IsStreamCommentStyle(int style) { - return style == SCE_RUST_COMMENTBLOCK || - style == SCE_RUST_COMMENTBLOCKDOC; -} - -// Options used for LexerRust -struct OptionsRust { - bool fold; - bool foldSyntaxBased; - bool foldComment; - bool foldCommentMultiline; - bool foldCommentExplicit; - std::string foldExplicitStart; - std::string foldExplicitEnd; - bool foldExplicitAnywhere; - bool foldCompact; - int foldAtElseInt; - bool foldAtElse; - OptionsRust() { - fold = false; - foldSyntaxBased = true; - foldComment = false; - foldCommentMultiline = true; - foldCommentExplicit = true; - foldExplicitStart = ""; - foldExplicitEnd = ""; - foldExplicitAnywhere = false; - foldCompact = true; - foldAtElseInt = -1; - foldAtElse = false; - } -}; - -static const char * const rustWordLists[NUM_RUST_KEYWORD_LISTS + 1] = { - "Primary keywords and identifiers", - "Built in types", - "Other keywords", - "Keywords 4", - "Keywords 5", - "Keywords 6", - "Keywords 7", - 0, - }; - -struct OptionSetRust : public OptionSet { - OptionSetRust() { - DefineProperty("fold", &OptionsRust::fold); - - DefineProperty("fold.comment", &OptionsRust::foldComment); - - DefineProperty("fold.compact", &OptionsRust::foldCompact); - - DefineProperty("fold.at.else", &OptionsRust::foldAtElse); - - DefineProperty("fold.rust.syntax.based", &OptionsRust::foldSyntaxBased, - "Set this property to 0 to disable syntax based folding."); - - DefineProperty("fold.rust.comment.multiline", &OptionsRust::foldCommentMultiline, - "Set this property to 0 to disable folding multi-line comments when fold.comment=1."); - - DefineProperty("fold.rust.comment.explicit", &OptionsRust::foldCommentExplicit, - "Set this property to 0 to disable folding explicit fold points when fold.comment=1."); - - DefineProperty("fold.rust.explicit.start", &OptionsRust::foldExplicitStart, - "The string to use for explicit fold start points, replacing the standard //{."); - - DefineProperty("fold.rust.explicit.end", &OptionsRust::foldExplicitEnd, - "The string to use for explicit fold end points, replacing the standard //}."); - - DefineProperty("fold.rust.explicit.anywhere", &OptionsRust::foldExplicitAnywhere, - "Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); - - DefineProperty("lexer.rust.fold.at.else", &OptionsRust::foldAtElseInt, - "This option enables Rust folding on a \"} else {\" line of an if statement."); - - DefineWordListSets(rustWordLists); - } -}; - -class LexerRust : public ILexer { - WordList keywords[NUM_RUST_KEYWORD_LISTS]; - OptionsRust options; - OptionSetRust osRust; -public: - virtual ~LexerRust() { - } - void SCI_METHOD Release() { - delete this; - } - int SCI_METHOD Version() const { - return lvOriginal; - } - const char * SCI_METHOD PropertyNames() { - return osRust.PropertyNames(); - } - int SCI_METHOD PropertyType(const char *name) { - return osRust.PropertyType(name); - } - const char * SCI_METHOD DescribeProperty(const char *name) { - return osRust.DescribeProperty(name); - } - Sci_Position SCI_METHOD PropertySet(const char *key, const char *val); - const char * SCI_METHOD DescribeWordListSets() { - return osRust.DescribeWordListSets(); - } - Sci_Position SCI_METHOD WordListSet(int n, const char *wl); - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess); - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess); - void * SCI_METHOD PrivateCall(int, void *) { - return 0; - } - static ILexer *LexerFactoryRust() { - return new LexerRust(); - } -}; - -Sci_Position SCI_METHOD LexerRust::PropertySet(const char *key, const char *val) { - if (osRust.PropertySet(&options, key, val)) { - return 0; - } - return -1; -} - -Sci_Position SCI_METHOD LexerRust::WordListSet(int n, const char *wl) { - Sci_Position firstModification = -1; - if (n < NUM_RUST_KEYWORD_LISTS) { - WordList *wordListN = &keywords[n]; - WordList wlNew; - wlNew.Set(wl); - if (*wordListN != wlNew) { - wordListN->Set(wl); - firstModification = 0; - } - } - return firstModification; -} - -static bool IsWhitespace(int c) { - return c == ' ' || c == '\t' || c == '\r' || c == '\n'; -} - -/* This isn't quite right for Unicode identifiers */ -static bool IsIdentifierStart(int ch) { - return (IsASCII(ch) && (isalpha(ch) || ch == '_')) || !IsASCII(ch); -} - -/* This isn't quite right for Unicode identifiers */ -static bool IsIdentifierContinue(int ch) { - return (IsASCII(ch) && (isalnum(ch) || ch == '_')) || !IsASCII(ch); -} - -static void ScanWhitespace(Accessor& styler, Sci_Position& pos, Sci_Position max) { - while (IsWhitespace(styler.SafeGetCharAt(pos, '\0')) && pos < max) { - if (pos == styler.LineEnd(styler.GetLine(pos))) - styler.SetLineState(styler.GetLine(pos), 0); - pos++; - } - styler.ColourTo(pos-1, SCE_RUST_DEFAULT); -} - -static void GrabString(char* s, Accessor& styler, Sci_Position start, Sci_Position len) { - for (Sci_Position ii = 0; ii < len; ii++) - s[ii] = styler[ii + start]; - s[len] = '\0'; -} - -static void ScanIdentifier(Accessor& styler, Sci_Position& pos, WordList *keywords) { - Sci_Position start = pos; - while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0'))) - pos++; - - if (styler.SafeGetCharAt(pos, '\0') == '!') { - pos++; - styler.ColourTo(pos - 1, SCE_RUST_MACRO); - } else { - char s[MAX_RUST_IDENT_CHARS + 1]; - int len = pos - start; - len = len > MAX_RUST_IDENT_CHARS ? MAX_RUST_IDENT_CHARS : len; - GrabString(s, styler, start, len); - bool keyword = false; - for (int ii = 0; ii < NUM_RUST_KEYWORD_LISTS; ii++) { - if (keywords[ii].InList(s)) { - styler.ColourTo(pos - 1, SCE_RUST_WORD + ii); - keyword = true; - break; - } - } - if (!keyword) { - styler.ColourTo(pos - 1, SCE_RUST_IDENTIFIER); - } - } -} - -/* Scans a sequence of digits, returning true if it found any. */ -static bool ScanDigits(Accessor& styler, Sci_Position& pos, int base) { - Sci_Position old_pos = pos; - for (;;) { - int c = styler.SafeGetCharAt(pos, '\0'); - if (IsADigit(c, base) || c == '_') - pos++; - else - break; - } - return old_pos != pos; -} - -/* Scans an integer and floating point literals. */ -static void ScanNumber(Accessor& styler, Sci_Position& pos) { - int base = 10; - int c = styler.SafeGetCharAt(pos, '\0'); - int n = styler.SafeGetCharAt(pos + 1, '\0'); - bool error = false; - /* Scan the prefix, thus determining the base. - * 10 is default if there's no prefix. */ - if (c == '0' && n == 'x') { - pos += 2; - base = 16; - } else if (c == '0' && n == 'b') { - pos += 2; - base = 2; - } else if (c == '0' && n == 'o') { - pos += 2; - base = 8; - } - - /* Scan initial digits. The literal is malformed if there are none. */ - error |= !ScanDigits(styler, pos, base); - /* See if there's an integer suffix. We mimic the Rust's lexer - * and munch it even if there was an error above. */ - c = styler.SafeGetCharAt(pos, '\0'); - if (c == 'u' || c == 'i') { - pos++; - c = styler.SafeGetCharAt(pos, '\0'); - n = styler.SafeGetCharAt(pos + 1, '\0'); - if (c == '8' || c == 's') { - pos++; - } else if (c == '1' && n == '6') { - pos += 2; - } else if (c == '3' && n == '2') { - pos += 2; - } else if (c == '6' && n == '4') { - pos += 2; - } else { - error = true; - } - /* See if it's a floating point literal. These literals have to be base 10. - */ - } else if (!error) { - /* If there's a period, it's a floating point literal unless it's - * followed by an identifier (meaning this is a method call, e.g. - * `1.foo()`) or another period, in which case it's a range (e.g. 1..2) - */ - n = styler.SafeGetCharAt(pos + 1, '\0'); - if (c == '.' && !(IsIdentifierStart(n) || n == '.')) { - error |= base != 10; - pos++; - /* It's ok to have no digits after the period. */ - ScanDigits(styler, pos, 10); - } - - /* Look for the exponentiation. */ - c = styler.SafeGetCharAt(pos, '\0'); - if (c == 'e' || c == 'E') { - error |= base != 10; - pos++; - c = styler.SafeGetCharAt(pos, '\0'); - if (c == '-' || c == '+') - pos++; - /* It is invalid to have no digits in the exponent. */ - error |= !ScanDigits(styler, pos, 10); - } - - /* Scan the floating point suffix. */ - c = styler.SafeGetCharAt(pos, '\0'); - if (c == 'f') { - error |= base != 10; - pos++; - c = styler.SafeGetCharAt(pos, '\0'); - n = styler.SafeGetCharAt(pos + 1, '\0'); - if (c == '3' && n == '2') { - pos += 2; - } else if (c == '6' && n == '4') { - pos += 2; - } else { - error = true; - } - } - } - - if (error) - styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); - else - styler.ColourTo(pos - 1, SCE_RUST_NUMBER); -} - -static bool IsOneCharOperator(int c) { - return c == ';' || c == ',' || c == '(' || c == ')' - || c == '{' || c == '}' || c == '[' || c == ']' - || c == '@' || c == '#' || c == '~' || c == '+' - || c == '*' || c == '/' || c == '^' || c == '%' - || c == '.' || c == ':' || c == '!' || c == '<' - || c == '>' || c == '=' || c == '-' || c == '&' - || c == '|' || c == '$' || c == '?'; -} - -static bool IsTwoCharOperator(int c, int n) { - return (c == '.' && n == '.') || (c == ':' && n == ':') - || (c == '!' && n == '=') || (c == '<' && n == '<') - || (c == '<' && n == '=') || (c == '>' && n == '>') - || (c == '>' && n == '=') || (c == '=' && n == '=') - || (c == '=' && n == '>') || (c == '-' && n == '>') - || (c == '&' && n == '&') || (c == '|' && n == '|') - || (c == '-' && n == '=') || (c == '&' && n == '=') - || (c == '|' && n == '=') || (c == '+' && n == '=') - || (c == '*' && n == '=') || (c == '/' && n == '=') - || (c == '^' && n == '=') || (c == '%' && n == '='); -} - -static bool IsThreeCharOperator(int c, int n, int n2) { - return (c == '<' && n == '<' && n2 == '=') - || (c == '>' && n == '>' && n2 == '='); -} - -static bool IsValidCharacterEscape(int c) { - return c == 'n' || c == 'r' || c == 't' || c == '\\' - || c == '\'' || c == '"' || c == '0'; -} - -static bool IsValidStringEscape(int c) { - return IsValidCharacterEscape(c) || c == '\n' || c == '\r'; -} - -static bool ScanNumericEscape(Accessor &styler, Sci_Position& pos, Sci_Position num_digits, bool stop_asap) { - for (;;) { - int c = styler.SafeGetCharAt(pos, '\0'); - if (!IsADigit(c, 16)) - break; - num_digits--; - pos++; - if (num_digits == 0 && stop_asap) - return true; - } - if (num_digits == 0) { - return true; - } else { - return false; - } -} - -/* This is overly permissive for character literals in order to accept UTF-8 encoded - * character literals. */ -static void ScanCharacterLiteralOrLifetime(Accessor &styler, Sci_Position& pos, bool ascii_only) { - pos++; - int c = styler.SafeGetCharAt(pos, '\0'); - int n = styler.SafeGetCharAt(pos + 1, '\0'); - bool done = false; - bool valid_lifetime = !ascii_only && IsIdentifierStart(c); - bool valid_char = true; - bool first = true; - while (!done) { - switch (c) { - case '\\': - done = true; - if (IsValidCharacterEscape(n)) { - pos += 2; - } else if (n == 'x') { - pos += 2; - valid_char = ScanNumericEscape(styler, pos, 2, false); - } else if (n == 'u' && !ascii_only) { - pos += 2; - if (styler.SafeGetCharAt(pos, '\0') != '{') { - // old-style - valid_char = ScanNumericEscape(styler, pos, 4, false); - } else { - int n_digits = 0; - while (IsADigit(styler.SafeGetCharAt(++pos, '\0'), 16) && n_digits++ < 6) { - } - if (n_digits > 0 && styler.SafeGetCharAt(pos, '\0') == '}') - pos++; - else - valid_char = false; - } - } else if (n == 'U' && !ascii_only) { - pos += 2; - valid_char = ScanNumericEscape(styler, pos, 8, false); - } else { - valid_char = false; - } - break; - case '\'': - valid_char = !first; - done = true; - break; - case '\t': - case '\n': - case '\r': - case '\0': - valid_char = false; - done = true; - break; - default: - if (ascii_only && !IsASCII((char)c)) { - done = true; - valid_char = false; - } else if (!IsIdentifierContinue(c) && !first) { - done = true; - } else { - pos++; - } - break; - } - c = styler.SafeGetCharAt(pos, '\0'); - n = styler.SafeGetCharAt(pos + 1, '\0'); - - first = false; - } - if (styler.SafeGetCharAt(pos, '\0') == '\'') { - valid_lifetime = false; - } else { - valid_char = false; - } - if (valid_lifetime) { - styler.ColourTo(pos - 1, SCE_RUST_LIFETIME); - } else if (valid_char) { - pos++; - styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTECHARACTER : SCE_RUST_CHARACTER); - } else { - styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); - } -} - -enum CommentState { - UnknownComment, - DocComment, - NotDocComment -}; - -/* - * The rule for block-doc comments is as follows: /xxN and /x! (where x is an asterisk, N is a non-asterisk) start doc comments. - * Otherwise it's a regular comment. - */ -static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position max, CommentState state, int level) { - int c = styler.SafeGetCharAt(pos, '\0'); - bool maybe_doc_comment = false; - if (c == '*') { - int n = styler.SafeGetCharAt(pos + 1, '\0'); - if (n != '*' && n != '/') { - maybe_doc_comment = true; - } - } else if (c == '!') { - maybe_doc_comment = true; - } - - for (;;) { - int n = styler.SafeGetCharAt(pos + 1, '\0'); - if (pos == styler.LineEnd(styler.GetLine(pos))) - styler.SetLineState(styler.GetLine(pos), level); - if (c == '*') { - pos++; - if (n == '/') { - pos++; - level--; - if (level == 0) { - styler.SetLineState(styler.GetLine(pos), 0); - if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) - styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCKDOC); - else - styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCK); - break; - } - } - } else if (c == '/') { - pos++; - if (n == '*') { - pos++; - level++; - } - } - else { - pos++; - } - if (pos >= max) { - if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) - styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCKDOC); - else - styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCK); - break; - } - c = styler.SafeGetCharAt(pos, '\0'); - } -} - -/* - * The rule for line-doc comments is as follows... ///N and //! (where N is a non slash) start doc comments. - * Otherwise it's a normal line comment. - */ -static void ResumeLineComment(Accessor &styler, Sci_Position& pos, Sci_Position max, CommentState state) { - bool maybe_doc_comment = false; - int c = styler.SafeGetCharAt(pos, '\0'); - if (c == '/') { - if (pos < max) { - pos++; - c = styler.SafeGetCharAt(pos, '\0'); - if (c != '/') { - maybe_doc_comment = true; - } - } - } else if (c == '!') { - maybe_doc_comment = true; - } - - while (pos < max && c != '\n') { - if (pos == styler.LineEnd(styler.GetLine(pos))) - styler.SetLineState(styler.GetLine(pos), 0); - pos++; - c = styler.SafeGetCharAt(pos, '\0'); - } - - if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) - styler.ColourTo(pos - 1, SCE_RUST_COMMENTLINEDOC); - else - styler.ColourTo(pos - 1, SCE_RUST_COMMENTLINE); -} - -static void ScanComments(Accessor &styler, Sci_Position& pos, Sci_Position max) { - pos++; - int c = styler.SafeGetCharAt(pos, '\0'); - pos++; - if (c == '/') - ResumeLineComment(styler, pos, max, UnknownComment); - else if (c == '*') - ResumeBlockComment(styler, pos, max, UnknownComment, 1); -} - -static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max, bool ascii_only) { - int c = styler.SafeGetCharAt(pos, '\0'); - bool error = false; - while (c != '"' && !error) { - if (pos >= max) { - error = true; - break; - } - if (pos == styler.LineEnd(styler.GetLine(pos))) - styler.SetLineState(styler.GetLine(pos), 0); - if (c == '\\') { - int n = styler.SafeGetCharAt(pos + 1, '\0'); - if (IsValidStringEscape(n)) { - pos += 2; - } else if (n == 'x') { - pos += 2; - error = !ScanNumericEscape(styler, pos, 2, true); - } else if (n == 'u' && !ascii_only) { - pos += 2; - if (styler.SafeGetCharAt(pos, '\0') != '{') { - // old-style - error = !ScanNumericEscape(styler, pos, 4, true); - } else { - int n_digits = 0; - while (IsADigit(styler.SafeGetCharAt(++pos, '\0'), 16) && n_digits++ < 6) { - } - if (n_digits > 0 && styler.SafeGetCharAt(pos, '\0') == '}') - pos++; - else - error = true; - } - } else if (n == 'U' && !ascii_only) { - pos += 2; - error = !ScanNumericEscape(styler, pos, 8, true); - } else { - pos += 1; - error = true; - } - } else { - if (ascii_only && !IsASCII((char)c)) - error = true; - else - pos++; - } - c = styler.SafeGetCharAt(pos, '\0'); - } - if (!error) - pos++; - styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTESTRING : SCE_RUST_STRING); -} - -static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, int num_hashes, bool ascii_only) { - for (;;) { - if (pos == styler.LineEnd(styler.GetLine(pos))) - styler.SetLineState(styler.GetLine(pos), num_hashes); - - int c = styler.SafeGetCharAt(pos, '\0'); - if (c == '"') { - pos++; - int trailing_num_hashes = 0; - while (styler.SafeGetCharAt(pos, '\0') == '#' && trailing_num_hashes < num_hashes) { - trailing_num_hashes++; - pos++; - } - if (trailing_num_hashes == num_hashes) { - styler.SetLineState(styler.GetLine(pos), 0); - break; - } - } else if (pos >= max) { - break; - } else { - if (ascii_only && !IsASCII((char)c)) - break; - pos++; - } - } - styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTESTRINGR : SCE_RUST_STRINGR); -} - -static void ScanRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, bool ascii_only) { - pos++; - int num_hashes = 0; - while (styler.SafeGetCharAt(pos, '\0') == '#') { - num_hashes++; - pos++; - } - if (styler.SafeGetCharAt(pos, '\0') != '"') { - styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); - } else { - pos++; - ResumeRawString(styler, pos, max, num_hashes, ascii_only); - } -} - -void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - PropSetSimple props; - Accessor styler(pAccess, &props); - Sci_Position pos = startPos; - Sci_Position max = pos + length; - - styler.StartAt(pos); - styler.StartSegment(pos); - - if (initStyle == SCE_RUST_COMMENTBLOCK || initStyle == SCE_RUST_COMMENTBLOCKDOC) { - ResumeBlockComment(styler, pos, max, initStyle == SCE_RUST_COMMENTBLOCKDOC ? DocComment : NotDocComment, styler.GetLineState(styler.GetLine(pos) - 1)); - } else if (initStyle == SCE_RUST_COMMENTLINE || initStyle == SCE_RUST_COMMENTLINEDOC) { - ResumeLineComment(styler, pos, max, initStyle == SCE_RUST_COMMENTLINEDOC ? DocComment : NotDocComment); - } else if (initStyle == SCE_RUST_STRING) { - ResumeString(styler, pos, max, false); - } else if (initStyle == SCE_RUST_BYTESTRING) { - ResumeString(styler, pos, max, true); - } else if (initStyle == SCE_RUST_STRINGR) { - ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), false); - } else if (initStyle == SCE_RUST_BYTESTRINGR) { - ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), true); - } - - while (pos < max) { - int c = styler.SafeGetCharAt(pos, '\0'); - int n = styler.SafeGetCharAt(pos + 1, '\0'); - int n2 = styler.SafeGetCharAt(pos + 2, '\0'); - - if (pos == 0 && c == '#' && n == '!' && n2 != '[') { - pos += 2; - ResumeLineComment(styler, pos, max, NotDocComment); - } else if (IsWhitespace(c)) { - ScanWhitespace(styler, pos, max); - } else if (c == '/' && (n == '/' || n == '*')) { - ScanComments(styler, pos, max); - } else if (c == 'r' && (n == '#' || n == '"')) { - ScanRawString(styler, pos, max, false); - } else if (c == 'b' && n == 'r' && (n2 == '#' || n2 == '"')) { - pos++; - ScanRawString(styler, pos, max, true); - } else if (c == 'b' && n == '"') { - pos += 2; - ResumeString(styler, pos, max, true); - } else if (c == 'b' && n == '\'') { - pos++; - ScanCharacterLiteralOrLifetime(styler, pos, true); - } else if (IsIdentifierStart(c)) { - ScanIdentifier(styler, pos, keywords); - } else if (IsADigit(c)) { - ScanNumber(styler, pos); - } else if (IsThreeCharOperator(c, n, n2)) { - pos += 3; - styler.ColourTo(pos - 1, SCE_RUST_OPERATOR); - } else if (IsTwoCharOperator(c, n)) { - pos += 2; - styler.ColourTo(pos - 1, SCE_RUST_OPERATOR); - } else if (IsOneCharOperator(c)) { - pos++; - styler.ColourTo(pos - 1, SCE_RUST_OPERATOR); - } else if (c == '\'') { - ScanCharacterLiteralOrLifetime(styler, pos, false); - } else if (c == '"') { - pos++; - ResumeString(styler, pos, max, false); - } else { - pos++; - styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); - } - } - styler.ColourTo(pos - 1, SCE_RUST_DEFAULT); - styler.Flush(); -} - -void SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - - if (!options.fold) - return; - - LexAccessor styler(pAccess); - - Sci_PositionU endPos = startPos + length; - int visibleChars = 0; - bool inLineComment = false; - Sci_Position lineCurrent = styler.GetLine(startPos); - int levelCurrent = SC_FOLDLEVELBASE; - if (lineCurrent > 0) - levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; - Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1); - int levelMinCurrent = levelCurrent; - int levelNext = levelCurrent; - char chNext = styler[startPos]; - int styleNext = styler.StyleAt(startPos); - int style = initStyle; - const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); - for (Sci_PositionU i = startPos; i < endPos; i++) { - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - int stylePrev = style; - style = styleNext; - styleNext = styler.StyleAt(i + 1); - bool atEOL = i == (lineStartNext-1); - if ((style == SCE_RUST_COMMENTLINE) || (style == SCE_RUST_COMMENTLINEDOC)) - inLineComment = true; - if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) { - if (!IsStreamCommentStyle(stylePrev)) { - levelNext++; - } else if (!IsStreamCommentStyle(styleNext) && !atEOL) { - // Comments don't end at end of line and the next character may be unstyled. - levelNext--; - } - } - if (options.foldComment && options.foldCommentExplicit && ((style == SCE_RUST_COMMENTLINE) || options.foldExplicitAnywhere)) { - if (userDefinedFoldMarkers) { - if (styler.Match(i, options.foldExplicitStart.c_str())) { - levelNext++; - } else if (styler.Match(i, options.foldExplicitEnd.c_str())) { - levelNext--; - } - } else { - if ((ch == '/') && (chNext == '/')) { - char chNext2 = styler.SafeGetCharAt(i + 2); - if (chNext2 == '{') { - levelNext++; - } else if (chNext2 == '}') { - levelNext--; - } - } - } - } - if (options.foldSyntaxBased && (style == SCE_RUST_OPERATOR)) { - if (ch == '{') { - // Measure the minimum before a '{' to allow - // folding on "} else {" - if (levelMinCurrent > levelNext) { - levelMinCurrent = levelNext; - } - levelNext++; - } else if (ch == '}') { - levelNext--; - } - } - if (!IsASpace(ch)) - visibleChars++; - if (atEOL || (i == endPos-1)) { - int levelUse = levelCurrent; - if (options.foldSyntaxBased && options.foldAtElse) { - levelUse = levelMinCurrent; - } - int lev = levelUse | levelNext << 16; - if (visibleChars == 0 && options.foldCompact) - lev |= SC_FOLDLEVELWHITEFLAG; - if (levelUse < levelNext) - lev |= SC_FOLDLEVELHEADERFLAG; - if (lev != styler.LevelAt(lineCurrent)) { - styler.SetLevel(lineCurrent, lev); - } - lineCurrent++; - lineStartNext = styler.LineStart(lineCurrent+1); - levelCurrent = levelNext; - levelMinCurrent = levelCurrent; - if (atEOL && (i == static_cast(styler.Length()-1))) { - // There is an empty line at end of file so give it same level and empty - styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); - } - visibleChars = 0; - inLineComment = false; - } - } -} - -LexerModule lmRust(SCLEX_RUST, LexerRust::LexerFactoryRust, "rust", rustWordLists); diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/Accessor.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/Accessor.cxx deleted file mode 100644 index f8b46ef88..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/Accessor.cxx +++ /dev/null @@ -1,79 +0,0 @@ -// Scintilla source code edit control -/** @file Accessor.cxx - ** Interfaces between Scintilla and lexers. - **/ -// Copyright 1998-2002 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) { -} - -int Accessor::GetPropertyInt(const char *key, int defaultValue) const { - return pprops->GetInt(key, defaultValue); -} - -int Accessor::IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) { - Sci_Position end = Length(); - int spaceFlags = 0; - - // Determines the indentation level of the current line and also checks for consistent - // indentation compared to the previous line. - // Indentation is judged consistent when the indentation whitespace of each line lines - // the same or the indentation of one line is a prefix of the other. - - Sci_Position pos = LineStart(line); - char ch = (*this)[pos]; - int indent = 0; - bool inPrevPrefix = line > 0; - Sci_Position posPrev = inPrevPrefix ? LineStart(line-1) : 0; - while ((ch == ' ' || ch == '\t') && (pos < end)) { - if (inPrevPrefix) { - char chPrev = (*this)[posPrev++]; - if (chPrev == ' ' || chPrev == '\t') { - if (chPrev != ch) - spaceFlags |= wsInconsistent; - } else { - inPrevPrefix = false; - } - } - if (ch == ' ') { - spaceFlags |= wsSpace; - indent++; - } else { // Tab - spaceFlags |= wsTab; - if (spaceFlags & wsSpace) - spaceFlags |= wsSpaceTab; - indent = (indent / 8 + 1) * 8; - } - ch = (*this)[++pos]; - } - - *flags = spaceFlags; - indent += SC_FOLDLEVELBASE; - // if completely empty line or the start of a comment... - if ((LineStart(line) == Length()) || (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') || - (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos))) - return indent | SC_FOLDLEVELWHITEFLAG; - else - return indent; -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/Accessor.h b/qrenderdoc/3rdparty/scintilla/lexlib/Accessor.h deleted file mode 100644 index 00b2a54da..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/Accessor.h +++ /dev/null @@ -1,35 +0,0 @@ -// Scintilla source code edit control -/** @file Accessor.h - ** Interfaces between Scintilla and lexers. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef ACCESSOR_H -#define ACCESSOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -enum { wsSpace=1, wsTab=2, wsSpaceTab=4, wsInconsistent=8 }; - -class Accessor; -class WordList; -class PropSetSimple; - -typedef bool (*PFNIsCommentLeader)(Accessor &styler, Sci_Position pos, Sci_Position len); - -class Accessor : public LexAccessor { -public: - PropSetSimple *pprops; - Accessor(IDocument *pAccess_, PropSetSimple *pprops_); - int GetPropertyInt(const char *, int defaultValue=0) const; - int IndentAmount(Sci_Position line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.cxx deleted file mode 100644 index 2be46c013..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.cxx +++ /dev/null @@ -1,3304 +0,0 @@ -// Scintilla source code edit control -/** @file CharacterCategory.cxx - ** Returns the Unicode general category of a character. - ** Table automatically regenerated by scripts/GenerateCharacterCategory.py - ** Should only be rarely regenerated for new versions of Unicode. - **/ -// Copyright 2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include "StringCopy.h" -#include "CharacterCategory.h" - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -namespace { - // Use an unnamed namespace to protect the declarations from name conflicts - -const int catRanges[] = { -//++Autogenerated -- start of section automatically generated -// Created with Python 3.3.0, Unicode 6.1.0 -25, -1046, -1073, -1171, -1201, -1293, -1326, -1361, -1394, -1425, -1452, -1489, -1544, -1873, -1938, -2033, -2080, -2925, -2961, -2990, -3028, -3051, -3092, -3105, -3949, -3986, -4014, -4050, -4089, -5142, -5169, -5203, -5333, -5361, -5396, -5429, -5444, -5487, -5522, -5562, -5589, -5620, -5653, -5682, -5706, -5780, -5793, -5841, -5908, -5930, -5956, -6000, -6026, -6129, -6144, -6898, -6912, -7137, -7922, -7937, -8192, -8225, -8256, -8289, -8320, -8353, -8384, -8417, -8448, -8481, -8512, -8545, -8576, -8609, -8640, -8673, -8704, -8737, -8768, -8801, -8832, -8865, -8896, -8929, -8960, -8993, -9024, -9057, -9088, -9121, -9152, -9185, -9216, -9249, -9280, -9313, -9344, -9377, -9408, -9441, -9472, -9505, -9536, -9569, -9600, -9633, -9664, -9697, -9728, -9761, -9792, -9825, -9856, -9889, -9920, -9953, -10016, -10049, -10080, -10113, -10144, -10177, -10208, -10241, -10272, -10305, -10336, -10369, -10400, -10433, -10464, -10497, -10560, -10593, -10624, -10657, -10688, -10721, -10752, -10785, -10816, -10849, -10880, -10913, -10944, -10977, -11008, -11041, -11072, -11105, -11136, -11169, -11200, -11233, -11264, -11297, -11328, -11361, -11392, -11425, -11456, -11489, -11520, -11553, -11584, -11617, -11648, -11681, -11712, -11745, -11776, -11809, -11840, -11873, -11904, -11937, -11968, -12001, -12032, -12097, -12128, -12161, -12192, -12225, -12320, -12385, -12416, -12449, -12480, -12545, -12576, -12673, -12736, -12865, -12896, -12961, -12992, -13089, -13184, -13249, -13280, -13345, -13376, -13409, -13440, -13473, -13504, -13569, -13600, -13633, -13696, -13729, -13760, -13825, -13856, -13953, -13984, -14017, -14048, -14113, -14180, -14208, -14241, -14340, -14464, -14498, -14529, -14560, -14594, -14625, -14656, -14690, -14721, -14752, -14785, -14816, -14849, -14880, -14913, -14944, -14977, -15008, -15041, -15072, -15105, -15136, -15169, -15200, -15233, -15296, -15329, -15360, -15393, -15424, -15457, -15488, -15521, -15552, -15585, -15616, -15649, -15680, -15713, -15744, -15777, -15808, -15841, -15904, -15938, -15969, -16000, -16033, -16064, -16161, -16192, -16225, -16256, -16289, -16320, -16353, -16384, -16417, -16448, -16481, -16512, -16545, -16576, -16609, -16640, -16673, -16704, -16737, -16768, -16801, -16832, -16865, -16896, -16929, -16960, -16993, -17024, -17057, -17088, -17121, -17152, -17185, -17216, -17249, -17280, -17313, -17344, -17377, -17408, -17441, -17472, -17505, -17536, -17569, -17600, -17633, -17664, -17697, -17728, -17761, -17792, -17825, -17856, -17889, -17920, -17953, -17984, -18017, -18240, -18305, -18336, -18401, -18464, -18497, -18528, -18657, -18688, -18721, -18752, -18785, -18816, -18849, -18880, -18913, -21124, -21153, -22019, -22612, -22723, -23124, -23555, -23732, -23939, -23988, -24003, -24052, -24581, -28160, -28193, -28224, -28257, -28291, -28340, -28352, -28385, -28445, -28483, -28513, -28625, -28669, -28820, -28864, -28913, -28928, -29053, -29056, -29117, -29120, -29185, -29216, -29789, -29792, -30081, -31200, -31233, -31296, -31393, -31488, -31521, -31552, -31585, -31616, -31649, -31680, -31713, -31744, -31777, -31808, -31841, -31872, -31905, -31936, -31969, -32000, -32033, -32064, -32097, -32128, -32161, -32192, -32225, -32384, -32417, -32466, -32480, -32513, -32544, -32609, -32672, -34305, -35840, -35873, -35904, -35937, -35968, -36001, -36032, -36065, -36096, -36129, -36160, -36193, -36224, -36257, -36288, -36321, -36352, -36385, -36416, -36449, -36480, -36513, -36544, -36577, -36608, -36641, -36672, -36705, -36736, -36769, -36800, -36833, -36864, -36897, -36949, -36965, -37127, -37184, -37217, -37248, -37281, -37312, -37345, -37376, -37409, -37440, -37473, -37504, -37537, -37568, -37601, -37632, -37665, -37696, -37729, -37760, -37793, -37824, -37857, -37888, -37921, -37952, -37985, -38016, -38049, -38080, -38113, -38144, -38177, -38208, -38241, -38272, -38305, -38336, -38369, -38400, -38433, -38464, -38497, -38528, -38561, -38592, -38625, -38656, -38689, -38720, -38753, -38784, -38817, -38848, -38881, -38912, -38977, -39008, -39041, -39072, -39105, -39136, -39169, -39200, -39233, -39264, -39297, -39328, -39361, -39424, -39457, -39488, -39521, -39552, -39585, -39616, -39649, -39680, -39713, -39744, -39777, -39808, -39841, -39872, -39905, -39936, -39969, -40000, -40033, -40064, -40097, -40128, -40161, -40192, -40225, -40256, -40289, -40320, -40353, -40384, -40417, -40448, -40481, -40512, -40545, -40576, -40609, -40640, -40673, -40704, -40737, -40768, -40801, -40832, -40865, -40896, -40929, -40960, -40993, -41024, -41057, -41088, -41121, -41152, -41185, -41216, -41249, -41280, -41313, -41344, -41377, -41408, -41441, -41472, -41505, -41536, -41569, -41600, -41633, -41664, -41697, -41728, -41761, -41792, -41825, -41856, -41889, -41920, -41953, -41984, -42017, -42048, -42081, -42112, -42145, -42176, -42209, -42269, -42528, -43773, -43811, -43857, -44061, -44065, -45341, -45361, -45388, -45437, -45555, -45597, -45605, -47052, -47077, -47121, -47141, -47217, -47237, -47313, -47333, -47389, -47620, -48509, -48644, -48753, -48829, -49178, -49341, -49362, -49457, -49523, -49553, -49621, -49669, -50033, -50077, -50129, -50180, -51203, -51236, -51557, -52232, -52561, -52676, -52741, -52772, -55953, -55972, -56005, -56250, -56277, -56293, -56483, -56549, -56629, -56645, -56772, -56840, -57156, -57269, -57316, -57361, -57821, -57850, -57860, -57893, -57924, -58885, -59773, -59812, -62661, -63012, -63069, -63496, -63812, -64869, -65155, -65237, -65265, -65347, -65405, -65540, -66245, -66371, -66405, -66691, -66725, -66819, -66853, -67037, -67089, -67581, -67588, -68389, -68509, -68561, -68605, -70660, -70717, -70724, -71101, -72837, -73725, -73733, -73830, -73860, -75589, -75622, -75653, -75684, -75718, -75813, -76070, -76197, -76230, -76292, -76325, -76548, -76869, -76945, -77000, -77329, -77347, -77380, -77597, -77604, -77853, -77861, -77894, -77981, -77988, -78269, -78308, -78397, -78436, -79165, -79172, -79421, -79428, -79485, -79556, -79709, -79749, -79780, -79814, -79909, -80061, -80102, -80189, -80230, -80293, -80324, -80381, -80614, -80669, -80772, -80861, -80868, -80965, -81053, -81096, -81412, -81491, -81546, -81749, -81779, -81821, -81957, -82022, -82077, -82084, -82301, -82404, -82493, -82532, -83261, -83268, -83517, -83524, -83613, -83620, -83709, -83716, -83805, -83845, -83901, -83910, -84005, -84093, -84197, -84285, -84325, -84445, -84517, -84573, -84772, -84925, -84932, -84989, -85192, -85509, -85572, -85669, -85725, -86053, -86118, -86173, -86180, -86493, -86500, -86621, -86628, -87357, -87364, -87613, -87620, -87709, -87716, -87901, -87941, -87972, -88006, -88101, -88285, -88293, -88358, -88413, -88422, -88485, -88541, -88580, -88637, -89092, -89157, -89245, -89288, -89617, -89651, -89693, -90149, -90182, -90269, -90276, -90557, -90596, -90685, -90724, -91453, -91460, -91709, -91716, -91805, -91812, -91997, -92037, -92068, -92102, -92133, -92166, -92197, -92349, -92390, -92477, -92518, -92581, -92637, -92869, -92902, -92957, -93060, -93149, -93156, -93253, -93341, -93384, -93717, -93732, -93770, -93981, -94277, -94308, -94365, -94372, -94589, -94660, -94781, -94788, -94941, -95012, -95101, -95108, -95165, -95172, -95261, -95332, -95421, -95492, -95613, -95684, -96093, -96198, -96261, -96294, -96381, -96454, -96573, -96582, -96677, -96733, -96772, -96829, -96998, -97053, -97480, -97802, -97909, -98099, -98133, -98173, -98342, -98461, -98468, -98749, -98756, -98877, -98884, -99645, -99652, -99997, -100004, -100189, -100260, -100293, -100390, -100541, -100549, -100669, -100677, -100829, -101029, -101117, -101124, -101213, -101380, -101445, -101533, -101576, -101917, -102154, -102389, -102429, -102470, -102557, -102564, -102845, -102852, -102973, -102980, -103741, -103748, -104093, -104100, -104285, -104325, -104356, -104390, -104421, -104454, -104637, -104645, -104678, -104765, -104774, -104837, -104925, -105126, -105213, -105412, -105469, -105476, -105541, -105629, -105672, -106013, -106020, -106109, -106566, -106653, -106660, -106941, -106948, -107069, -107076, -108413, -108452, -108486, -108581, -108733, -108742, -108861, -108870, -108965, -108996, -109053, -109286, -109341, -109572, -109637, -109725, -109768, -110090, -110301, -110389, -110404, -110621, -110662, -110749, -110756, -111357, -111428, -112221, -112228, -112541, -112548, -112605, -112644, -112893, -112965, -113021, -113126, -113221, -113341, -113349, -113405, -113414, -113693, -114246, -114321, -114365, -114724, -116261, -116292, -116357, -116605, -116723, -116740, -116931, -116965, -117233, -117256, -117585, -117661, -118820, -118909, -118916, -118973, -119012, -119101, -119108, -119165, -119204, -119261, -119428, -119581, -119588, -119837, -119844, -119965, -119972, -120029, -120036, -120093, -120132, -120221, -120228, -120357, -120388, -120453, -120669, -120677, -120740, -120797, -120836, -121021, -121027, -121085, -121093, -121309, -121352, -121693, -121732, -121885, -122884, -122933, -123025, -123509, -123537, -123573, -123653, -123733, -123912, -124234, -124565, -124581, -124629, -124645, -124693, -124709, -124749, -124782, -124813, -124846, -124870, -124932, -125213, -125220, -126397, -126501, -126950, -126981, -127153, -127173, -127236, -127397, -127773, -127781, -128957, -128981, -129221, -129269, -129469, -129493, -129553, -129717, -129841, -129917, -131076, -132454, -132517, -132646, -132677, -132870, -132901, -132966, -133029, -133092, -133128, -133457, -133636, -133830, -133893, -133956, -134085, -134180, -134214, -134308, -134374, -134596, -134693, -134820, -135237, -135270, -135333, -135398, -135589, -135620, -135654, -135688, -136006, -136101, -136149, -136192, -137437, -137440, -137501, -137632, -137693, -137732, -139121, -139139, -139172, -149821, -149828, -149981, -150020, -150269, -150276, -150333, -150340, -150493, -150532, -151869, -151876, -152029, -152068, -153149, -153156, -153309, -153348, -153597, -153604, -153661, -153668, -153821, -153860, -154365, -154372, -156221, -156228, -156381, -156420, -158589, -158629, -158737, -159018, -159677, -159748, -160277, -160605, -160772, -163517, -163852, -163876, -183729, -183780, -184342, -184356, -185197, -185230, -185277, -185348, -187761, -187849, -187965, -188420, -188861, -188868, -188997, -189117, -189444, -190021, -190129, -190205, -190468, -191045, -191133, -191492, -191933, -191940, -192061, -192069, -192157, -192516, -194181, -194246, -194277, -194502, -194757, -194790, -194853, -195217, -195299, -195345, -195443, -195460, -195493, -195549, -195592, -195933, -196106, -196445, -196625, -196812, -196849, -196965, -197078, -197117, -197128, -197469, -197636, -198755, -198788, -200477, -200708, -202021, -202052, -202109, -202244, -204509, -204804, -205757, -205829, -205926, -206053, -206118, -206237, -206342, -206405, -206438, -206629, -206749, -206869, -206909, -206993, -207048, -207364, -208349, -208388, -208573, -208900, -210333, -210438, -210980, -211206, -211293, -211464, -211786, -211837, -211925, -212996, -213733, -213798, -213917, -213969, -214020, -215718, -215749, -215782, -215813, -216061, -216069, -216102, -216133, -216166, -216229, -216486, -216677, -217021, -217061, -217096, -217437, -217608, -217949, -218129, -218339, -218385, -218589, -221189, -221318, -221348, -222853, -222886, -222917, -223078, -223109, -223142, -223301, -223334, -223396, -223645, -223752, -224081, -224309, -224613, -224917, -225213, -225285, -225350, -225380, -226342, -226373, -226502, -226565, -226630, -226661, -226694, -226756, -226824, -227140, -228549, -228582, -228613, -228678, -228773, -228806, -228837, -228934, -229021, -229265, -229380, -230534, -230789, -231046, -231109, -231197, -231281, -231432, -231773, -231844, -231944, -232260, -233219, -233425, -233501, -235537, -235805, -236037, -236145, -236165, -236582, -236613, -236836, -236965, -236996, -237126, -237189, -237220, -237309, -237569, -238979, -240993, -241411, -241441, -242531, -243717, -244989, -245637, -245760, -245793, -245824, -245857, -245888, -245921, -245952, -245985, -246016, -246049, -246080, -246113, -246144, -246177, -246208, -246241, -246272, -246305, -246336, -246369, -246400, -246433, -246464, -246497, -246528, -246561, -246592, -246625, -246656, -246689, -246720, -246753, -246784, -246817, -246848, -246881, -246912, -246945, -246976, -247009, -247040, -247073, -247104, -247137, -247168, -247201, -247232, -247265, -247296, -247329, -247360, -247393, -247424, -247457, -247488, -247521, -247552, -247585, -247616, -247649, -247680, -247713, -247744, -247777, -247808, -247841, -247872, -247905, -247936, -247969, -248000, -248033, -248064, -248097, -248128, -248161, -248192, -248225, -248256, -248289, -248320, -248353, -248384, -248417, -248448, -248481, -248512, -248545, -248576, -248609, -248640, -248673, -248704, -248737, -248768, -248801, -248832, -248865, -248896, -248929, -248960, -248993, -249024, -249057, -249088, -249121, -249152, -249185, -249216, -249249, -249280, -249313, -249344, -249377, -249408, -249441, -249472, -249505, -249536, -249569, -249600, -249633, -249664, -249697, -249728, -249761, -249792, -249825, -249856, -249889, -249920, -249953, -249984, -250017, -250048, -250081, -250112, -250145, -250176, -250209, -250240, -250273, -250304, -250337, -250368, -250401, -250432, -250465, -250496, -250529, -250816, -250849, -250880, -250913, -250944, -250977, -251008, -251041, -251072, -251105, -251136, -251169, -251200, -251233, -251264, -251297, -251328, -251361, -251392, -251425, -251456, -251489, -251520, -251553, -251584, -251617, -251648, -251681, -251712, -251745, -251776, -251809, -251840, -251873, -251904, -251937, -251968, -252001, -252032, -252065, -252096, -252129, -252160, -252193, -252224, -252257, -252288, -252321, -252352, -252385, -252416, -252449, -252480, -252513, -252544, -252577, -252608, -252641, -252672, -252705, -252736, -252769, -252800, -252833, -252864, -252897, -252928, -252961, -252992, -253025, -253056, -253089, -253120, -253153, -253184, -253217, -253248, -253281, -253312, -253345, -253376, -253409, -253440, -253473, -253504, -253537, -253568, -253601, -253632, -253665, -253696, -253729, -253760, -253793, -253824, -253857, -253888, -253921, -254208, -254465, -254685, -254720, -254941, -254977, -255232, -255489, -255744, -256001, -256221, -256256, -256477, -256513, -256797, -256800, -256861, -256864, -256925, -256928, -256989, -256992, -257025, -257280, -257537, -258013, -258049, -258306, -258561, -258818, -259073, -259330, -259585, -259773, -259777, -259840, -259970, -260020, -260033, -260084, -260161, -260285, -260289, -260352, -260482, -260532, -260609, -260765, -260801, -260864, -261021, -261044, -261121, -261376, -261556, -261661, -261697, -261821, -261825, -261888, -262018, -262068, -262141, -262166, -262522, -262668, -262865, -262927, -262960, -262989, -263023, -263088, -263117, -263151, -263185, -263447, -263480, -263514, -263670, -263697, -263983, -264016, -264049, -264171, -264241, -264338, -264365, -264398, -264433, -264786, -264817, -264843, -264881, -265206, -265242, -265405, -265562, -265738, -265763, -265821, -265866, -266066, -266157, -266190, -266211, -266250, -266578, -266669, -266702, -266749, -266755, -267197, -267283, -268125, -268805, -269223, -269349, -269383, -269477, -269885, -270357, -270400, -270453, -270560, -270613, -270657, -270688, -270785, -270848, -270945, -270997, -271008, -271061, -271122, -271136, -271317, -271488, -271541, -271552, -271605, -271616, -271669, -271680, -271829, -271841, -271872, -272001, -272036, -272161, -272213, -272257, -272320, -272402, -272544, -272577, -272725, -272754, -272789, -272833, -272885, -272906, -273417, -274528, -274561, -274601, -274730, -274781, -274962, -275125, -275282, -275349, -275474, -275509, -275570, -275605, -275666, -275701, -275922, -275957, -276946, -277013, -277074, -277109, -277138, -277173, -278162, -286741, -286994, -287125, -287762, -287829, -288045, -288078, -288117, -290706, -290741, -291698, -292501, -293778, -293973, -294557, -294933, -296189, -296981, -297341, -297994, -299925, -302410, -303125, -308978, -309013, -309298, -309333, -311058, -311317, -314866, -314901, -319517, -319541, -322829, -322862, -322893, -322926, -322957, -322990, -323021, -323054, -323085, -323118, -323149, -323182, -323213, -323246, -323274, -324245, -325650, -325805, -325838, -325874, -326861, -326894, -326925, -326958, -326989, -327022, -327053, -327086, -327117, -327150, -327186, -327701, -335890, -340077, -340110, -340141, -340174, -340205, -340238, -340269, -340302, -340333, -340366, -340397, -340430, -340461, -340494, -340525, -340558, -340589, -340622, -340653, -340686, -340717, -340750, -340786, -342797, -342830, -342861, -342894, -342930, -343949, -343982, -344018, -352277, -353810, -354485, -354546, -354749, -354837, -355165, -360448, -361981, -361985, -363517, -363520, -363553, -363584, -363681, -363744, -363777, -363808, -363841, -363872, -363905, -363936, -364065, -364096, -364129, -364192, -364225, -364419, -364480, -364577, -364608, -364641, -364672, -364705, -364736, -364769, -364800, -364833, -364864, -364897, -364928, -364961, -364992, -365025, -365056, -365089, -365120, -365153, -365184, -365217, -365248, -365281, -365312, -365345, -365376, -365409, -365440, -365473, -365504, -365537, -365568, -365601, -365632, -365665, -365696, -365729, -365760, -365793, -365824, -365857, -365888, -365921, -365952, -365985, -366016, -366049, -366080, -366113, -366144, -366177, -366208, -366241, -366272, -366305, -366336, -366369, -366400, -366433, -366464, -366497, -366528, -366561, -366592, -366625, -366656, -366689, -366720, -366753, -366784, -366817, -366848, -366881, -366912, -366945, -366976, -367009, -367040, -367073, -367104, -367137, -367168, -367201, -367232, -367265, -367296, -367329, -367360, -367393, -367424, -367457, -367488, -367521, -367552, -367585, -367616, -367649, -367680, -367713, -367797, -367968, -368001, -368032, -368065, -368101, -368192, -368225, -368285, -368433, -368554, -368593, -368641, -369885, -369889, -369949, -370081, -370141, -370180, -371997, -372195, -372241, -372285, -372709, -372740, -373501, -373764, -374013, -374020, -374269, -374276, -374525, -374532, -374781, -374788, -375037, -375044, -375293, -375300, -375549, -375556, -375805, -375813, -376849, -376911, -376944, -376975, -377008, -377041, -377135, -377168, -377201, -377231, -377264, -377297, -377580, -377617, -377676, -377713, -377743, -377776, -377809, -377871, -377904, -377933, -377966, -377997, -378030, -378061, -378094, -378125, -378158, -378193, -378339, -378385, -378700, -378781, -380949, -381789, -381813, -384669, -385045, -391901, -392725, -393117, -393238, -393265, -393365, -393379, -393412, -393449, -393485, -393518, -393549, -393582, -393613, -393646, -393677, -393710, -393741, -393774, -393813, -393869, -393902, -393933, -393966, -393997, -394030, -394061, -394094, -394124, -394157, -394190, -394261, -394281, -394565, -394694, -394764, -394787, -394965, -395017, -395107, -395140, -395185, -395221, -395293, -395300, -398077, -398117, -398196, -398243, -398308, -398348, -398372, -401265, -401283, -401380, -401437, -401572, -402909, -402980, -406013, -406037, -406090, -406229, -406532, -407421, -407573, -408733, -409092, -409621, -410621, -410634, -410965, -411914, -412181, -412202, -412693, -413706, -414037, -415274, -415765, -417789, -417813, -425988, -636637, -636949, -638980, -1309117, -1310724, -1311395, -1311428, -1348029, -1348117, -1349885, -1350148, -1351427, -1351633, -1351684, -1360259, -1360305, -1360388, -1360904, -1361220, -1361309, -1361920, -1361953, -1361984, -1362017, -1362048, -1362081, -1362112, -1362145, -1362176, -1362209, -1362240, -1362273, -1362304, -1362337, -1362368, -1362401, -1362432, -1362465, -1362496, -1362529, -1362560, -1362593, -1362624, -1362657, -1362688, -1362721, -1362752, -1362785, -1362816, -1362849, -1362880, -1362913, -1362944, -1362977, -1363008, -1363041, -1363072, -1363105, -1363136, -1363169, -1363200, -1363233, -1363264, -1363297, -1363328, -1363361, -1363396, -1363429, -1363463, -1363569, -1363589, -1363921, -1363939, -1363968, -1364001, -1364032, -1364065, -1364096, -1364129, -1364160, -1364193, -1364224, -1364257, -1364288, -1364321, -1364352, -1364385, -1364416, -1364449, -1364480, -1364513, -1364544, -1364577, -1364608, -1364641, -1364672, -1364705, -1364765, -1364965, -1364996, -1367241, -1367557, -1367633, -1367837, -1368084, -1368803, -1369108, -1369152, -1369185, -1369216, -1369249, -1369280, -1369313, -1369344, -1369377, -1369408, -1369441, -1369472, -1369505, -1369536, -1369569, -1369664, -1369697, -1369728, -1369761, -1369792, -1369825, -1369856, -1369889, -1369920, -1369953, -1369984, -1370017, -1370048, -1370081, -1370112, -1370145, -1370176, -1370209, -1370240, -1370273, -1370304, -1370337, -1370368, -1370401, -1370432, -1370465, -1370496, -1370529, -1370560, -1370593, -1370624, -1370657, -1370688, -1370721, -1370752, -1370785, -1370816, -1370849, -1370880, -1370913, -1370944, -1370977, -1371008, -1371041, -1371072, -1371105, -1371136, -1371169, -1371200, -1371233, -1371264, -1371297, -1371328, -1371361, -1371392, -1371425, -1371456, -1371489, -1371520, -1371553, -1371584, -1371617, -1371651, -1371681, -1371936, -1371969, -1372000, -1372033, -1372064, -1372129, -1372160, -1372193, -1372224, -1372257, -1372288, -1372321, -1372352, -1372385, -1372419, -1372468, -1372512, -1372545, -1372576, -1372609, -1372669, -1372672, -1372705, -1372736, -1372769, -1372829, -1373184, -1373217, -1373248, -1373281, -1373312, -1373345, -1373376, -1373409, -1373440, -1373473, -1373504, -1373565, -1376003, -1376065, -1376100, -1376325, -1376356, -1376453, -1376484, -1376613, -1376644, -1377382, -1377445, -1377510, -1377557, -1377693, -1377802, -1378005, -1378067, -1378101, -1378141, -1378308, -1379985, -1380125, -1380358, -1380420, -1382022, -1382533, -1382589, -1382865, -1382920, -1383261, -1383429, -1384004, -1384209, -1384292, -1384349, -1384456, -1384772, -1385669, -1385937, -1385988, -1386725, -1387078, -1387165, -1387505, -1387524, -1388477, -1388549, -1388646, -1388676, -1390181, -1390214, -1390277, -1390406, -1390469, -1390502, -1390641, -1391069, -1391075, -1391112, -1391453, -1391569, -1391645, -1392644, -1393957, -1394150, -1394213, -1394278, -1394341, -1394429, -1394692, -1394789, -1394820, -1395077, -1395110, -1395165, -1395208, -1395549, -1395601, -1395716, -1396227, -1396260, -1396469, -1396548, -1396582, -1396637, -1396740, -1398277, -1398308, -1398341, -1398436, -1398501, -1398564, -1398725, -1398788, -1398821, -1398852, -1398909, -1399652, -1399715, -1399761, -1399812, -1400166, -1400197, -1400262, -1400337, -1400388, -1400419, -1400486, -1400517, -1400573, -1400868, -1401085, -1401124, -1401341, -1401380, -1401597, -1401860, -1402109, -1402116, -1402365, -1406980, -1408102, -1408165, -1408198, -1408261, -1408294, -1408369, -1408390, -1408421, -1408477, -1408520, -1408861, -1409028, -1766557, -1766916, -1767677, -1767780, -1769373, -1769499, -1835036, -2039812, -2051549, -2051588, -2055005, -2056193, -2056445, -2056801, -2056989, -2057124, -2057157, -2057188, -2057522, -2057540, -2057981, -2057988, -2058173, -2058180, -2058237, -2058244, -2058333, -2058340, -2058429, -2058436, -2061908, -2062429, -2062948, -2074573, -2074606, -2074653, -2075140, -2077213, -2077252, -2079005, -2080260, -2080659, -2080693, -2080733, -2080773, -2081297, -2081517, -2081550, -2081585, -2081629, -2081797, -2082045, -2082321, -2082348, -2082411, -2082477, -2082510, -2082541, -2082574, -2082605, -2082638, -2082669, -2082702, -2082733, -2082766, -2082797, -2082830, -2082861, -2082894, -2082925, -2082958, -2082993, -2083053, -2083086, -2083121, -2083243, -2083345, -2083453, -2083473, -2083596, -2083629, -2083662, -2083693, -2083726, -2083757, -2083790, -2083825, -2083922, -2083948, -2083986, -2084093, -2084113, -2084147, -2084177, -2084253, -2084356, -2084541, -2084548, -2088893, -2088954, -2088989, -2089009, -2089107, -2089137, -2089229, -2089262, -2089297, -2089330, -2089361, -2089388, -2089425, -2089480, -2089809, -2089874, -2089969, -2090016, -2090861, -2090897, -2090926, -2090964, -2090987, -2091028, -2091041, -2091885, -2091922, -2091950, -2091986, -2092013, -2092046, -2092081, -2092109, -2092142, -2092177, -2092228, -2092547, -2092580, -2094019, -2094084, -2095101, -2095172, -2095389, -2095428, -2095645, -2095684, -2095901, -2095940, -2096061, -2096147, -2096210, -2096244, -2096277, -2096307, -2096381, -2096405, -2096434, -2096565, -2096637, -2096954, -2097045, -2097117, -2097156, -2097565, -2097572, -2098429, -2098436, -2099069, -2099076, -2099165, -2099172, -2099677, -2099716, -2100189, -2101252, -2105213, -2105361, -2105469, -2105578, -2107037, -2107125, -2107401, -2109098, -2109237, -2109770, -2109821, -2109973, -2110365, -2112021, -2113445, -2113501, -2117636, -2118589, -2118660, -2120253, -2121732, -2122749, -2122762, -2122909, -2123268, -2123817, -2123844, -2124105, -2124157, -2125828, -2126813, -2126833, -2126852, -2128029, -2128132, -2128401, -2128425, -2128605, -2129920, -2131201, -2132484, -2135005, -2135048, -2135389, -2162692, -2162909, -2162948, -2163005, -2163012, -2164445, -2164452, -2164541, -2164612, -2164669, -2164708, -2165469, -2165489, -2165514, -2165789, -2170884, -2171594, -2171805, -2171889, -2171908, -2172765, -2172913, -2172957, -2174980, -2176797, -2176964, -2177053, -2179076, -2179109, -2179229, -2179237, -2179325, -2179461, -2179588, -2179741, -2179748, -2179869, -2179876, -2180765, -2180869, -2180989, -2181093, -2181130, -2181405, -2181649, -2181949, -2182148, -2183082, -2183153, -2183197, -2187268, -2189021, -2189105, -2189316, -2190045, -2190090, -2190340, -2190973, -2191114, -2191389, -2195460, -2197821, -2214922, -2215933, -2228230, -2228261, -2228294, -2228324, -2230021, -2230513, -2230749, -2230858, -2231496, -2231837, -2232325, -2232390, -2232420, -2233862, -2233957, -2234086, -2234149, -2234225, -2234298, -2234321, -2234461, -2234884, -2235709, -2235912, -2236253, -2236421, -2236516, -2237669, -2237830, -2237861, -2238141, -2238152, -2238481, -2238621, -2240517, -2240582, -2240612, -2242150, -2242245, -2242534, -2242596, -2242737, -2242877, -2243080, -2243421, -2281476, -2282853, -2282886, -2282917, -2282950, -2283013, -2283206, -2283237, -2283293, -2283528, -2283869, -2359300, -2387453, -2392073, -2395261, -2395665, -2395805, -2490372, -2524669, -2949124, -2967357, -3006468, -3008701, -3009028, -3009062, -3010557, -3011045, -3011171, -3011613, -3538948, -3539037, -3801109, -3808989, -3809301, -3810557, -3810613, -3812518, -3812581, -3812693, -3812774, -3812986, -3813221, -3813493, -3813541, -3813781, -3814725, -3814869, -3816413, -3817493, -3819589, -3819701, -3819741, -3825685, -3828477, -3828746, -3829341, -3833856, -3834689, -3835520, -3836353, -3836605, -3836609, -3837184, -3838017, -3838848, -3838909, -3838912, -3839005, -3839040, -3839101, -3839136, -3839229, -3839264, -3839421, -3839424, -3839681, -3839837, -3839841, -3839901, -3839905, -3840157, -3840161, -3840512, -3841345, -3842176, -3842269, -3842272, -3842429, -3842464, -3842749, -3842752, -3843005, -3843009, -3843840, -3843933, -3843936, -3844093, -3844096, -3844285, -3844288, -3844349, -3844416, -3844669, -3844673, -3845504, -3846337, -3847168, -3848001, -3848832, -3849665, -3850496, -3851329, -3852160, -3852993, -3853824, -3854657, -3855581, -3855616, -3856434, -3856449, -3857266, -3857281, -3857472, -3858290, -3858305, -3859122, -3859137, -3859328, -3860146, -3860161, -3860978, -3860993, -3861184, -3862002, -3862017, -3862834, -3862849, -3863040, -3863858, -3863873, -3864690, -3864705, -3864896, -3864929, -3864989, -3865032, -3866653, -4046852, -4047005, -4047012, -4047901, -4047908, -4047997, -4048004, -4048061, -4048100, -4048157, -4048164, -4048509, -4048516, -4048669, -4048676, -4048733, -4048740, -4048797, -4048964, -4049021, -4049124, -4049181, -4049188, -4049245, -4049252, -4049309, -4049316, -4049437, -4049444, -4049533, -4049540, -4049597, -4049636, -4049693, -4049700, -4049757, -4049764, -4049821, -4049828, -4049885, -4049892, -4049949, -4049956, -4050045, -4050052, -4050109, -4050148, -4050301, -4050308, -4050557, -4050564, -4050717, -4050724, -4050877, -4050884, -4050941, -4050948, -4051293, -4051300, -4051869, -4052004, -4052125, -4052132, -4052317, -4052324, -4052893, -4054546, -4054621, -4063253, -4064669, -4064789, -4067997, -4068373, -4068861, -4068917, -4069373, -4069429, -4069917, -4069941, -4070429, -4071434, -4071805, -4071957, -4072957, -4072981, -4074909, -4075029, -4076413, -4078805, -4079741, -4080149, -4081533, -4081685, -4081981, -4082197, -4082269, -4087829, -4088893, -4089365, -4089565, -4089589, -4091837, -4091925, -4092573, -4092949, -4094141, -4094165, -4094333, -4094997, -4095549, -4096021, -4098045, -4098069, -4098109, -4098133, -4103965, -4103989, -4104125, -4104213, -4106205, -4106261, -4106397, -4106773, -4107549, -4112245, -4114493, -4114613, -4114973, -4116501, -4118749, -4120597, -4124317, -4194308, -5561085, -5562372, -5695165, -5695492, -5702621, -6225924, -6243293, -29360186, -29360221, -29361178, -29364253, -29368325, -29376029, -31457308, -33554397, -33554460, -35651549, -//--Autogenerated -- end of section automatically generated -}; - -const int maxUnicode = 0x10ffff; -const int maskCategory = 0x1F; -const int nRanges = ELEMENTS(catRanges); - -} - -// Each element in catRanges is the start of a range of Unicode characters in -// one general category. -// The value is comprised of a 21-bit character value shifted 5 bits and a 5 bit -// category matching the CharacterCategory enumeration. -// Initial version has 3249 entries and adds about 13K to the executable. -// The array is in ascending order so can be searched using binary search. -// Therefore the average call takes log2(3249) = 12 comparisons. -// For speed, it may be useful to make a linear table for the common values, -// possibly for 0..0xff for most Western European text or 0..0xfff for most -// alphabetic languages. - -CharacterCategory CategoriseCharacter(int character) { - if (character < 0 || character > maxUnicode) - return ccCn; - const int baseValue = character * (maskCategory+1) + maskCategory; - const int *placeAfter = std::lower_bound(catRanges, catRanges+nRanges, baseValue); - return static_cast(*(placeAfter-1) & maskCategory); -} - -#ifdef SCI_NAMESPACE -} -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.h b/qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.h deleted file mode 100644 index c8600504b..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterCategory.h +++ /dev/null @@ -1,31 +0,0 @@ -// Scintilla source code edit control -/** @file CharacterCategory.h - ** Returns the Unicode general category of a character. - **/ -// Copyright 2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CHARACTERCATEGORY_H -#define CHARACTERCATEGORY_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -enum CharacterCategory { - ccLu, ccLl, ccLt, ccLm, ccLo, - ccMn, ccMc, ccMe, - ccNd, ccNl, ccNo, - ccPc, ccPd, ccPs, ccPe, ccPi, ccPf, ccPo, - ccSm, ccSc, ccSk, ccSo, - ccZs, ccZl, ccZp, - ccCc, ccCf, ccCs, ccCo, ccCn -}; - -CharacterCategory CategoriseCharacter(int character); - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.cxx deleted file mode 100644 index 55602af30..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.cxx +++ /dev/null @@ -1,61 +0,0 @@ -// Scintilla source code edit control -/** @file CharacterSet.cxx - ** Simple case functions for ASCII. - ** Lexer infrastructure. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include - -#include "CharacterSet.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -int CompareCaseInsensitive(const char *a, const char *b) { - while (*a && *b) { - if (*a != *b) { - char upperA = static_cast(MakeUpperCase(*a)); - char upperB = static_cast(MakeUpperCase(*b)); - if (upperA != upperB) - return upperA - upperB; - } - a++; - b++; - } - // Either *a or *b is nul - return *a - *b; -} - -int CompareNCaseInsensitive(const char *a, const char *b, size_t len) { - while (*a && *b && len) { - if (*a != *b) { - char upperA = static_cast(MakeUpperCase(*a)); - char upperB = static_cast(MakeUpperCase(*b)); - if (upperA != upperB) - return upperA - upperB; - } - a++; - b++; - len--; - } - if (len == 0) - return 0; - else - // Either *a or *b is nul - return *a - *b; -} - -#ifdef SCI_NAMESPACE -} -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.h b/qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.h deleted file mode 100644 index 183fbe421..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/CharacterSet.h +++ /dev/null @@ -1,184 +0,0 @@ -// Scintilla source code edit control -/** @file CharacterSet.h - ** Encapsulates a set of characters. Used to test if a character is within a set. - **/ -// Copyright 2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CHARACTERSET_H -#define CHARACTERSET_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class CharacterSet { - int size; - bool valueAfter; - bool *bset; -public: - enum setBase { - setNone=0, - setLower=1, - setUpper=2, - setDigits=4, - setAlpha=setLower|setUpper, - setAlphaNum=setAlpha|setDigits - }; - CharacterSet(setBase base=setNone, const char *initialSet="", int size_=0x80, bool valueAfter_=false) { - size = size_; - valueAfter = valueAfter_; - bset = new bool[size]; - for (int i=0; i < size; i++) { - bset[i] = false; - } - AddString(initialSet); - if (base & setLower) - AddString("abcdefghijklmnopqrstuvwxyz"); - if (base & setUpper) - AddString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - if (base & setDigits) - AddString("0123456789"); - } - CharacterSet(const CharacterSet &other) { - size = other.size; - valueAfter = other.valueAfter; - bset = new bool[size]; - for (int i=0; i < size; i++) { - bset[i] = other.bset[i]; - } - } - ~CharacterSet() { - delete []bset; - bset = 0; - size = 0; - } - CharacterSet &operator=(const CharacterSet &other) { - if (this != &other) { - bool *bsetNew = new bool[other.size]; - for (int i=0; i < other.size; i++) { - bsetNew[i] = other.bset[i]; - } - delete []bset; - size = other.size; - valueAfter = other.valueAfter; - bset = bsetNew; - } - return *this; - } - void Add(int val) { - assert(val >= 0); - assert(val < size); - bset[val] = true; - } - void AddString(const char *setToAdd) { - for (const char *cp=setToAdd; *cp; cp++) { - int val = static_cast(*cp); - assert(val >= 0); - assert(val < size); - bset[val] = true; - } - } - bool Contains(int val) const { - assert(val >= 0); - if (val < 0) return false; - return (val < size) ? bset[val] : valueAfter; - } -}; - -// Functions for classifying characters - -inline bool IsASpace(int ch) { - return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); -} - -inline bool IsASpaceOrTab(int ch) { - return (ch == ' ') || (ch == '\t'); -} - -inline bool IsADigit(int ch) { - return (ch >= '0') && (ch <= '9'); -} - -inline bool IsADigit(int ch, int base) { - if (base <= 10) { - return (ch >= '0') && (ch < '0' + base); - } else { - return ((ch >= '0') && (ch <= '9')) || - ((ch >= 'A') && (ch < 'A' + base - 10)) || - ((ch >= 'a') && (ch < 'a' + base - 10)); - } -} - -inline bool IsASCII(int ch) { - return (ch >= 0) && (ch < 0x80); -} - -inline bool IsLowerCase(int ch) { - return (ch >= 'a') && (ch <= 'z'); -} - -inline bool IsUpperCase(int ch) { - return (ch >= 'A') && (ch <= 'Z'); -} - -inline bool IsAlphaNumeric(int ch) { - return - ((ch >= '0') && (ch <= '9')) || - ((ch >= 'a') && (ch <= 'z')) || - ((ch >= 'A') && (ch <= 'Z')); -} - -/** - * Check if a character is a space. - * This is ASCII specific but is safe with chars >= 0x80. - */ -inline bool isspacechar(int ch) { - return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); -} - -inline bool iswordchar(int ch) { - return IsAlphaNumeric(ch) || ch == '.' || ch == '_'; -} - -inline bool iswordstart(int ch) { - return IsAlphaNumeric(ch) || ch == '_'; -} - -inline bool isoperator(int ch) { - if (IsAlphaNumeric(ch)) - return false; - if (ch == '%' || ch == '^' || ch == '&' || ch == '*' || - ch == '(' || ch == ')' || ch == '-' || ch == '+' || - ch == '=' || ch == '|' || ch == '{' || ch == '}' || - ch == '[' || ch == ']' || ch == ':' || ch == ';' || - ch == '<' || ch == '>' || ch == ',' || ch == '/' || - ch == '?' || ch == '!' || ch == '.' || ch == '~') - return true; - return false; -} - -// Simple case functions for ASCII. - -inline int MakeUpperCase(int ch) { - if (ch < 'a' || ch > 'z') - return ch; - else - return static_cast(ch - 'a' + 'A'); -} - -inline int MakeLowerCase(int ch) { - if (ch < 'A' || ch > 'Z') - return ch; - else - return ch - 'A' + 'a'; -} - -int CompareCaseInsensitive(const char *a, const char *b); -int CompareNCaseInsensitive(const char *a, const char *b, size_t len); - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexAccessor.h b/qrenderdoc/3rdparty/scintilla/lexlib/LexAccessor.h deleted file mode 100644 index f2cce50bd..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexAccessor.h +++ /dev/null @@ -1,204 +0,0 @@ -// Scintilla source code edit control -/** @file LexAccessor.h - ** Interfaces between Scintilla and lexers. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef LEXACCESSOR_H -#define LEXACCESSOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -enum EncodingType { enc8bit, encUnicode, encDBCS }; - -class LexAccessor { -private: - IDocument *pAccess; - enum {extremePosition=0x7FFFFFFF}; - /** @a bufferSize is a trade off between time taken to copy the characters - * and retrieval overhead. - * @a slopSize positions the buffer before the desired position - * in case there is some backtracking. */ - enum {bufferSize=4000, slopSize=bufferSize/8}; - char buf[bufferSize+1]; - Sci_Position startPos; - Sci_Position endPos; - int codePage; - enum EncodingType encodingType; - Sci_Position lenDoc; - char styleBuf[bufferSize]; - Sci_Position validLen; - Sci_PositionU startSeg; - Sci_Position startPosStyling; - int documentVersion; - - void Fill(Sci_Position position) { - startPos = position - slopSize; - if (startPos + bufferSize > lenDoc) - startPos = lenDoc - bufferSize; - if (startPos < 0) - startPos = 0; - endPos = startPos + bufferSize; - if (endPos > lenDoc) - endPos = lenDoc; - - pAccess->GetCharRange(buf, startPos, endPos-startPos); - buf[endPos-startPos] = '\0'; - } - -public: - explicit LexAccessor(IDocument *pAccess_) : - pAccess(pAccess_), startPos(extremePosition), endPos(0), - codePage(pAccess->CodePage()), - encodingType(enc8bit), - lenDoc(pAccess->Length()), - validLen(0), - startSeg(0), startPosStyling(0), - documentVersion(pAccess->Version()) { - // Prevent warnings by static analyzers about uninitialized buf and styleBuf. - buf[0] = 0; - styleBuf[0] = 0; - switch (codePage) { - case 65001: - encodingType = encUnicode; - break; - case 932: - case 936: - case 949: - case 950: - case 1361: - encodingType = encDBCS; - } - } - char operator[](Sci_Position position) { - if (position < startPos || position >= endPos) { - Fill(position); - } - return buf[position - startPos]; - } - IDocumentWithLineEnd *MultiByteAccess() const { - if (documentVersion >= dvLineEnd) { - return static_cast(pAccess); - } - return 0; - } - /** Safe version of operator[], returning a defined value for invalid position. */ - char SafeGetCharAt(Sci_Position position, char chDefault=' ') { - if (position < startPos || position >= endPos) { - Fill(position); - if (position < startPos || position >= endPos) { - // Position is outside range of document - return chDefault; - } - } - return buf[position - startPos]; - } - bool IsLeadByte(char ch) const { - return pAccess->IsDBCSLeadByte(ch); - } - EncodingType Encoding() const { - return encodingType; - } - bool Match(Sci_Position pos, const char *s) { - for (int i=0; *s; i++) { - if (*s != SafeGetCharAt(pos+i)) - return false; - s++; - } - return true; - } - char StyleAt(Sci_Position position) const { - return static_cast(pAccess->StyleAt(position)); - } - Sci_Position GetLine(Sci_Position position) const { - return pAccess->LineFromPosition(position); - } - Sci_Position LineStart(Sci_Position line) const { - return pAccess->LineStart(line); - } - Sci_Position LineEnd(Sci_Position line) { - if (documentVersion >= dvLineEnd) { - return (static_cast(pAccess))->LineEnd(line); - } else { - // Old interface means only '\r', '\n' and '\r\n' line ends. - Sci_Position startNext = pAccess->LineStart(line+1); - char chLineEnd = SafeGetCharAt(startNext-1); - if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r')) - return startNext - 2; - else - return startNext - 1; - } - } - int LevelAt(Sci_Position line) const { - return pAccess->GetLevel(line); - } - Sci_Position Length() const { - return lenDoc; - } - void Flush() { - if (validLen > 0) { - pAccess->SetStyles(validLen, styleBuf); - startPosStyling += validLen; - validLen = 0; - } - } - int GetLineState(Sci_Position line) const { - return pAccess->GetLineState(line); - } - int SetLineState(Sci_Position line, int state) { - return pAccess->SetLineState(line, state); - } - // Style setting - void StartAt(Sci_PositionU start) { - pAccess->StartStyling(start, '\377'); - startPosStyling = start; - } - Sci_PositionU GetStartSegment() const { - return startSeg; - } - void StartSegment(Sci_PositionU pos) { - startSeg = pos; - } - void ColourTo(Sci_PositionU pos, int chAttr) { - // Only perform styling if non empty range - if (pos != startSeg - 1) { - assert(pos >= startSeg); - if (pos < startSeg) { - return; - } - - if (validLen + (pos - startSeg + 1) >= bufferSize) - Flush(); - if (validLen + (pos - startSeg + 1) >= bufferSize) { - // Too big for buffer so send directly - pAccess->SetStyleFor(pos - startSeg + 1, static_cast(chAttr)); - } else { - for (Sci_PositionU i = startSeg; i <= pos; i++) { - assert((startPosStyling + validLen) < Length()); - styleBuf[validLen++] = static_cast(chAttr); - } - } - } - startSeg = pos+1; - } - void SetLevel(Sci_Position line, int level) { - pAccess->SetLevel(line, level); - } - void IndicatorFill(Sci_Position start, Sci_Position end, int indicator, int value) { - pAccess->DecorationSetCurrentIndicator(indicator); - pAccess->DecorationFillRange(start, value, end - start); - } - - void ChangeLexerState(Sci_Position start, Sci_Position end) { - pAccess->ChangeLexerState(start, end); - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.cxx deleted file mode 100644 index d887b3c6c..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.cxx +++ /dev/null @@ -1,92 +0,0 @@ -// Scintilla source code edit control -/** @file LexerBase.cxx - ** A simple lexer with no state. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "LexerModule.h" -#include "LexerBase.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -LexerBase::LexerBase() { - for (int wl = 0; wl < numWordLists; wl++) - keyWordLists[wl] = new WordList; - keyWordLists[numWordLists] = 0; -} - -LexerBase::~LexerBase() { - for (int wl = 0; wl < numWordLists; wl++) { - delete keyWordLists[wl]; - keyWordLists[wl] = 0; - } - keyWordLists[numWordLists] = 0; -} - -void SCI_METHOD LexerBase::Release() { - delete this; -} - -int SCI_METHOD LexerBase::Version() const { - return lvOriginal; -} - -const char * SCI_METHOD LexerBase::PropertyNames() { - return ""; -} - -int SCI_METHOD LexerBase::PropertyType(const char *) { - return SC_TYPE_BOOLEAN; -} - -const char * SCI_METHOD LexerBase::DescribeProperty(const char *) { - return ""; -} - -Sci_Position SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) { - const char *valOld = props.Get(key); - if (strcmp(val, valOld) != 0) { - props.Set(key, val); - return 0; - } else { - return -1; - } -} - -const char * SCI_METHOD LexerBase::DescribeWordListSets() { - return ""; -} - -Sci_Position SCI_METHOD LexerBase::WordListSet(int n, const char *wl) { - if (n < numWordLists) { - WordList wlNew; - wlNew.Set(wl); - if (*keyWordLists[n] != wlNew) { - keyWordLists[n]->Set(wl); - return 0; - } - } - return -1; -} - -void * SCI_METHOD LexerBase::PrivateCall(int, void *) { - return 0; -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.h b/qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.h deleted file mode 100644 index d8849d2f9..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerBase.h +++ /dev/null @@ -1,41 +0,0 @@ -// Scintilla source code edit control -/** @file LexerBase.h - ** A simple lexer with no state. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef LEXERBASE_H -#define LEXERBASE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// A simple lexer with no state -class LexerBase : public ILexer { -protected: - PropSetSimple props; - enum {numWordLists=KEYWORDSET_MAX+1}; - WordList *keyWordLists[numWordLists+1]; -public: - LexerBase(); - virtual ~LexerBase(); - void SCI_METHOD Release(); - int SCI_METHOD Version() const; - const char * SCI_METHOD PropertyNames(); - int SCI_METHOD PropertyType(const char *name); - const char * SCI_METHOD DescribeProperty(const char *name); - Sci_Position SCI_METHOD PropertySet(const char *key, const char *val); - const char * SCI_METHOD DescribeWordListSets(); - Sci_Position SCI_METHOD WordListSet(int n, const char *wl); - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) = 0; - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) = 0; - void * SCI_METHOD PrivateCall(int operation, void *pointer); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.cxx deleted file mode 100644 index 390bae06e..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.cxx +++ /dev/null @@ -1,111 +0,0 @@ -// Scintilla source code edit control -/** @file LexerModule.cxx - ** Colourise for particular languages. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "LexerModule.h" -#include "LexerBase.h" -#include "LexerSimple.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -LexerModule::LexerModule(int language_, - LexerFunction fnLexer_, - const char *languageName_, - LexerFunction fnFolder_, - const char *const wordListDescriptions_[]) : - language(language_), - fnLexer(fnLexer_), - fnFolder(fnFolder_), - fnFactory(0), - wordListDescriptions(wordListDescriptions_), - languageName(languageName_) { -} - -LexerModule::LexerModule(int language_, - LexerFactoryFunction fnFactory_, - const char *languageName_, - const char * const wordListDescriptions_[]) : - language(language_), - fnLexer(0), - fnFolder(0), - fnFactory(fnFactory_), - wordListDescriptions(wordListDescriptions_), - languageName(languageName_) { -} - -int LexerModule::GetNumWordLists() const { - if (wordListDescriptions == NULL) { - return -1; - } else { - int numWordLists = 0; - - while (wordListDescriptions[numWordLists]) { - ++numWordLists; - } - - return numWordLists; - } -} - -const char *LexerModule::GetWordListDescription(int index) const { - assert(index < GetNumWordLists()); - if (!wordListDescriptions || (index >= GetNumWordLists())) { - return ""; - } else { - return wordListDescriptions[index]; - } -} - -ILexer *LexerModule::Create() const { - if (fnFactory) - return fnFactory(); - else - return new LexerSimple(this); -} - -void LexerModule::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, - WordList *keywordlists[], Accessor &styler) const { - if (fnLexer) - fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler); -} - -void LexerModule::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, - WordList *keywordlists[], Accessor &styler) const { - if (fnFolder) { - Sci_Position lineCurrent = styler.GetLine(startPos); - // Move back one line in case deletion wrecked current line fold state - if (lineCurrent > 0) { - lineCurrent--; - Sci_Position newStartPos = styler.LineStart(lineCurrent); - lengthDoc += startPos - newStartPos; - startPos = newStartPos; - initStyle = 0; - if (startPos > 0) { - initStyle = styler.StyleAt(startPos - 1); - } - } - fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler); - } -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.h b/qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.h deleted file mode 100644 index a561cf151..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerModule.h +++ /dev/null @@ -1,82 +0,0 @@ -// Scintilla source code edit control -/** @file LexerModule.h - ** Colourise for particular languages. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef LEXERMODULE_H -#define LEXERMODULE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class Accessor; -class WordList; - -typedef void (*LexerFunction)(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, - WordList *keywordlists[], Accessor &styler); -typedef ILexer *(*LexerFactoryFunction)(); - -/** - * A LexerModule is responsible for lexing and folding a particular language. - * The class maintains a list of LexerModules which can be searched to find a - * module appropriate to a particular language. - */ -class LexerModule { -protected: - int language; - LexerFunction fnLexer; - LexerFunction fnFolder; - LexerFactoryFunction fnFactory; - const char * const * wordListDescriptions; - -public: - const char *languageName; - LexerModule(int language_, - LexerFunction fnLexer_, - const char *languageName_=0, - LexerFunction fnFolder_=0, - const char * const wordListDescriptions_[] = NULL); - LexerModule(int language_, - LexerFactoryFunction fnFactory_, - const char *languageName_, - const char * const wordListDescriptions_[] = NULL); - virtual ~LexerModule() { - } - int GetLanguage() const { return language; } - - // -1 is returned if no WordList information is available - int GetNumWordLists() const; - const char *GetWordListDescription(int index) const; - - ILexer *Create() const; - - virtual void Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, - WordList *keywordlists[], Accessor &styler) const; - virtual void Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, - WordList *keywordlists[], Accessor &styler) const; - - friend class Catalogue; -}; - -inline int Maximum(int a, int b) { - return (a > b) ? a : b; -} - -// Shut up annoying Visual C++ warnings: -#ifdef _MSC_VER -#pragma warning(disable: 4244 4456 4457) -#endif - -// Turn off shadow warnings for lexers as may be maintained by others -#if defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wshadow" -#endif - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.cxx deleted file mode 100644 index 30c291bcb..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.cxx +++ /dev/null @@ -1,68 +0,0 @@ -// Scintilla source code edit control -/** @file LexerNoExceptions.cxx - ** A simple lexer with no state which does not throw exceptions so can be used in an external lexer. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "LexerModule.h" -#include "LexerBase.h" -#include "LexerNoExceptions.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -Sci_Position SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) { - try { - return LexerBase::PropertySet(key, val); - } catch (...) { - // Should not throw into caller as may be compiled with different compiler or options - } - return -1; -} - -Sci_Position SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) { - try { - return LexerBase::WordListSet(n, wl); - } catch (...) { - // Should not throw into caller as may be compiled with different compiler or options - } - return -1; -} - -void SCI_METHOD LexerNoExceptions::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - try { - Accessor astyler(pAccess, &props); - Lexer(startPos, length, initStyle, pAccess, astyler); - astyler.Flush(); - } catch (...) { - // Should not throw into caller as may be compiled with different compiler or options - pAccess->SetErrorStatus(SC_STATUS_FAILURE); - } -} -void SCI_METHOD LexerNoExceptions::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - try { - Accessor astyler(pAccess, &props); - Folder(startPos, length, initStyle, pAccess, astyler); - astyler.Flush(); - } catch (...) { - // Should not throw into caller as may be compiled with different compiler or options - pAccess->SetErrorStatus(SC_STATUS_FAILURE); - } -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.h b/qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.h deleted file mode 100644 index ba24a8eb7..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerNoExceptions.h +++ /dev/null @@ -1,32 +0,0 @@ -// Scintilla source code edit control -/** @file LexerNoExceptions.h - ** A simple lexer with no state. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef LEXERNOEXCEPTIONS_H -#define LEXERNOEXCEPTIONS_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// A simple lexer with no state -class LexerNoExceptions : public LexerBase { -public: - // TODO Also need to prevent exceptions in constructor and destructor - Sci_Position SCI_METHOD PropertySet(const char *key, const char *val); - Sci_Position SCI_METHOD WordListSet(int n, const char *wl); - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess); - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *); - - virtual void Lexer(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess, Accessor &styler) = 0; - virtual void Folder(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess, Accessor &styler) = 0; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.cxx deleted file mode 100644 index 437c96f78..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.cxx +++ /dev/null @@ -1,57 +0,0 @@ -// Scintilla source code edit control -/** @file LexerSimple.cxx - ** A simple lexer with no state. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.h" -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "LexerModule.h" -#include "LexerBase.h" -#include "LexerSimple.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) { - for (int wl = 0; wl < module->GetNumWordLists(); wl++) { - if (!wordLists.empty()) - wordLists += "\n"; - wordLists += module->GetWordListDescription(wl); - } -} - -const char * SCI_METHOD LexerSimple::DescribeWordListSets() { - return wordLists.c_str(); -} - -void SCI_METHOD LexerSimple::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) { - Accessor astyler(pAccess, &props); - module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler); - astyler.Flush(); -} - -void SCI_METHOD LexerSimple::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) { - if (props.GetInt("fold")) { - Accessor astyler(pAccess, &props); - module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler); - astyler.Flush(); - } -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.h b/qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.h deleted file mode 100644 index a88c409cb..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/LexerSimple.h +++ /dev/null @@ -1,30 +0,0 @@ -// Scintilla source code edit control -/** @file LexerSimple.h - ** A simple lexer with no state. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef LEXERSIMPLE_H -#define LEXERSIMPLE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// A simple lexer with no state -class LexerSimple : public LexerBase { - const LexerModule *module; - std::string wordLists; -public: - explicit LexerSimple(const LexerModule *module_); - const char * SCI_METHOD DescribeWordListSets(); - void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess); - void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/OptionSet.h b/qrenderdoc/3rdparty/scintilla/lexlib/OptionSet.h deleted file mode 100644 index 2935a2089..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/OptionSet.h +++ /dev/null @@ -1,142 +0,0 @@ -// Scintilla source code edit control -/** @file OptionSet.h - ** Manage descriptive information about an options struct for a lexer. - ** Hold the names, positions, and descriptions of boolean, integer and string options and - ** allow setting options and retrieving metadata about the options. - **/ -// Copyright 2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef OPTIONSET_H -#define OPTIONSET_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -template -class OptionSet { - typedef T Target; - typedef bool T::*plcob; - typedef int T::*plcoi; - typedef std::string T::*plcos; - struct Option { - int opType; - union { - plcob pb; - plcoi pi; - plcos ps; - }; - std::string description; - Option() : - opType(SC_TYPE_BOOLEAN), pb(0), description("") { - } - Option(plcob pb_, std::string description_="") : - opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) { - } - Option(plcoi pi_, std::string description_) : - opType(SC_TYPE_INTEGER), pi(pi_), description(description_) { - } - Option(plcos ps_, std::string description_) : - opType(SC_TYPE_STRING), ps(ps_), description(description_) { - } - bool Set(T *base, const char *val) const { - switch (opType) { - case SC_TYPE_BOOLEAN: { - bool option = atoi(val) != 0; - if ((*base).*pb != option) { - (*base).*pb = option; - return true; - } - break; - } - case SC_TYPE_INTEGER: { - int option = atoi(val); - if ((*base).*pi != option) { - (*base).*pi = option; - return true; - } - break; - } - case SC_TYPE_STRING: { - if ((*base).*ps != val) { - (*base).*ps = val; - return true; - } - break; - } - } - return false; - } - }; - typedef std::map OptionMap; - OptionMap nameToDef; - std::string names; - std::string wordLists; - - void AppendName(const char *name) { - if (!names.empty()) - names += "\n"; - names += name; - } -public: - virtual ~OptionSet() { - } - void DefineProperty(const char *name, plcob pb, std::string description="") { - nameToDef[name] = Option(pb, description); - AppendName(name); - } - void DefineProperty(const char *name, plcoi pi, std::string description="") { - nameToDef[name] = Option(pi, description); - AppendName(name); - } - void DefineProperty(const char *name, plcos ps, std::string description="") { - nameToDef[name] = Option(ps, description); - AppendName(name); - } - const char *PropertyNames() const { - return names.c_str(); - } - int PropertyType(const char *name) { - typename OptionMap::iterator it = nameToDef.find(name); - if (it != nameToDef.end()) { - return it->second.opType; - } - return SC_TYPE_BOOLEAN; - } - const char *DescribeProperty(const char *name) { - typename OptionMap::iterator it = nameToDef.find(name); - if (it != nameToDef.end()) { - return it->second.description.c_str(); - } - return ""; - } - - bool PropertySet(T *base, const char *name, const char *val) { - typename OptionMap::iterator it = nameToDef.find(name); - if (it != nameToDef.end()) { - return it->second.Set(base, val); - } - return false; - } - - void DefineWordListSets(const char * const wordListDescriptions[]) { - if (wordListDescriptions) { - for (size_t wl = 0; wordListDescriptions[wl]; wl++) { - if (!wordLists.empty()) - wordLists += "\n"; - wordLists += wordListDescriptions[wl]; - } - } - } - - const char *DescribeWordListSets() const { - return wordLists.c_str(); - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.cxx deleted file mode 100644 index 6592d70eb..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.cxx +++ /dev/null @@ -1,156 +0,0 @@ -// SciTE - Scintilla based Text Editor -/** @file PropSetSimple.cxx - ** A Java style properties file module. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -// Maintain a dictionary of properties - -#include -#include -#include - -#include -#include - -#include "PropSetSimple.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -typedef std::map mapss; - -PropSetSimple::PropSetSimple() { - mapss *props = new mapss; - impl = static_cast(props); -} - -PropSetSimple::~PropSetSimple() { - mapss *props = static_cast(impl); - delete props; - impl = 0; -} - -void PropSetSimple::Set(const char *key, const char *val, int lenKey, int lenVal) { - mapss *props = static_cast(impl); - if (!*key) // Empty keys are not supported - return; - if (lenKey == -1) - lenKey = static_cast(strlen(key)); - if (lenVal == -1) - lenVal = static_cast(strlen(val)); - (*props)[std::string(key, lenKey)] = std::string(val, lenVal); -} - -static bool IsASpaceCharacter(unsigned int ch) { - return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d)); -} - -void PropSetSimple::Set(const char *keyVal) { - while (IsASpaceCharacter(*keyVal)) - keyVal++; - const char *endVal = keyVal; - while (*endVal && (*endVal != '\n')) - endVal++; - const char *eqAt = strchr(keyVal, '='); - if (eqAt) { - Set(keyVal, eqAt + 1, static_cast(eqAt-keyVal), - static_cast(endVal - eqAt - 1)); - } else if (*keyVal) { // No '=' so assume '=1' - Set(keyVal, "1", static_cast(endVal-keyVal), 1); - } -} - -void PropSetSimple::SetMultiple(const char *s) { - const char *eol = strchr(s, '\n'); - while (eol) { - Set(s); - s = eol + 1; - eol = strchr(s, '\n'); - } - Set(s); -} - -const char *PropSetSimple::Get(const char *key) const { - mapss *props = static_cast(impl); - mapss::const_iterator keyPos = props->find(std::string(key)); - if (keyPos != props->end()) { - return keyPos->second.c_str(); - } else { - return ""; - } -} - -// There is some inconsistency between GetExpanded("foo") and Expand("$(foo)"). -// A solution is to keep a stack of variables that have been expanded, so that -// recursive expansions can be skipped. For now I'll just use the C++ stack -// for that, through a recursive function and a simple chain of pointers. - -struct VarChain { - VarChain(const char *var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {} - - bool contains(const char *testVar) const { - return (var && (0 == strcmp(var, testVar))) - || (link && link->contains(testVar)); - } - - const char *var; - const VarChain *link; -}; - -static int ExpandAllInPlace(const PropSetSimple &props, std::string &withVars, int maxExpands, const VarChain &blankVars) { - size_t varStart = withVars.find("$("); - while ((varStart != std::string::npos) && (maxExpands > 0)) { - size_t varEnd = withVars.find(")", varStart+2); - if (varEnd == std::string::npos) { - break; - } - - // For consistency, when we see '$(ab$(cde))', expand the inner variable first, - // regardless whether there is actually a degenerate variable named 'ab$(cde'. - size_t innerVarStart = withVars.find("$(", varStart+2); - while ((innerVarStart != std::string::npos) && (innerVarStart > varStart) && (innerVarStart < varEnd)) { - varStart = innerVarStart; - innerVarStart = withVars.find("$(", varStart+2); - } - - std::string var(withVars.c_str(), varStart + 2, varEnd - varStart - 2); - std::string val = props.Get(var.c_str()); - - if (blankVars.contains(var.c_str())) { - val = ""; // treat blankVar as an empty string (e.g. to block self-reference) - } - - if (--maxExpands >= 0) { - maxExpands = ExpandAllInPlace(props, val, maxExpands, VarChain(var.c_str(), &blankVars)); - } - - withVars.erase(varStart, varEnd-varStart+1); - withVars.insert(varStart, val.c_str(), val.length()); - - varStart = withVars.find("$("); - } - - return maxExpands; -} - -int PropSetSimple::GetExpanded(const char *key, char *result) const { - std::string val = Get(key); - ExpandAllInPlace(*this, val, 100, VarChain(key)); - const int n = static_cast(val.size()); - if (result) { - memcpy(result, val.c_str(), n+1); - } - return n; // Not including NUL -} - -int PropSetSimple::GetInt(const char *key, int defaultValue) const { - std::string val = Get(key); - ExpandAllInPlace(*this, val, 100, VarChain(key)); - if (!val.empty()) { - return atoi(val.c_str()); - } - return defaultValue; -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.h b/qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.h deleted file mode 100644 index 8ca741f03..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/PropSetSimple.h +++ /dev/null @@ -1,32 +0,0 @@ -// Scintilla source code edit control -/** @file PropSetSimple.h - ** A basic string to string map. - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef PROPSETSIMPLE_H -#define PROPSETSIMPLE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class PropSetSimple { - void *impl; - void Set(const char *keyVal); -public: - PropSetSimple(); - virtual ~PropSetSimple(); - void Set(const char *key, const char *val, int lenKey=-1, int lenVal=-1); - void SetMultiple(const char *); - const char *Get(const char *key) const; - int GetExpanded(const char *key, char *result) const; - int GetInt(const char *key, int defaultValue=0) const; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/SparseState.h b/qrenderdoc/3rdparty/scintilla/lexlib/SparseState.h deleted file mode 100644 index e767d6710..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/SparseState.h +++ /dev/null @@ -1,110 +0,0 @@ -// Scintilla source code edit control -/** @file SparseState.h - ** Hold lexer state that may change rarely. - ** This is often per-line state such as whether a particular type of section has been entered. - ** A state continues until it is changed. - **/ -// Copyright 2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SPARSESTATE_H -#define SPARSESTATE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -template -class SparseState { - struct State { - int position; - T value; - State(int position_, T value_) : position(position_), value(value_) { - } - inline bool operator<(const State &other) const { - return position < other.position; - } - inline bool operator==(const State &other) const { - return (position == other.position) && (value == other.value); - } - }; - int positionFirst; - typedef std::vector stateVector; - stateVector states; - - typename stateVector::iterator Find(int position) { - State searchValue(position, T()); - return std::lower_bound(states.begin(), states.end(), searchValue); - } - -public: - explicit SparseState(int positionFirst_=-1) { - positionFirst = positionFirst_; - } - void Set(int position, T value) { - Delete(position); - if (states.empty() || (value != states[states.size()-1].value)) { - states.push_back(State(position, value)); - } - } - T ValueAt(int position) { - if (states.empty()) - return T(); - if (position < states[0].position) - return T(); - typename stateVector::iterator low = Find(position); - if (low == states.end()) { - return states[states.size()-1].value; - } else { - if (low->position > position) { - --low; - } - return low->value; - } - } - bool Delete(int position) { - typename stateVector::iterator low = Find(position); - if (low != states.end()) { - states.erase(low, states.end()); - return true; - } - return false; - } - size_t size() const { - return states.size(); - } - - // Returns true if Merge caused a significant change - bool Merge(const SparseState &other, int ignoreAfter) { - // Changes caused beyond ignoreAfter are not significant - Delete(ignoreAfter+1); - - bool different = true; - bool changed = false; - typename stateVector::iterator low = Find(other.positionFirst); - if (static_cast(states.end() - low) == other.states.size()) { - // Same number in other as after positionFirst in this - different = !std::equal(low, states.end(), other.states.begin()); - } - if (different) { - if (low != states.end()) { - states.erase(low, states.end()); - changed = true; - } - typename stateVector::const_iterator startOther = other.states.begin(); - if (!states.empty() && !other.states.empty() && states.back().value == startOther->value) - ++startOther; - if (startOther != other.states.end()) { - states.insert(states.end(), startOther, other.states.end()); - changed = true; - } - } - return changed; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/StringCopy.h b/qrenderdoc/3rdparty/scintilla/lexlib/StringCopy.h deleted file mode 100644 index 1812b4e35..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/StringCopy.h +++ /dev/null @@ -1,36 +0,0 @@ -// Scintilla source code edit control -/** @file StringCopy.h - ** Safe string copy function which always NUL terminates. - ** ELEMENTS macro for determining array sizes. - **/ -// Copyright 2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef STRINGCOPY_H -#define STRINGCOPY_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// Safer version of string copy functions like strcpy, wcsncpy, etc. -// Instantiate over fixed length strings of both char and wchar_t. -// May truncate if source doesn't fit into dest with room for NUL. - -template -void StringCopy(T (&dest)[count], const T* source) { - for (size_t i=0; i -// This file is in the public domain. - -#include -#include -#include -#include -#include - -#include "ILexer.h" - -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -bool StyleContext::MatchIgnoreCase(const char *s) { - if (MakeLowerCase(ch) != static_cast(*s)) - return false; - s++; - if (MakeLowerCase(chNext) != static_cast(*s)) - return false; - s++; - for (int n = 2; *s; n++) { - if (static_cast(*s) != - MakeLowerCase(static_cast(styler.SafeGetCharAt(currentPos + n, 0)))) - return false; - s++; - } - return true; -} - -static void getRange(Sci_PositionU start, - Sci_PositionU end, - LexAccessor &styler, - char *s, - Sci_PositionU len) { - Sci_PositionU i = 0; - while ((i < end - start + 1) && (i < len-1)) { - s[i] = styler[start + i]; - i++; - } - s[i] = '\0'; -} - -void StyleContext::GetCurrent(char *s, Sci_PositionU len) { - getRange(styler.GetStartSegment(), currentPos - 1, styler, s, len); -} - -static void getRangeLowered(Sci_PositionU start, - Sci_PositionU end, - LexAccessor &styler, - char *s, - Sci_PositionU len) { - Sci_PositionU i = 0; - while ((i < end - start + 1) && (i < len-1)) { - s[i] = static_cast(tolower(styler[start + i])); - i++; - } - s[i] = '\0'; -} - -void StyleContext::GetCurrentLowered(char *s, Sci_PositionU len) { - getRangeLowered(styler.GetStartSegment(), currentPos - 1, styler, s, len); -} diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/StyleContext.h b/qrenderdoc/3rdparty/scintilla/lexlib/StyleContext.h deleted file mode 100644 index 6cbda358e..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/StyleContext.h +++ /dev/null @@ -1,210 +0,0 @@ -// Scintilla source code edit control -/** @file StyleContext.h - ** Lexer infrastructure. - **/ -// Copyright 1998-2004 by Neil Hodgson -// This file is in the public domain. - -#ifndef STYLECONTEXT_H -#define STYLECONTEXT_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// All languages handled so far can treat all characters >= 0x80 as one class -// which just continues the current token or starts an identifier if in default. -// DBCS treated specially as the second character can be < 0x80 and hence -// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80 -class StyleContext { - LexAccessor &styler; - IDocumentWithLineEnd *multiByteAccess; - Sci_PositionU endPos; - Sci_PositionU lengthDocument; - - // Used for optimizing GetRelativeCharacter - Sci_PositionU posRelative; - Sci_PositionU currentPosLastRelative; - Sci_Position offsetRelative; - - StyleContext &operator=(const StyleContext &); - - void GetNextChar() { - if (multiByteAccess) { - chNext = multiByteAccess->GetCharacterAndWidth(currentPos+width, &widthNext); - } else { - chNext = static_cast(styler.SafeGetCharAt(currentPos+width, 0)); - widthNext = 1; - } - // End of line determined from line end position, allowing CR, LF, - // CRLF and Unicode line ends as set by document. - if (currentLine < lineDocEnd) - atLineEnd = static_cast(currentPos) >= (lineStartNext-1); - else // Last line - atLineEnd = static_cast(currentPos) >= lineStartNext; - } - -public: - Sci_PositionU currentPos; - Sci_Position currentLine; - Sci_Position lineDocEnd; - Sci_Position lineStartNext; - bool atLineStart; - bool atLineEnd; - int state; - int chPrev; - int ch; - Sci_Position width; - int chNext; - Sci_Position widthNext; - - StyleContext(Sci_PositionU startPos, Sci_PositionU length, - int initStyle, LexAccessor &styler_, char chMask='\377') : - styler(styler_), - multiByteAccess(0), - endPos(startPos + length), - posRelative(0), - currentPosLastRelative(0x7FFFFFFF), - offsetRelative(0), - currentPos(startPos), - currentLine(-1), - lineStartNext(-1), - atLineEnd(false), - state(initStyle & chMask), // Mask off all bits which aren't in the chMask. - chPrev(0), - ch(0), - width(0), - chNext(0), - widthNext(1) { - if (styler.Encoding() != enc8bit) { - multiByteAccess = styler.MultiByteAccess(); - } - styler.StartAt(startPos /*, chMask*/); - styler.StartSegment(startPos); - currentLine = styler.GetLine(startPos); - lineStartNext = styler.LineStart(currentLine+1); - lengthDocument = static_cast(styler.Length()); - if (endPos == lengthDocument) - endPos++; - lineDocEnd = styler.GetLine(lengthDocument); - atLineStart = static_cast(styler.LineStart(currentLine)) == startPos; - - // Variable width is now 0 so GetNextChar gets the char at currentPos into chNext/widthNext - width = 0; - GetNextChar(); - ch = chNext; - width = widthNext; - - GetNextChar(); - } - void Complete() { - styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state); - styler.Flush(); - } - bool More() const { - return currentPos < endPos; - } - void Forward() { - if (currentPos < endPos) { - atLineStart = atLineEnd; - if (atLineStart) { - currentLine++; - lineStartNext = styler.LineStart(currentLine+1); - } - chPrev = ch; - currentPos += width; - ch = chNext; - width = widthNext; - GetNextChar(); - } else { - atLineStart = false; - chPrev = ' '; - ch = ' '; - chNext = ' '; - atLineEnd = true; - } - } - void Forward(Sci_Position nb) { - for (Sci_Position i = 0; i < nb; i++) { - Forward(); - } - } - void ForwardBytes(Sci_Position nb) { - Sci_PositionU forwardPos = currentPos + nb; - while (forwardPos > currentPos) { - Forward(); - } - } - void ChangeState(int state_) { - state = state_; - } - void SetState(int state_) { - styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state); - state = state_; - } - void ForwardSetState(int state_) { - Forward(); - styler.ColourTo(currentPos - ((currentPos > lengthDocument) ? 2 : 1), state); - state = state_; - } - Sci_Position LengthCurrent() const { - return currentPos - styler.GetStartSegment(); - } - int GetRelative(Sci_Position n) { - return static_cast(styler.SafeGetCharAt(currentPos+n, 0)); - } - int GetRelativeCharacter(Sci_Position n) { - if (n == 0) - return ch; - if (multiByteAccess) { - if ((currentPosLastRelative != currentPos) || - ((n > 0) && ((offsetRelative < 0) || (n < offsetRelative))) || - ((n < 0) && ((offsetRelative > 0) || (n > offsetRelative)))) { - posRelative = currentPos; - offsetRelative = 0; - } - Sci_Position diffRelative = n - offsetRelative; - Sci_Position posNew = multiByteAccess->GetRelativePosition(posRelative, diffRelative); - int chReturn = multiByteAccess->GetCharacterAndWidth(posNew, 0); - posRelative = posNew; - currentPosLastRelative = currentPos; - offsetRelative = n; - return chReturn; - } else { - // fast version for single byte encodings - return static_cast(styler.SafeGetCharAt(currentPos + n, 0)); - } - } - bool Match(char ch0) const { - return ch == static_cast(ch0); - } - bool Match(char ch0, char ch1) const { - return (ch == static_cast(ch0)) && (chNext == static_cast(ch1)); - } - bool Match(const char *s) { - if (ch != static_cast(*s)) - return false; - s++; - if (!*s) - return true; - if (chNext != static_cast(*s)) - return false; - s++; - for (int n=2; *s; n++) { - if (*s != styler.SafeGetCharAt(currentPos+n, 0)) - return false; - s++; - } - return true; - } - // Non-inline - bool MatchIgnoreCase(const char *s); - void GetCurrent(char *s, Sci_PositionU len); - void GetCurrentLowered(char *s, Sci_PositionU len); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/SubStyles.h b/qrenderdoc/3rdparty/scintilla/lexlib/SubStyles.h deleted file mode 100644 index f5b15e9cf..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/SubStyles.h +++ /dev/null @@ -1,178 +0,0 @@ -// Scintilla source code edit control -/** @file SubStyles.h - ** Manage substyles for a lexer. - **/ -// Copyright 2012 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SUBSTYLES_H -#define SUBSTYLES_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class WordClassifier { - int baseStyle; - int firstStyle; - int lenStyles; - std::map wordToStyle; - -public: - - explicit WordClassifier(int baseStyle_) : baseStyle(baseStyle_), firstStyle(0), lenStyles(0) { - } - - void Allocate(int firstStyle_, int lenStyles_) { - firstStyle = firstStyle_; - lenStyles = lenStyles_; - wordToStyle.clear(); - } - - int Base() const { - return baseStyle; - } - - int Start() const { - return firstStyle; - } - - int Length() const { - return lenStyles; - } - - void Clear() { - firstStyle = 0; - lenStyles = 0; - wordToStyle.clear(); - } - - int ValueFor(const std::string &s) const { - std::map::const_iterator it = wordToStyle.find(s); - if (it != wordToStyle.end()) - return it->second; - else - return -1; - } - - bool IncludesStyle(int style) const { - return (style >= firstStyle) && (style < (firstStyle + lenStyles)); - } - - void SetIdentifiers(int style, const char *identifiers) { - while (*identifiers) { - const char *cpSpace = identifiers; - while (*cpSpace && !(*cpSpace == ' ' || *cpSpace == '\t' || *cpSpace == '\r' || *cpSpace == '\n')) - cpSpace++; - if (cpSpace > identifiers) { - std::string word(identifiers, cpSpace - identifiers); - wordToStyle[word] = style; - } - identifiers = cpSpace; - if (*identifiers) - identifiers++; - } - } -}; - -class SubStyles { - int classifications; - const char *baseStyles; - int styleFirst; - int stylesAvailable; - int secondaryDistance; - int allocated; - std::vector classifiers; - - int BlockFromBaseStyle(int baseStyle) const { - for (int b=0; b < classifications; b++) { - if (baseStyle == baseStyles[b]) - return b; - } - return -1; - } - - int BlockFromStyle(int style) const { - int b = 0; - for (std::vector::const_iterator it=classifiers.begin(); it != classifiers.end(); ++it) { - if (it->IncludesStyle(style)) - return b; - b++; - } - return -1; - } - -public: - - SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) : - classifications(0), - baseStyles(baseStyles_), - styleFirst(styleFirst_), - stylesAvailable(stylesAvailable_), - secondaryDistance(secondaryDistance_), - allocated(0) { - while (baseStyles[classifications]) { - classifiers.push_back(WordClassifier(baseStyles[classifications])); - classifications++; - } - } - - int Allocate(int styleBase, int numberStyles) { - int block = BlockFromBaseStyle(styleBase); - if (block >= 0) { - if ((allocated + numberStyles) > stylesAvailable) - return -1; - int startBlock = styleFirst + allocated; - allocated += numberStyles; - classifiers[block].Allocate(startBlock, numberStyles); - return startBlock; - } else { - return -1; - } - } - - int Start(int styleBase) { - int block = BlockFromBaseStyle(styleBase); - return (block >= 0) ? classifiers[block].Start() : -1; - } - - int Length(int styleBase) { - int block = BlockFromBaseStyle(styleBase); - return (block >= 0) ? classifiers[block].Length() : 0; - } - - int BaseStyle(int subStyle) const { - int block = BlockFromStyle(subStyle); - if (block >= 0) - return classifiers[block].Base(); - else - return subStyle; - } - - int DistanceToSecondaryStyles() const { - return secondaryDistance; - } - - void SetIdentifiers(int style, const char *identifiers) { - int block = BlockFromStyle(style); - if (block >= 0) - classifiers[block].SetIdentifiers(style, identifiers); - } - - void Free() { - allocated = 0; - for (std::vector::iterator it=classifiers.begin(); it != classifiers.end(); ++it) - it->Clear(); - } - - const WordClassifier &Classifier(int baseStyle) const { - const int block = BlockFromBaseStyle(baseStyle); - return classifiers[block >= 0 ? block : 0]; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/WordList.cxx b/qrenderdoc/3rdparty/scintilla/lexlib/WordList.cxx deleted file mode 100644 index b8662916c..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/WordList.cxx +++ /dev/null @@ -1,302 +0,0 @@ -// Scintilla source code edit control -/** @file WordList.cxx - ** Hold a list of words. - **/ -// Copyright 1998-2002 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include - -#include - -#include "StringCopy.h" -#include "WordList.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -/** - * Creates an array that points into each word in the string and puts \0 terminators - * after each word. - */ -static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) { - int prev = '\n'; - int words = 0; - // For rapid determination of whether a character is a separator, build - // a look up table. - bool wordSeparator[256]; - for (int i=0; i<256; i++) { - wordSeparator[i] = false; - } - wordSeparator[static_cast('\r')] = true; - wordSeparator[static_cast('\n')] = true; - if (!onlyLineEnds) { - wordSeparator[static_cast(' ')] = true; - wordSeparator[static_cast('\t')] = true; - } - for (int j = 0; wordlist[j]; j++) { - int curr = static_cast(wordlist[j]); - if (!wordSeparator[curr] && wordSeparator[prev]) - words++; - prev = curr; - } - char **keywords = new char *[words + 1]; - int wordsStore = 0; - const size_t slen = strlen(wordlist); - if (words) { - prev = '\0'; - for (size_t k = 0; k < slen; k++) { - if (!wordSeparator[static_cast(wordlist[k])]) { - if (!prev) { - keywords[wordsStore] = &wordlist[k]; - wordsStore++; - } - } else { - wordlist[k] = '\0'; - } - prev = wordlist[k]; - } - } - keywords[wordsStore] = &wordlist[slen]; - *len = wordsStore; - return keywords; -} - -WordList::WordList(bool onlyLineEnds_) : - words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_) { - // Prevent warnings by static analyzers about uninitialized starts. - starts[0] = -1; -} - -WordList::~WordList() { - Clear(); -} - -WordList::operator bool() const { - return len ? true : false; -} - -bool WordList::operator!=(const WordList &other) const { - if (len != other.len) - return true; - for (int i=0; i(a), *static_cast(b)); -} - -static void SortWordList(char **words, unsigned int len) { - qsort(reinterpret_cast(words), len, sizeof(*words), cmpWords); -} - -#endif - -void WordList::Set(const char *s) { - Clear(); - const size_t lenS = strlen(s) + 1; - list = new char[lenS]; - memcpy(list, s, lenS); - words = ArrayFromWordList(list, &len, onlyLineEnds); -#ifdef _MSC_VER - std::sort(words, words + len, cmpWords); -#else - SortWordList(words, len); -#endif - for (unsigned int k = 0; k < ELEMENTS(starts); k++) - starts[k] = -1; - for (int l = len - 1; l >= 0; l--) { - unsigned char indexChar = words[l][0]; - starts[indexChar] = l; - } -} - -/** Check whether a string is in the list. - * List elements are either exact matches or prefixes. - * Prefix elements start with '^' and match all strings that start with the rest of the element - * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'. - */ -bool WordList::InList(const char *s) const { - if (0 == words) - return false; - unsigned char firstChar = s[0]; - int j = starts[firstChar]; - if (j >= 0) { - while (static_cast(words[j][0]) == firstChar) { - if (s[1] == words[j][1]) { - const char *a = words[j] + 1; - const char *b = s + 1; - while (*a && *a == *b) { - a++; - b++; - } - if (!*a && !*b) - return true; - } - j++; - } - } - j = starts[static_cast('^')]; - if (j >= 0) { - while (words[j][0] == '^') { - const char *a = words[j] + 1; - const char *b = s; - while (*a && *a == *b) { - a++; - b++; - } - if (!*a) - return true; - j++; - } - } - return false; -} - -/** similar to InList, but word s can be a substring of keyword. - * eg. the keyword define is defined as def~ine. This means the word must start - * with def to be a keyword, but also defi, defin and define are valid. - * The marker is ~ in this case. - */ -bool WordList::InListAbbreviated(const char *s, const char marker) const { - if (0 == words) - return false; - unsigned char firstChar = s[0]; - int j = starts[firstChar]; - if (j >= 0) { - while (static_cast(words[j][0]) == firstChar) { - bool isSubword = false; - int start = 1; - if (words[j][1] == marker) { - isSubword = true; - start++; - } - if (s[1] == words[j][start]) { - const char *a = words[j] + start; - const char *b = s + 1; - while (*a && *a == *b) { - a++; - if (*a == marker) { - isSubword = true; - a++; - } - b++; - } - if ((!*a || isSubword) && !*b) - return true; - } - j++; - } - } - j = starts[static_cast('^')]; - if (j >= 0) { - while (words[j][0] == '^') { - const char *a = words[j] + 1; - const char *b = s; - while (*a && *a == *b) { - a++; - b++; - } - if (!*a) - return true; - j++; - } - } - return false; -} - -/** similar to InListAbbreviated, but word s can be a abridged version of a keyword. -* eg. the keyword is defined as "after.~:". This means the word must have a prefix (begins with) of -* "after." and suffix (ends with) of ":" to be a keyword, Hence "after.field:" , "after.form.item:" are valid. -* Similarly "~.is.valid" keyword is suffix only... hence "field.is.valid" , "form.is.valid" are valid. -* The marker is ~ in this case. -* No multiple markers check is done and wont work. -*/ -bool WordList::InListAbridged(const char *s, const char marker) const { - if (0 == words) - return false; - unsigned char firstChar = s[0]; - int j = starts[firstChar]; - if (j >= 0) { - while (static_cast(words[j][0]) == firstChar) { - const char *a = words[j]; - const char *b = s; - while (*a && *a == *b) { - a++; - if (*a == marker) { - a++; - const size_t suffixLengthA = strlen(a); - const size_t suffixLengthB = strlen(b); - if (suffixLengthA >= suffixLengthB) - break; - b = b + suffixLengthB - suffixLengthA - 1; - } - b++; - } - if (!*a && !*b) - return true; - j++; - } - } - - j = starts[static_cast(marker)]; - if (j >= 0) { - while (words[j][0] == marker) { - const char *a = words[j] + 1; - const char *b = s; - const size_t suffixLengthA = strlen(a); - const size_t suffixLengthB = strlen(b); - if (suffixLengthA > suffixLengthB) { - j++; - continue; - } - b = b + suffixLengthB - suffixLengthA; - - while (*a && *a == *b) { - a++; - b++; - } - if (!*a && !*b) - return true; - j++; - } - } - - return false; -} - -const char *WordList::WordAt(int n) const { - return words[n]; -} - diff --git a/qrenderdoc/3rdparty/scintilla/lexlib/WordList.h b/qrenderdoc/3rdparty/scintilla/lexlib/WordList.h deleted file mode 100644 index b1f8c85b2..000000000 --- a/qrenderdoc/3rdparty/scintilla/lexlib/WordList.h +++ /dev/null @@ -1,42 +0,0 @@ -// Scintilla source code edit control -/** @file WordList.h - ** Hold a list of words. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef WORDLIST_H -#define WORDLIST_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - */ -class WordList { - // Each word contains at least one character - a empty word acts as sentinel at the end. - char **words; - char *list; - int len; - bool onlyLineEnds; ///< Delimited by any white space or only line ends - int starts[256]; -public: - explicit WordList(bool onlyLineEnds_ = false); - ~WordList(); - operator bool() const; - bool operator!=(const WordList &other) const; - int Length() const; - void Clear(); - void Set(const char *s); - bool InList(const char *s) const; - bool InListAbbreviated(const char *s, const char marker) const; - bool InListAbridged(const char *s, const char marker) const; - const char *WordAt(int n) const; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/qt/README b/qrenderdoc/3rdparty/scintilla/qt/README deleted file mode 100644 index e6d490fb6..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/README +++ /dev/null @@ -1,36 +0,0 @@ -README for building of Scintilla on Qt - -There are three different Scintilla libraries that can be produced: - - ScintillaEditBase -A basic widget callable from C++ which is small and can be used just as is -or with higher level functionality added. - - ScintillaEdit -A more complete C++ widget with a method for every Scintilla API and a -secondary API allowing direct access to document objects. - - ScintillaEditPy -A Python callable version of ScintillaEdit using the PySide bindings. - - Building a library - -ScintillaEditBase can be built without performing any generation steps. -The ScintillaEditBase/ScintillaEditBase.pro project can be loaded into -Qt Creator and the "Build All" command performed. -Alternatively, run "qmake" to build make files and then use the platform -make to build. Most commonly, use "make" on Unix and "nmake" -on Windows. - -ScintillaEdit requires a generation command be run first. From the -ScintillaEdit directory: - -python WidgetGen.py - -After the generation command has run, the ScintillaEdit.h and -ScintillaEdit.cpp files will have been populated with the Scintilla API -methods. -To build, use Qt Creator or qmake and make as for ScintillaEditBase. - -ScintillaEditPy is more complex and instructions are found in -ScintillaEditPy/README. diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.cpp b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.cpp deleted file mode 100644 index fd9f3e995..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.cpp +++ /dev/null @@ -1,305 +0,0 @@ -// ScintillaDocument.cpp -// Wrapper for Scintilla document object so it can be manipulated independently. -// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware - -#include -#include -#include - -#include "ScintillaDocument.h" - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -class WatcherHelper : public DocWatcher { - ScintillaDocument *owner; -public: - explicit WatcherHelper(ScintillaDocument *owner_); - virtual ~WatcherHelper(); - - void NotifyModifyAttempt(Document *doc, void *userData); - void NotifySavePoint(Document *doc, void *userData, bool atSavePoint); - void NotifyModified(Document *doc, DocModification mh, void *userData); - void NotifyDeleted(Document *doc, void *userData); - void NotifyStyleNeeded(Document *doc, void *userData, int endPos); - void NotifyLexerChanged(Document *doc, void *userData); - void NotifyErrorOccurred(Document *doc, void *userData, int status); -}; - -WatcherHelper::WatcherHelper(ScintillaDocument *owner_) : owner(owner_) { -} - -WatcherHelper::~WatcherHelper() { -} - -void WatcherHelper::NotifyModifyAttempt(Document *, void *) { - owner->emit_modify_attempt(); -} - -void WatcherHelper::NotifySavePoint(Document *, void *, bool atSavePoint) { - owner->emit_save_point(atSavePoint); -} - -void WatcherHelper::NotifyModified(Document *, DocModification mh, void *) { - int length = mh.length; - if (!mh.text) - length = 0; - QByteArray ba = QByteArray::fromRawData(mh.text, length); - owner->emit_modified(mh.position, mh.modificationType, ba, length, - mh.linesAdded, mh.line, mh.foldLevelNow, mh.foldLevelPrev); -} - -void WatcherHelper::NotifyDeleted(Document *, void *) { -} - -void WatcherHelper::NotifyStyleNeeded(Document *, void *, int endPos) { - owner->emit_style_needed(endPos); -} - -void WatcherHelper::NotifyLexerChanged(Document *, void *) { - owner->emit_lexer_changed(); -} - -void WatcherHelper::NotifyErrorOccurred(Document *, void *, int status) { - owner->emit_error_occurred(status); -} - -ScintillaDocument::ScintillaDocument(QObject *parent, void *pdoc_) : - QObject(parent), pdoc(pdoc_), docWatcher(0) { - if (!pdoc) { - pdoc = new Document(); - } - docWatcher = new WatcherHelper(this); - (static_cast(pdoc))->AddRef(); - (static_cast(pdoc))->AddWatcher(docWatcher, pdoc); -} - -ScintillaDocument::~ScintillaDocument() { - Document *doc = static_cast(pdoc); - if (doc) { - doc->RemoveWatcher(docWatcher, doc); - doc->Release(); - } - pdoc = NULL; - delete docWatcher; - docWatcher = NULL; -} - -void *ScintillaDocument::pointer() { - return pdoc; -} - -int ScintillaDocument::line_from_position(int pos) { - return (static_cast(pdoc))->LineFromPosition(pos); -} - -bool ScintillaDocument::is_cr_lf(int pos) { - return (static_cast(pdoc))->IsCrLf(pos); -} - -bool ScintillaDocument::delete_chars(int pos, int len) { - return (static_cast(pdoc))->DeleteChars(pos, len); -} - -int ScintillaDocument::undo() { - return (static_cast(pdoc))->Undo(); -} - -int ScintillaDocument::redo() { - return (static_cast(pdoc))->Redo(); -} - -bool ScintillaDocument::can_undo() { - return (static_cast(pdoc))->CanUndo(); -} - -bool ScintillaDocument::can_redo() { - return (static_cast(pdoc))->CanRedo(); -} - -void ScintillaDocument::delete_undo_history() { - (static_cast(pdoc))->DeleteUndoHistory(); -} - -bool ScintillaDocument::set_undo_collection(bool collect_undo) { - return (static_cast(pdoc))->SetUndoCollection(collect_undo); -} - -bool ScintillaDocument::is_collecting_undo() { - return (static_cast(pdoc))->IsCollectingUndo(); -} - -void ScintillaDocument::begin_undo_action() { - (static_cast(pdoc))->BeginUndoAction(); -} - -void ScintillaDocument::end_undo_action() { - (static_cast(pdoc))->EndUndoAction(); -} - -void ScintillaDocument::set_save_point() { - (static_cast(pdoc))->SetSavePoint(); -} - -bool ScintillaDocument::is_save_point() { - return (static_cast(pdoc))->IsSavePoint(); -} - -void ScintillaDocument::set_read_only(bool read_only) { - (static_cast(pdoc))->SetReadOnly(read_only); -} - -bool ScintillaDocument::is_read_only() { - return (static_cast(pdoc))->IsReadOnly(); -} - -void ScintillaDocument::insert_string(int position, QByteArray &str) { - (static_cast(pdoc))->InsertString(position, str.data(), str.size()); -} - -QByteArray ScintillaDocument::get_char_range(int position, int length) { - Document *doc = static_cast(pdoc); - - if (position < 0 || length <= 0 || position + length > doc->Length()) - return QByteArray(); - - QByteArray ba(length, '\0'); - doc->GetCharRange(ba.data(), position, length); - return ba; -} - -char ScintillaDocument::style_at(int position) { - return (static_cast(pdoc))->StyleAt(position); -} - -int ScintillaDocument::line_start(int lineno) { - return (static_cast(pdoc))->LineStart(lineno); -} - -int ScintillaDocument::line_end(int lineno) { - return (static_cast(pdoc))->LineEnd(lineno); -} - -int ScintillaDocument::line_end_position(int pos) { - return (static_cast(pdoc))->LineEndPosition(pos); -} - -int ScintillaDocument::length() { - return (static_cast(pdoc))->Length(); -} - -int ScintillaDocument::lines_total() { - return (static_cast(pdoc))->LinesTotal(); -} - -void ScintillaDocument::start_styling(int position, char flags) { - (static_cast(pdoc))->StartStyling(position, flags); -} - -bool ScintillaDocument::set_style_for(int length, char style) { - return (static_cast(pdoc))->SetStyleFor(length, style); -} - -int ScintillaDocument::get_end_styled() { - return (static_cast(pdoc))->GetEndStyled(); -} - -void ScintillaDocument::ensure_styled_to(int position) { - (static_cast(pdoc))->EnsureStyledTo(position); -} - -void ScintillaDocument::set_current_indicator(int indic) { - (static_cast(pdoc))->decorations.SetCurrentIndicator(indic); -} - -void ScintillaDocument::decoration_fill_range(int position, int value, int fillLength) { - (static_cast(pdoc))->DecorationFillRange(position, value, fillLength); -} - -int ScintillaDocument::decorations_value_at(int indic, int position) { - return (static_cast(pdoc))->decorations.ValueAt(indic, position); -} - -int ScintillaDocument::decorations_start(int indic, int position) { - return (static_cast(pdoc))->decorations.Start(indic, position); -} - -int ScintillaDocument::decorations_end(int indic, int position) { - return (static_cast(pdoc))->decorations.End(indic, position); -} - -int ScintillaDocument::get_code_page() { - return (static_cast(pdoc))->CodePage(); -} - -void ScintillaDocument::set_code_page(int code_page) { - (static_cast(pdoc))->dbcsCodePage = code_page; -} - -int ScintillaDocument::get_eol_mode() { - return (static_cast(pdoc))->eolMode; -} - -void ScintillaDocument::set_eol_mode(int eol_mode) { - (static_cast(pdoc))->eolMode = eol_mode; -} - -int ScintillaDocument::move_position_outside_char(int pos, int move_dir, bool check_line_end) { - return (static_cast(pdoc))->MovePositionOutsideChar(pos, move_dir, check_line_end); -} - -int ScintillaDocument::get_character(int pos) { - return (static_cast(pdoc))->GetCharacterAndWidth(pos, NULL); -} - -// Signal emitters - -void ScintillaDocument::emit_modify_attempt() { - emit modify_attempt(); -} - -void ScintillaDocument::emit_save_point(bool atSavePoint) { - emit save_point(atSavePoint); -} - -void ScintillaDocument::emit_modified(int position, int modification_type, const QByteArray& text, int length, - int linesAdded, int line, int foldLevelNow, int foldLevelPrev) { - emit modified(position, modification_type, text, length, - linesAdded, line, foldLevelNow, foldLevelPrev); -} - -void ScintillaDocument::emit_style_needed(int pos) { - emit style_needed(pos); -} - -void ScintillaDocument::emit_lexer_changed() { - emit lexer_changed(); -} - -void ScintillaDocument::emit_error_occurred(int status) { - emit error_occurred(status); -} - diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.h b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.h deleted file mode 100644 index 510127f94..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaDocument.h +++ /dev/null @@ -1,109 +0,0 @@ -// ScintillaDocument.h -// Wrapper for Scintilla document object so it can be manipulated independently. -// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware - -#ifndef SCINTILLADOCUMENT_H -#define SCINTILLADOCUMENT_H - -#include - -class WatcherHelper; - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#ifndef EXPORT_IMPORT_API -#ifdef WIN32 -#ifdef MAKING_LIBRARY -#define EXPORT_IMPORT_API __declspec(dllexport) -#else -// Defining dllimport upsets moc -#define EXPORT_IMPORT_API __declspec(dllimport) -//#define EXPORT_IMPORT_API -#endif -#else -#define EXPORT_IMPORT_API -#endif -#endif - -class EXPORT_IMPORT_API ScintillaDocument : public QObject -{ - Q_OBJECT - - void *pdoc; - WatcherHelper *docWatcher; - -public: - explicit ScintillaDocument(QObject *parent = 0, void *pdoc_=0); - virtual ~ScintillaDocument(); - void *pointer(); - - int line_from_position(int pos); - bool is_cr_lf(int pos); - bool delete_chars(int pos, int len); - int undo(); - int redo(); - bool can_undo(); - bool can_redo(); - void delete_undo_history(); - bool set_undo_collection(bool collect_undo); - bool is_collecting_undo(); - void begin_undo_action(); - void end_undo_action(); - void set_save_point(); - bool is_save_point(); - void set_read_only(bool read_only); - bool is_read_only(); - void insert_string(int position, QByteArray &str); - QByteArray get_char_range(int position, int length); - char style_at(int position); - int line_start(int lineno); - int line_end(int lineno); - int line_end_position(int pos); - int length(); - int lines_total(); - void start_styling(int position, char flags); - bool set_style_for(int length, char style); - int get_end_styled(); - void ensure_styled_to(int position); - void set_current_indicator(int indic); - void decoration_fill_range(int position, int value, int fillLength); - int decorations_value_at(int indic, int position); - int decorations_start(int indic, int position); - int decorations_end(int indic, int position); - int get_code_page(); - void set_code_page(int code_page); - int get_eol_mode(); - void set_eol_mode(int eol_mode); - int move_position_outside_char(int pos, int move_dir, bool check_line_end); - - int get_character(int pos); // Calls GetCharacterAndWidth(pos, NULL) - -private: - void emit_modify_attempt(); - void emit_save_point(bool atSavePoint); - void emit_modified(int position, int modification_type, const QByteArray& text, int length, - int linesAdded, int line, int foldLevelNow, int foldLevelPrev); - void emit_style_needed(int pos); - void emit_lexer_changed(); - void emit_error_occurred(int status); - -signals: - void modify_attempt(); - void save_point(bool atSavePoint); - void modified(int position, int modification_type, const QByteArray& text, int length, - int linesAdded, int line, int foldLevelNow, int foldLevelPrev); - void style_needed(int pos); - void lexer_changed(); - void error_occurred(int status); - - friend class ::WatcherHelper; - -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif // SCINTILLADOCUMENT_H diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.cpp b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.cpp deleted file mode 100644 index c325be048..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.cpp +++ /dev/null @@ -1,2840 +0,0 @@ -// ScintillaEdit.cpp -// Extended version of ScintillaEditBase with a method for each API -// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware - -#include "ScintillaEdit.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -ScintillaEdit::ScintillaEdit(QWidget *parent) : ScintillaEditBase(parent) { -} - -ScintillaEdit::~ScintillaEdit() { -} - -QByteArray ScintillaEdit::TextReturner(int message, uptr_t wParam) const { - int length = send(message, wParam, 0); - QByteArray ba(length, '\0'); - send(message, wParam, (sptr_t)ba.data()); - // Remove extra NULs - if (ba.size() > 0 && ba.at(ba.size()-1) == 0) - ba.chop(1); - return ba; -} - -QPairScintillaEdit::find_text(int flags, const char *text, int cpMin, int cpMax) { - struct Sci_TextToFind ft = {{0, 0}, 0, {0, 0}}; - ft.chrg.cpMin = cpMin; - ft.chrg.cpMax = cpMax; - ft.chrgText.cpMin = cpMin; - ft.chrgText.cpMax = cpMax; - ft.lpstrText = const_cast(text); - - int start = send(SCI_FINDTEXT, flags, (uptr_t) (&ft)); - - return QPair(start, ft.chrgText.cpMax); -} - -QByteArray ScintillaEdit::get_text_range(int start, int end) { - if (start > end) - start = end; - - int length = end-start; - QByteArray ba(length+1, '\0'); - struct Sci_TextRange tr = {{start, end}, ba.data()}; - - send(SCI_GETTEXTRANGE, 0, (sptr_t)&tr); - ba.chop(1); // Remove extra NUL - - return ba; -} - -ScintillaDocument *ScintillaEdit::get_doc() { - return new ScintillaDocument(0, (void *)send(SCI_GETDOCPOINTER, 0, 0)); -} - -void ScintillaEdit::set_doc(ScintillaDocument *pdoc_) { - send(SCI_SETDOCPOINTER, 0, (sptr_t)(pdoc_->pointer())); -} - -long ScintillaEdit::format_range(bool draw, QPaintDevice* target, QPaintDevice* measure, - const QRect& print_rect, const QRect& page_rect, - long range_start, long range_end) -{ - Sci_RangeToFormat to_format; - - to_format.hdc = target; - to_format.hdcTarget = measure; - - to_format.rc.left = print_rect.left(); - to_format.rc.top = print_rect.top(); - to_format.rc.right = print_rect.right(); - to_format.rc.bottom = print_rect.bottom(); - - to_format.rcPage.left = page_rect.left(); - to_format.rcPage.top = page_rect.top(); - to_format.rcPage.right = page_rect.right(); - to_format.rcPage.bottom = page_rect.bottom(); - - to_format.chrg.cpMin = range_start; - to_format.chrg.cpMax = range_end; - - return send(SCI_FORMATRANGE, draw, reinterpret_cast(&to_format)); -} - -/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ -void ScintillaEdit::addText(sptr_t length, const char * text) { - send(SCI_ADDTEXT, length, (sptr_t)text); -} - -void ScintillaEdit::addStyledText(sptr_t length, const char * c) { - send(SCI_ADDSTYLEDTEXT, length, (sptr_t)c); -} - -void ScintillaEdit::insertText(sptr_t pos, const char * text) { - send(SCI_INSERTTEXT, pos, (sptr_t)text); -} - -void ScintillaEdit::changeInsertion(sptr_t length, const char * text) { - send(SCI_CHANGEINSERTION, length, (sptr_t)text); -} - -void ScintillaEdit::clearAll() { - send(SCI_CLEARALL, 0, 0); -} - -void ScintillaEdit::deleteRange(sptr_t start, sptr_t lengthDelete) { - send(SCI_DELETERANGE, start, lengthDelete); -} - -void ScintillaEdit::clearDocumentStyle() { - send(SCI_CLEARDOCUMENTSTYLE, 0, 0); -} - -sptr_t ScintillaEdit::length() const { - return send(SCI_GETLENGTH, 0, 0); -} - -sptr_t ScintillaEdit::charAt(sptr_t pos) const { - return send(SCI_GETCHARAT, pos, 0); -} - -sptr_t ScintillaEdit::currentPos() const { - return send(SCI_GETCURRENTPOS, 0, 0); -} - -sptr_t ScintillaEdit::anchor() const { - return send(SCI_GETANCHOR, 0, 0); -} - -sptr_t ScintillaEdit::styleAt(sptr_t pos) const { - return send(SCI_GETSTYLEAT, pos, 0); -} - -void ScintillaEdit::redo() { - send(SCI_REDO, 0, 0); -} - -void ScintillaEdit::setUndoCollection(bool collectUndo) { - send(SCI_SETUNDOCOLLECTION, collectUndo, 0); -} - -void ScintillaEdit::selectAll() { - send(SCI_SELECTALL, 0, 0); -} - -void ScintillaEdit::setSavePoint() { - send(SCI_SETSAVEPOINT, 0, 0); -} - -bool ScintillaEdit::canRedo() { - return send(SCI_CANREDO, 0, 0); -} - -sptr_t ScintillaEdit::markerLineFromHandle(sptr_t markerHandle) { - return send(SCI_MARKERLINEFROMHANDLE, markerHandle, 0); -} - -void ScintillaEdit::markerDeleteHandle(sptr_t markerHandle) { - send(SCI_MARKERDELETEHANDLE, markerHandle, 0); -} - -bool ScintillaEdit::undoCollection() const { - return send(SCI_GETUNDOCOLLECTION, 0, 0); -} - -sptr_t ScintillaEdit::viewWS() const { - return send(SCI_GETVIEWWS, 0, 0); -} - -void ScintillaEdit::setViewWS(sptr_t viewWS) { - send(SCI_SETVIEWWS, viewWS, 0); -} - -sptr_t ScintillaEdit::tabDrawMode() const { - return send(SCI_GETTABDRAWMODE, 0, 0); -} - -void ScintillaEdit::setTabDrawMode(sptr_t tabDrawMode) { - send(SCI_SETTABDRAWMODE, tabDrawMode, 0); -} - -sptr_t ScintillaEdit::positionFromPoint(sptr_t x, sptr_t y) { - return send(SCI_POSITIONFROMPOINT, x, y); -} - -sptr_t ScintillaEdit::positionFromPointClose(sptr_t x, sptr_t y) { - return send(SCI_POSITIONFROMPOINTCLOSE, x, y); -} - -void ScintillaEdit::gotoLine(sptr_t line) { - send(SCI_GOTOLINE, line, 0); -} - -void ScintillaEdit::gotoPos(sptr_t caret) { - send(SCI_GOTOPOS, caret, 0); -} - -void ScintillaEdit::setAnchor(sptr_t anchor) { - send(SCI_SETANCHOR, anchor, 0); -} - -QByteArray ScintillaEdit::getCurLine(sptr_t length) { - return TextReturner(SCI_GETCURLINE, length); -} - -sptr_t ScintillaEdit::endStyled() const { - return send(SCI_GETENDSTYLED, 0, 0); -} - -void ScintillaEdit::convertEOLs(sptr_t eolMode) { - send(SCI_CONVERTEOLS, eolMode, 0); -} - -sptr_t ScintillaEdit::eOLMode() const { - return send(SCI_GETEOLMODE, 0, 0); -} - -void ScintillaEdit::setEOLMode(sptr_t eolMode) { - send(SCI_SETEOLMODE, eolMode, 0); -} - -void ScintillaEdit::startStyling(sptr_t start, sptr_t unused) { - send(SCI_STARTSTYLING, start, unused); -} - -void ScintillaEdit::setStyling(sptr_t length, sptr_t style) { - send(SCI_SETSTYLING, length, style); -} - -bool ScintillaEdit::bufferedDraw() const { - return send(SCI_GETBUFFEREDDRAW, 0, 0); -} - -void ScintillaEdit::setBufferedDraw(bool buffered) { - send(SCI_SETBUFFEREDDRAW, buffered, 0); -} - -void ScintillaEdit::setTabWidth(sptr_t tabWidth) { - send(SCI_SETTABWIDTH, tabWidth, 0); -} - -sptr_t ScintillaEdit::tabWidth() const { - return send(SCI_GETTABWIDTH, 0, 0); -} - -void ScintillaEdit::clearTabStops(sptr_t line) { - send(SCI_CLEARTABSTOPS, line, 0); -} - -void ScintillaEdit::addTabStop(sptr_t line, sptr_t x) { - send(SCI_ADDTABSTOP, line, x); -} - -sptr_t ScintillaEdit::getNextTabStop(sptr_t line, sptr_t x) { - return send(SCI_GETNEXTTABSTOP, line, x); -} - -void ScintillaEdit::setCodePage(sptr_t codePage) { - send(SCI_SETCODEPAGE, codePage, 0); -} - -sptr_t ScintillaEdit::iMEInteraction() const { - return send(SCI_GETIMEINTERACTION, 0, 0); -} - -void ScintillaEdit::setIMEInteraction(sptr_t imeInteraction) { - send(SCI_SETIMEINTERACTION, imeInteraction, 0); -} - -void ScintillaEdit::markerDefine(sptr_t markerNumber, sptr_t markerSymbol) { - send(SCI_MARKERDEFINE, markerNumber, markerSymbol); -} - -void ScintillaEdit::markerSetFore(sptr_t markerNumber, sptr_t fore) { - send(SCI_MARKERSETFORE, markerNumber, fore); -} - -void ScintillaEdit::markerSetBack(sptr_t markerNumber, sptr_t back) { - send(SCI_MARKERSETBACK, markerNumber, back); -} - -void ScintillaEdit::markerSetBackSelected(sptr_t markerNumber, sptr_t back) { - send(SCI_MARKERSETBACKSELECTED, markerNumber, back); -} - -void ScintillaEdit::markerEnableHighlight(bool enabled) { - send(SCI_MARKERENABLEHIGHLIGHT, enabled, 0); -} - -sptr_t ScintillaEdit::markerAdd(sptr_t line, sptr_t markerNumber) { - return send(SCI_MARKERADD, line, markerNumber); -} - -void ScintillaEdit::markerDelete(sptr_t line, sptr_t markerNumber) { - send(SCI_MARKERDELETE, line, markerNumber); -} - -void ScintillaEdit::markerDeleteAll(sptr_t markerNumber) { - send(SCI_MARKERDELETEALL, markerNumber, 0); -} - -sptr_t ScintillaEdit::markerGet(sptr_t line) { - return send(SCI_MARKERGET, line, 0); -} - -sptr_t ScintillaEdit::markerNext(sptr_t lineStart, sptr_t markerMask) { - return send(SCI_MARKERNEXT, lineStart, markerMask); -} - -sptr_t ScintillaEdit::markerPrevious(sptr_t lineStart, sptr_t markerMask) { - return send(SCI_MARKERPREVIOUS, lineStart, markerMask); -} - -void ScintillaEdit::markerDefinePixmap(sptr_t markerNumber, const char * pixmap) { - send(SCI_MARKERDEFINEPIXMAP, markerNumber, (sptr_t)pixmap); -} - -void ScintillaEdit::markerAddSet(sptr_t line, sptr_t markerSet) { - send(SCI_MARKERADDSET, line, markerSet); -} - -void ScintillaEdit::markerSetAlpha(sptr_t markerNumber, sptr_t alpha) { - send(SCI_MARKERSETALPHA, markerNumber, alpha); -} - -void ScintillaEdit::setMarginTypeN(sptr_t margin, sptr_t marginType) { - send(SCI_SETMARGINTYPEN, margin, marginType); -} - -sptr_t ScintillaEdit::marginTypeN(sptr_t margin) const { - return send(SCI_GETMARGINTYPEN, margin, 0); -} - -void ScintillaEdit::setMarginWidthN(sptr_t margin, sptr_t pixelWidth) { - send(SCI_SETMARGINWIDTHN, margin, pixelWidth); -} - -sptr_t ScintillaEdit::marginWidthN(sptr_t margin) const { - return send(SCI_GETMARGINWIDTHN, margin, 0); -} - -void ScintillaEdit::setMarginMaskN(sptr_t margin, sptr_t mask) { - send(SCI_SETMARGINMASKN, margin, mask); -} - -sptr_t ScintillaEdit::marginMaskN(sptr_t margin) const { - return send(SCI_GETMARGINMASKN, margin, 0); -} - -void ScintillaEdit::setMarginSensitiveN(sptr_t margin, bool sensitive) { - send(SCI_SETMARGINSENSITIVEN, margin, sensitive); -} - -bool ScintillaEdit::marginSensitiveN(sptr_t margin) const { - return send(SCI_GETMARGINSENSITIVEN, margin, 0); -} - -void ScintillaEdit::setMarginCursorN(sptr_t margin, sptr_t cursor) { - send(SCI_SETMARGINCURSORN, margin, cursor); -} - -sptr_t ScintillaEdit::marginCursorN(sptr_t margin) const { - return send(SCI_GETMARGINCURSORN, margin, 0); -} - -void ScintillaEdit::setMarginBackN(sptr_t margin, sptr_t back) { - send(SCI_SETMARGINBACKN, margin, back); -} - -sptr_t ScintillaEdit::marginBackN(sptr_t margin) const { - return send(SCI_GETMARGINBACKN, margin, 0); -} - -void ScintillaEdit::setMargins(sptr_t margins) { - send(SCI_SETMARGINS, margins, 0); -} - -sptr_t ScintillaEdit::margins() const { - return send(SCI_GETMARGINS, 0, 0); -} - -void ScintillaEdit::styleClearAll() { - send(SCI_STYLECLEARALL, 0, 0); -} - -void ScintillaEdit::styleSetFore(sptr_t style, sptr_t fore) { - send(SCI_STYLESETFORE, style, fore); -} - -void ScintillaEdit::styleSetBack(sptr_t style, sptr_t back) { - send(SCI_STYLESETBACK, style, back); -} - -void ScintillaEdit::styleSetBold(sptr_t style, bool bold) { - send(SCI_STYLESETBOLD, style, bold); -} - -void ScintillaEdit::styleSetItalic(sptr_t style, bool italic) { - send(SCI_STYLESETITALIC, style, italic); -} - -void ScintillaEdit::styleSetSize(sptr_t style, sptr_t sizePoints) { - send(SCI_STYLESETSIZE, style, sizePoints); -} - -void ScintillaEdit::styleSetFont(sptr_t style, const char * fontName) { - send(SCI_STYLESETFONT, style, (sptr_t)fontName); -} - -void ScintillaEdit::styleSetEOLFilled(sptr_t style, bool eolFilled) { - send(SCI_STYLESETEOLFILLED, style, eolFilled); -} - -void ScintillaEdit::styleResetDefault() { - send(SCI_STYLERESETDEFAULT, 0, 0); -} - -void ScintillaEdit::styleSetUnderline(sptr_t style, bool underline) { - send(SCI_STYLESETUNDERLINE, style, underline); -} - -sptr_t ScintillaEdit::styleFore(sptr_t style) const { - return send(SCI_STYLEGETFORE, style, 0); -} - -sptr_t ScintillaEdit::styleBack(sptr_t style) const { - return send(SCI_STYLEGETBACK, style, 0); -} - -bool ScintillaEdit::styleBold(sptr_t style) const { - return send(SCI_STYLEGETBOLD, style, 0); -} - -bool ScintillaEdit::styleItalic(sptr_t style) const { - return send(SCI_STYLEGETITALIC, style, 0); -} - -sptr_t ScintillaEdit::styleSize(sptr_t style) const { - return send(SCI_STYLEGETSIZE, style, 0); -} - -QByteArray ScintillaEdit::styleFont(sptr_t style) const { - return TextReturner(SCI_STYLEGETFONT, style); -} - -bool ScintillaEdit::styleEOLFilled(sptr_t style) const { - return send(SCI_STYLEGETEOLFILLED, style, 0); -} - -bool ScintillaEdit::styleUnderline(sptr_t style) const { - return send(SCI_STYLEGETUNDERLINE, style, 0); -} - -sptr_t ScintillaEdit::styleCase(sptr_t style) const { - return send(SCI_STYLEGETCASE, style, 0); -} - -sptr_t ScintillaEdit::styleCharacterSet(sptr_t style) const { - return send(SCI_STYLEGETCHARACTERSET, style, 0); -} - -bool ScintillaEdit::styleVisible(sptr_t style) const { - return send(SCI_STYLEGETVISIBLE, style, 0); -} - -bool ScintillaEdit::styleChangeable(sptr_t style) const { - return send(SCI_STYLEGETCHANGEABLE, style, 0); -} - -bool ScintillaEdit::styleHotSpot(sptr_t style) const { - return send(SCI_STYLEGETHOTSPOT, style, 0); -} - -void ScintillaEdit::styleSetCase(sptr_t style, sptr_t caseVisible) { - send(SCI_STYLESETCASE, style, caseVisible); -} - -void ScintillaEdit::styleSetSizeFractional(sptr_t style, sptr_t sizeHundredthPoints) { - send(SCI_STYLESETSIZEFRACTIONAL, style, sizeHundredthPoints); -} - -sptr_t ScintillaEdit::styleSizeFractional(sptr_t style) const { - return send(SCI_STYLEGETSIZEFRACTIONAL, style, 0); -} - -void ScintillaEdit::styleSetWeight(sptr_t style, sptr_t weight) { - send(SCI_STYLESETWEIGHT, style, weight); -} - -sptr_t ScintillaEdit::styleWeight(sptr_t style) const { - return send(SCI_STYLEGETWEIGHT, style, 0); -} - -void ScintillaEdit::styleSetCharacterSet(sptr_t style, sptr_t characterSet) { - send(SCI_STYLESETCHARACTERSET, style, characterSet); -} - -void ScintillaEdit::styleSetHotSpot(sptr_t style, bool hotspot) { - send(SCI_STYLESETHOTSPOT, style, hotspot); -} - -void ScintillaEdit::setSelFore(bool useSetting, sptr_t fore) { - send(SCI_SETSELFORE, useSetting, fore); -} - -void ScintillaEdit::setSelBack(bool useSetting, sptr_t back) { - send(SCI_SETSELBACK, useSetting, back); -} - -sptr_t ScintillaEdit::selAlpha() const { - return send(SCI_GETSELALPHA, 0, 0); -} - -void ScintillaEdit::setSelAlpha(sptr_t alpha) { - send(SCI_SETSELALPHA, alpha, 0); -} - -bool ScintillaEdit::selEOLFilled() const { - return send(SCI_GETSELEOLFILLED, 0, 0); -} - -void ScintillaEdit::setSelEOLFilled(bool filled) { - send(SCI_SETSELEOLFILLED, filled, 0); -} - -void ScintillaEdit::setCaretFore(sptr_t fore) { - send(SCI_SETCARETFORE, fore, 0); -} - -void ScintillaEdit::assignCmdKey(sptr_t keyDefinition, sptr_t sciCommand) { - send(SCI_ASSIGNCMDKEY, keyDefinition, sciCommand); -} - -void ScintillaEdit::clearCmdKey(sptr_t keyDefinition) { - send(SCI_CLEARCMDKEY, keyDefinition, 0); -} - -void ScintillaEdit::clearAllCmdKeys() { - send(SCI_CLEARALLCMDKEYS, 0, 0); -} - -void ScintillaEdit::setStylingEx(sptr_t length, const char * styles) { - send(SCI_SETSTYLINGEX, length, (sptr_t)styles); -} - -void ScintillaEdit::styleSetVisible(sptr_t style, bool visible) { - send(SCI_STYLESETVISIBLE, style, visible); -} - -sptr_t ScintillaEdit::caretPeriod() const { - return send(SCI_GETCARETPERIOD, 0, 0); -} - -void ScintillaEdit::setCaretPeriod(sptr_t periodMilliseconds) { - send(SCI_SETCARETPERIOD, periodMilliseconds, 0); -} - -void ScintillaEdit::setWordChars(const char * characters) { - send(SCI_SETWORDCHARS, 0, (sptr_t)characters); -} - -QByteArray ScintillaEdit::wordChars() const { - return TextReturner(SCI_GETWORDCHARS, 0); -} - -void ScintillaEdit::beginUndoAction() { - send(SCI_BEGINUNDOACTION, 0, 0); -} - -void ScintillaEdit::endUndoAction() { - send(SCI_ENDUNDOACTION, 0, 0); -} - -void ScintillaEdit::indicSetStyle(sptr_t indicator, sptr_t indicatorStyle) { - send(SCI_INDICSETSTYLE, indicator, indicatorStyle); -} - -sptr_t ScintillaEdit::indicStyle(sptr_t indicator) const { - return send(SCI_INDICGETSTYLE, indicator, 0); -} - -void ScintillaEdit::indicSetFore(sptr_t indicator, sptr_t fore) { - send(SCI_INDICSETFORE, indicator, fore); -} - -sptr_t ScintillaEdit::indicFore(sptr_t indicator) const { - return send(SCI_INDICGETFORE, indicator, 0); -} - -void ScintillaEdit::indicSetUnder(sptr_t indicator, bool under) { - send(SCI_INDICSETUNDER, indicator, under); -} - -bool ScintillaEdit::indicUnder(sptr_t indicator) const { - return send(SCI_INDICGETUNDER, indicator, 0); -} - -void ScintillaEdit::indicSetHoverStyle(sptr_t indicator, sptr_t indicatorStyle) { - send(SCI_INDICSETHOVERSTYLE, indicator, indicatorStyle); -} - -sptr_t ScintillaEdit::indicHoverStyle(sptr_t indicator) const { - return send(SCI_INDICGETHOVERSTYLE, indicator, 0); -} - -void ScintillaEdit::indicSetHoverFore(sptr_t indicator, sptr_t fore) { - send(SCI_INDICSETHOVERFORE, indicator, fore); -} - -sptr_t ScintillaEdit::indicHoverFore(sptr_t indicator) const { - return send(SCI_INDICGETHOVERFORE, indicator, 0); -} - -void ScintillaEdit::indicSetFlags(sptr_t indicator, sptr_t flags) { - send(SCI_INDICSETFLAGS, indicator, flags); -} - -sptr_t ScintillaEdit::indicFlags(sptr_t indicator) const { - return send(SCI_INDICGETFLAGS, indicator, 0); -} - -void ScintillaEdit::setWhitespaceFore(bool useSetting, sptr_t fore) { - send(SCI_SETWHITESPACEFORE, useSetting, fore); -} - -void ScintillaEdit::setWhitespaceBack(bool useSetting, sptr_t back) { - send(SCI_SETWHITESPACEBACK, useSetting, back); -} - -void ScintillaEdit::setWhitespaceSize(sptr_t size) { - send(SCI_SETWHITESPACESIZE, size, 0); -} - -sptr_t ScintillaEdit::whitespaceSize() const { - return send(SCI_GETWHITESPACESIZE, 0, 0); -} - -void ScintillaEdit::setStyleBits(sptr_t bits) { - send(SCI_SETSTYLEBITS, bits, 0); -} - -sptr_t ScintillaEdit::styleBits() const { - return send(SCI_GETSTYLEBITS, 0, 0); -} - -void ScintillaEdit::setLineState(sptr_t line, sptr_t state) { - send(SCI_SETLINESTATE, line, state); -} - -sptr_t ScintillaEdit::lineState(sptr_t line) const { - return send(SCI_GETLINESTATE, line, 0); -} - -sptr_t ScintillaEdit::maxLineState() const { - return send(SCI_GETMAXLINESTATE, 0, 0); -} - -bool ScintillaEdit::caretLineVisible() const { - return send(SCI_GETCARETLINEVISIBLE, 0, 0); -} - -void ScintillaEdit::setCaretLineVisible(bool show) { - send(SCI_SETCARETLINEVISIBLE, show, 0); -} - -sptr_t ScintillaEdit::caretLineBack() const { - return send(SCI_GETCARETLINEBACK, 0, 0); -} - -void ScintillaEdit::setCaretLineBack(sptr_t back) { - send(SCI_SETCARETLINEBACK, back, 0); -} - -void ScintillaEdit::styleSetChangeable(sptr_t style, bool changeable) { - send(SCI_STYLESETCHANGEABLE, style, changeable); -} - -void ScintillaEdit::autoCShow(sptr_t lengthEntered, const char * itemList) { - send(SCI_AUTOCSHOW, lengthEntered, (sptr_t)itemList); -} - -void ScintillaEdit::autoCCancel() { - send(SCI_AUTOCCANCEL, 0, 0); -} - -bool ScintillaEdit::autoCActive() { - return send(SCI_AUTOCACTIVE, 0, 0); -} - -sptr_t ScintillaEdit::autoCPosStart() { - return send(SCI_AUTOCPOSSTART, 0, 0); -} - -void ScintillaEdit::autoCComplete() { - send(SCI_AUTOCCOMPLETE, 0, 0); -} - -void ScintillaEdit::autoCStops(const char * characterSet) { - send(SCI_AUTOCSTOPS, 0, (sptr_t)characterSet); -} - -void ScintillaEdit::autoCSetSeparator(sptr_t separatorCharacter) { - send(SCI_AUTOCSETSEPARATOR, separatorCharacter, 0); -} - -sptr_t ScintillaEdit::autoCSeparator() const { - return send(SCI_AUTOCGETSEPARATOR, 0, 0); -} - -void ScintillaEdit::autoCSelect(const char * select) { - send(SCI_AUTOCSELECT, 0, (sptr_t)select); -} - -void ScintillaEdit::autoCSetCancelAtStart(bool cancel) { - send(SCI_AUTOCSETCANCELATSTART, cancel, 0); -} - -bool ScintillaEdit::autoCCancelAtStart() const { - return send(SCI_AUTOCGETCANCELATSTART, 0, 0); -} - -void ScintillaEdit::autoCSetFillUps(const char * characterSet) { - send(SCI_AUTOCSETFILLUPS, 0, (sptr_t)characterSet); -} - -void ScintillaEdit::autoCSetChooseSingle(bool chooseSingle) { - send(SCI_AUTOCSETCHOOSESINGLE, chooseSingle, 0); -} - -bool ScintillaEdit::autoCChooseSingle() const { - return send(SCI_AUTOCGETCHOOSESINGLE, 0, 0); -} - -void ScintillaEdit::autoCSetIgnoreCase(bool ignoreCase) { - send(SCI_AUTOCSETIGNORECASE, ignoreCase, 0); -} - -bool ScintillaEdit::autoCIgnoreCase() const { - return send(SCI_AUTOCGETIGNORECASE, 0, 0); -} - -void ScintillaEdit::userListShow(sptr_t listType, const char * itemList) { - send(SCI_USERLISTSHOW, listType, (sptr_t)itemList); -} - -void ScintillaEdit::autoCSetAutoHide(bool autoHide) { - send(SCI_AUTOCSETAUTOHIDE, autoHide, 0); -} - -bool ScintillaEdit::autoCAutoHide() const { - return send(SCI_AUTOCGETAUTOHIDE, 0, 0); -} - -void ScintillaEdit::autoCSetDropRestOfWord(bool dropRestOfWord) { - send(SCI_AUTOCSETDROPRESTOFWORD, dropRestOfWord, 0); -} - -bool ScintillaEdit::autoCDropRestOfWord() const { - return send(SCI_AUTOCGETDROPRESTOFWORD, 0, 0); -} - -void ScintillaEdit::registerImage(sptr_t type, const char * xpmData) { - send(SCI_REGISTERIMAGE, type, (sptr_t)xpmData); -} - -void ScintillaEdit::clearRegisteredImages() { - send(SCI_CLEARREGISTEREDIMAGES, 0, 0); -} - -sptr_t ScintillaEdit::autoCTypeSeparator() const { - return send(SCI_AUTOCGETTYPESEPARATOR, 0, 0); -} - -void ScintillaEdit::autoCSetTypeSeparator(sptr_t separatorCharacter) { - send(SCI_AUTOCSETTYPESEPARATOR, separatorCharacter, 0); -} - -void ScintillaEdit::autoCSetMaxWidth(sptr_t characterCount) { - send(SCI_AUTOCSETMAXWIDTH, characterCount, 0); -} - -sptr_t ScintillaEdit::autoCMaxWidth() const { - return send(SCI_AUTOCGETMAXWIDTH, 0, 0); -} - -void ScintillaEdit::autoCSetMaxHeight(sptr_t rowCount) { - send(SCI_AUTOCSETMAXHEIGHT, rowCount, 0); -} - -sptr_t ScintillaEdit::autoCMaxHeight() const { - return send(SCI_AUTOCGETMAXHEIGHT, 0, 0); -} - -void ScintillaEdit::setIndent(sptr_t indentSize) { - send(SCI_SETINDENT, indentSize, 0); -} - -sptr_t ScintillaEdit::indent() const { - return send(SCI_GETINDENT, 0, 0); -} - -void ScintillaEdit::setUseTabs(bool useTabs) { - send(SCI_SETUSETABS, useTabs, 0); -} - -bool ScintillaEdit::useTabs() const { - return send(SCI_GETUSETABS, 0, 0); -} - -void ScintillaEdit::setLineIndentation(sptr_t line, sptr_t indentation) { - send(SCI_SETLINEINDENTATION, line, indentation); -} - -sptr_t ScintillaEdit::lineIndentation(sptr_t line) const { - return send(SCI_GETLINEINDENTATION, line, 0); -} - -sptr_t ScintillaEdit::lineIndentPosition(sptr_t line) const { - return send(SCI_GETLINEINDENTPOSITION, line, 0); -} - -sptr_t ScintillaEdit::column(sptr_t pos) const { - return send(SCI_GETCOLUMN, pos, 0); -} - -sptr_t ScintillaEdit::countCharacters(sptr_t start, sptr_t end) { - return send(SCI_COUNTCHARACTERS, start, end); -} - -void ScintillaEdit::setHScrollBar(bool visible) { - send(SCI_SETHSCROLLBAR, visible, 0); -} - -bool ScintillaEdit::hScrollBar() const { - return send(SCI_GETHSCROLLBAR, 0, 0); -} - -void ScintillaEdit::setIndentationGuides(sptr_t indentView) { - send(SCI_SETINDENTATIONGUIDES, indentView, 0); -} - -sptr_t ScintillaEdit::indentationGuides() const { - return send(SCI_GETINDENTATIONGUIDES, 0, 0); -} - -void ScintillaEdit::setHighlightGuide(sptr_t column) { - send(SCI_SETHIGHLIGHTGUIDE, column, 0); -} - -sptr_t ScintillaEdit::highlightGuide() const { - return send(SCI_GETHIGHLIGHTGUIDE, 0, 0); -} - -sptr_t ScintillaEdit::lineEndPosition(sptr_t line) const { - return send(SCI_GETLINEENDPOSITION, line, 0); -} - -sptr_t ScintillaEdit::codePage() const { - return send(SCI_GETCODEPAGE, 0, 0); -} - -sptr_t ScintillaEdit::caretFore() const { - return send(SCI_GETCARETFORE, 0, 0); -} - -bool ScintillaEdit::readOnly() const { - return send(SCI_GETREADONLY, 0, 0); -} - -void ScintillaEdit::setCurrentPos(sptr_t caret) { - send(SCI_SETCURRENTPOS, caret, 0); -} - -void ScintillaEdit::setSelectionStart(sptr_t anchor) { - send(SCI_SETSELECTIONSTART, anchor, 0); -} - -sptr_t ScintillaEdit::selectionStart() const { - return send(SCI_GETSELECTIONSTART, 0, 0); -} - -void ScintillaEdit::setSelectionEnd(sptr_t caret) { - send(SCI_SETSELECTIONEND, caret, 0); -} - -sptr_t ScintillaEdit::selectionEnd() const { - return send(SCI_GETSELECTIONEND, 0, 0); -} - -void ScintillaEdit::setEmptySelection(sptr_t caret) { - send(SCI_SETEMPTYSELECTION, caret, 0); -} - -void ScintillaEdit::setPrintMagnification(sptr_t magnification) { - send(SCI_SETPRINTMAGNIFICATION, magnification, 0); -} - -sptr_t ScintillaEdit::printMagnification() const { - return send(SCI_GETPRINTMAGNIFICATION, 0, 0); -} - -void ScintillaEdit::setPrintColourMode(sptr_t mode) { - send(SCI_SETPRINTCOLOURMODE, mode, 0); -} - -sptr_t ScintillaEdit::printColourMode() const { - return send(SCI_GETPRINTCOLOURMODE, 0, 0); -} - -sptr_t ScintillaEdit::firstVisibleLine() const { - return send(SCI_GETFIRSTVISIBLELINE, 0, 0); -} - -QByteArray ScintillaEdit::getLine(sptr_t line) { - return TextReturner(SCI_GETLINE, line); -} - -sptr_t ScintillaEdit::lineCount() const { - return send(SCI_GETLINECOUNT, 0, 0); -} - -void ScintillaEdit::setMarginLeft(sptr_t pixelWidth) { - send(SCI_SETMARGINLEFT, 0, pixelWidth); -} - -sptr_t ScintillaEdit::marginLeft() const { - return send(SCI_GETMARGINLEFT, 0, 0); -} - -void ScintillaEdit::setMarginRight(sptr_t pixelWidth) { - send(SCI_SETMARGINRIGHT, 0, pixelWidth); -} - -sptr_t ScintillaEdit::marginRight() const { - return send(SCI_GETMARGINRIGHT, 0, 0); -} - -bool ScintillaEdit::modify() const { - return send(SCI_GETMODIFY, 0, 0); -} - -void ScintillaEdit::setSel(sptr_t anchor, sptr_t caret) { - send(SCI_SETSEL, anchor, caret); -} - -QByteArray ScintillaEdit::getSelText() { - return TextReturner(SCI_GETSELTEXT, 0); -} - -void ScintillaEdit::hideSelection(bool hide) { - send(SCI_HIDESELECTION, hide, 0); -} - -sptr_t ScintillaEdit::pointXFromPosition(sptr_t pos) { - return send(SCI_POINTXFROMPOSITION, 0, pos); -} - -sptr_t ScintillaEdit::pointYFromPosition(sptr_t pos) { - return send(SCI_POINTYFROMPOSITION, 0, pos); -} - -sptr_t ScintillaEdit::lineFromPosition(sptr_t pos) { - return send(SCI_LINEFROMPOSITION, pos, 0); -} - -sptr_t ScintillaEdit::positionFromLine(sptr_t line) { - return send(SCI_POSITIONFROMLINE, line, 0); -} - -void ScintillaEdit::lineScroll(sptr_t columns, sptr_t lines) { - send(SCI_LINESCROLL, columns, lines); -} - -void ScintillaEdit::scrollCaret() { - send(SCI_SCROLLCARET, 0, 0); -} - -void ScintillaEdit::scrollRange(sptr_t secondary, sptr_t primary) { - send(SCI_SCROLLRANGE, secondary, primary); -} - -void ScintillaEdit::replaceSel(const char * text) { - send(SCI_REPLACESEL, 0, (sptr_t)text); -} - -void ScintillaEdit::setReadOnly(bool readOnly) { - send(SCI_SETREADONLY, readOnly, 0); -} - -void ScintillaEdit::null() { - send(SCI_NULL, 0, 0); -} - -bool ScintillaEdit::canPaste() { - return send(SCI_CANPASTE, 0, 0); -} - -bool ScintillaEdit::canUndo() { - return send(SCI_CANUNDO, 0, 0); -} - -void ScintillaEdit::emptyUndoBuffer() { - send(SCI_EMPTYUNDOBUFFER, 0, 0); -} - -void ScintillaEdit::undo() { - send(SCI_UNDO, 0, 0); -} - -void ScintillaEdit::cut() { - send(SCI_CUT, 0, 0); -} - -void ScintillaEdit::copy() { - send(SCI_COPY, 0, 0); -} - -void ScintillaEdit::paste() { - send(SCI_PASTE, 0, 0); -} - -void ScintillaEdit::clear() { - send(SCI_CLEAR, 0, 0); -} - -void ScintillaEdit::setText(const char * text) { - send(SCI_SETTEXT, 0, (sptr_t)text); -} - -QByteArray ScintillaEdit::getText(sptr_t length) { - return TextReturner(SCI_GETTEXT, length); -} - -sptr_t ScintillaEdit::textLength() const { - return send(SCI_GETTEXTLENGTH, 0, 0); -} - -sptr_t ScintillaEdit::directFunction() const { - return send(SCI_GETDIRECTFUNCTION, 0, 0); -} - -sptr_t ScintillaEdit::directPointer() const { - return send(SCI_GETDIRECTPOINTER, 0, 0); -} - -void ScintillaEdit::setOvertype(bool overType) { - send(SCI_SETOVERTYPE, overType, 0); -} - -bool ScintillaEdit::overtype() const { - return send(SCI_GETOVERTYPE, 0, 0); -} - -void ScintillaEdit::setCaretWidth(sptr_t pixelWidth) { - send(SCI_SETCARETWIDTH, pixelWidth, 0); -} - -sptr_t ScintillaEdit::caretWidth() const { - return send(SCI_GETCARETWIDTH, 0, 0); -} - -void ScintillaEdit::setTargetStart(sptr_t start) { - send(SCI_SETTARGETSTART, start, 0); -} - -sptr_t ScintillaEdit::targetStart() const { - return send(SCI_GETTARGETSTART, 0, 0); -} - -void ScintillaEdit::setTargetEnd(sptr_t end) { - send(SCI_SETTARGETEND, end, 0); -} - -sptr_t ScintillaEdit::targetEnd() const { - return send(SCI_GETTARGETEND, 0, 0); -} - -void ScintillaEdit::setTargetRange(sptr_t start, sptr_t end) { - send(SCI_SETTARGETRANGE, start, end); -} - -QByteArray ScintillaEdit::targetText() const { - return TextReturner(SCI_GETTARGETTEXT, 0); -} - -void ScintillaEdit::targetFromSelection() { - send(SCI_TARGETFROMSELECTION, 0, 0); -} - -void ScintillaEdit::targetWholeDocument() { - send(SCI_TARGETWHOLEDOCUMENT, 0, 0); -} - -sptr_t ScintillaEdit::replaceTarget(sptr_t length, const char * text) { - return send(SCI_REPLACETARGET, length, (sptr_t)text); -} - -sptr_t ScintillaEdit::replaceTargetRE(sptr_t length, const char * text) { - return send(SCI_REPLACETARGETRE, length, (sptr_t)text); -} - -sptr_t ScintillaEdit::searchInTarget(sptr_t length, const char * text) { - return send(SCI_SEARCHINTARGET, length, (sptr_t)text); -} - -void ScintillaEdit::setSearchFlags(sptr_t searchFlags) { - send(SCI_SETSEARCHFLAGS, searchFlags, 0); -} - -sptr_t ScintillaEdit::searchFlags() const { - return send(SCI_GETSEARCHFLAGS, 0, 0); -} - -void ScintillaEdit::callTipShow(sptr_t pos, const char * definition) { - send(SCI_CALLTIPSHOW, pos, (sptr_t)definition); -} - -void ScintillaEdit::callTipCancel() { - send(SCI_CALLTIPCANCEL, 0, 0); -} - -bool ScintillaEdit::callTipActive() { - return send(SCI_CALLTIPACTIVE, 0, 0); -} - -sptr_t ScintillaEdit::callTipPosStart() { - return send(SCI_CALLTIPPOSSTART, 0, 0); -} - -void ScintillaEdit::callTipSetPosStart(sptr_t posStart) { - send(SCI_CALLTIPSETPOSSTART, posStart, 0); -} - -void ScintillaEdit::callTipSetHlt(sptr_t highlightStart, sptr_t highlightEnd) { - send(SCI_CALLTIPSETHLT, highlightStart, highlightEnd); -} - -void ScintillaEdit::callTipSetBack(sptr_t back) { - send(SCI_CALLTIPSETBACK, back, 0); -} - -void ScintillaEdit::callTipSetFore(sptr_t fore) { - send(SCI_CALLTIPSETFORE, fore, 0); -} - -void ScintillaEdit::callTipSetForeHlt(sptr_t fore) { - send(SCI_CALLTIPSETFOREHLT, fore, 0); -} - -void ScintillaEdit::callTipUseStyle(sptr_t tabSize) { - send(SCI_CALLTIPUSESTYLE, tabSize, 0); -} - -void ScintillaEdit::callTipSetPosition(bool above) { - send(SCI_CALLTIPSETPOSITION, above, 0); -} - -sptr_t ScintillaEdit::visibleFromDocLine(sptr_t docLine) { - return send(SCI_VISIBLEFROMDOCLINE, docLine, 0); -} - -sptr_t ScintillaEdit::docLineFromVisible(sptr_t displayLine) { - return send(SCI_DOCLINEFROMVISIBLE, displayLine, 0); -} - -sptr_t ScintillaEdit::wrapCount(sptr_t docLine) { - return send(SCI_WRAPCOUNT, docLine, 0); -} - -void ScintillaEdit::setFoldLevel(sptr_t line, sptr_t level) { - send(SCI_SETFOLDLEVEL, line, level); -} - -sptr_t ScintillaEdit::foldLevel(sptr_t line) const { - return send(SCI_GETFOLDLEVEL, line, 0); -} - -sptr_t ScintillaEdit::lastChild(sptr_t line, sptr_t level) const { - return send(SCI_GETLASTCHILD, line, level); -} - -sptr_t ScintillaEdit::foldParent(sptr_t line) const { - return send(SCI_GETFOLDPARENT, line, 0); -} - -void ScintillaEdit::showLines(sptr_t lineStart, sptr_t lineEnd) { - send(SCI_SHOWLINES, lineStart, lineEnd); -} - -void ScintillaEdit::hideLines(sptr_t lineStart, sptr_t lineEnd) { - send(SCI_HIDELINES, lineStart, lineEnd); -} - -bool ScintillaEdit::lineVisible(sptr_t line) const { - return send(SCI_GETLINEVISIBLE, line, 0); -} - -bool ScintillaEdit::allLinesVisible() const { - return send(SCI_GETALLLINESVISIBLE, 0, 0); -} - -void ScintillaEdit::setFoldExpanded(sptr_t line, bool expanded) { - send(SCI_SETFOLDEXPANDED, line, expanded); -} - -bool ScintillaEdit::foldExpanded(sptr_t line) const { - return send(SCI_GETFOLDEXPANDED, line, 0); -} - -void ScintillaEdit::toggleFold(sptr_t line) { - send(SCI_TOGGLEFOLD, line, 0); -} - -void ScintillaEdit::toggleFoldShowText(sptr_t line, const char * text) { - send(SCI_TOGGLEFOLDSHOWTEXT, line, (sptr_t)text); -} - -void ScintillaEdit::foldDisplayTextSetStyle(sptr_t style) { - send(SCI_FOLDDISPLAYTEXTSETSTYLE, style, 0); -} - -void ScintillaEdit::foldLine(sptr_t line, sptr_t action) { - send(SCI_FOLDLINE, line, action); -} - -void ScintillaEdit::foldChildren(sptr_t line, sptr_t action) { - send(SCI_FOLDCHILDREN, line, action); -} - -void ScintillaEdit::expandChildren(sptr_t line, sptr_t level) { - send(SCI_EXPANDCHILDREN, line, level); -} - -void ScintillaEdit::foldAll(sptr_t action) { - send(SCI_FOLDALL, action, 0); -} - -void ScintillaEdit::ensureVisible(sptr_t line) { - send(SCI_ENSUREVISIBLE, line, 0); -} - -void ScintillaEdit::setAutomaticFold(sptr_t automaticFold) { - send(SCI_SETAUTOMATICFOLD, automaticFold, 0); -} - -sptr_t ScintillaEdit::automaticFold() const { - return send(SCI_GETAUTOMATICFOLD, 0, 0); -} - -void ScintillaEdit::setFoldFlags(sptr_t flags) { - send(SCI_SETFOLDFLAGS, flags, 0); -} - -void ScintillaEdit::ensureVisibleEnforcePolicy(sptr_t line) { - send(SCI_ENSUREVISIBLEENFORCEPOLICY, line, 0); -} - -void ScintillaEdit::setTabIndents(bool tabIndents) { - send(SCI_SETTABINDENTS, tabIndents, 0); -} - -bool ScintillaEdit::tabIndents() const { - return send(SCI_GETTABINDENTS, 0, 0); -} - -void ScintillaEdit::setBackSpaceUnIndents(bool bsUnIndents) { - send(SCI_SETBACKSPACEUNINDENTS, bsUnIndents, 0); -} - -bool ScintillaEdit::backSpaceUnIndents() const { - return send(SCI_GETBACKSPACEUNINDENTS, 0, 0); -} - -void ScintillaEdit::setMouseDwellTime(sptr_t periodMilliseconds) { - send(SCI_SETMOUSEDWELLTIME, periodMilliseconds, 0); -} - -sptr_t ScintillaEdit::mouseDwellTime() const { - return send(SCI_GETMOUSEDWELLTIME, 0, 0); -} - -sptr_t ScintillaEdit::wordStartPosition(sptr_t pos, bool onlyWordCharacters) { - return send(SCI_WORDSTARTPOSITION, pos, onlyWordCharacters); -} - -sptr_t ScintillaEdit::wordEndPosition(sptr_t pos, bool onlyWordCharacters) { - return send(SCI_WORDENDPOSITION, pos, onlyWordCharacters); -} - -bool ScintillaEdit::isRangeWord(sptr_t start, sptr_t end) { - return send(SCI_ISRANGEWORD, start, end); -} - -void ScintillaEdit::setIdleStyling(sptr_t idleStyling) { - send(SCI_SETIDLESTYLING, idleStyling, 0); -} - -sptr_t ScintillaEdit::idleStyling() const { - return send(SCI_GETIDLESTYLING, 0, 0); -} - -void ScintillaEdit::setWrapMode(sptr_t wrapMode) { - send(SCI_SETWRAPMODE, wrapMode, 0); -} - -sptr_t ScintillaEdit::wrapMode() const { - return send(SCI_GETWRAPMODE, 0, 0); -} - -void ScintillaEdit::setWrapVisualFlags(sptr_t wrapVisualFlags) { - send(SCI_SETWRAPVISUALFLAGS, wrapVisualFlags, 0); -} - -sptr_t ScintillaEdit::wrapVisualFlags() const { - return send(SCI_GETWRAPVISUALFLAGS, 0, 0); -} - -void ScintillaEdit::setWrapVisualFlagsLocation(sptr_t wrapVisualFlagsLocation) { - send(SCI_SETWRAPVISUALFLAGSLOCATION, wrapVisualFlagsLocation, 0); -} - -sptr_t ScintillaEdit::wrapVisualFlagsLocation() const { - return send(SCI_GETWRAPVISUALFLAGSLOCATION, 0, 0); -} - -void ScintillaEdit::setWrapStartIndent(sptr_t indent) { - send(SCI_SETWRAPSTARTINDENT, indent, 0); -} - -sptr_t ScintillaEdit::wrapStartIndent() const { - return send(SCI_GETWRAPSTARTINDENT, 0, 0); -} - -void ScintillaEdit::setWrapIndentMode(sptr_t wrapIndentMode) { - send(SCI_SETWRAPINDENTMODE, wrapIndentMode, 0); -} - -sptr_t ScintillaEdit::wrapIndentMode() const { - return send(SCI_GETWRAPINDENTMODE, 0, 0); -} - -void ScintillaEdit::setLayoutCache(sptr_t cacheMode) { - send(SCI_SETLAYOUTCACHE, cacheMode, 0); -} - -sptr_t ScintillaEdit::layoutCache() const { - return send(SCI_GETLAYOUTCACHE, 0, 0); -} - -void ScintillaEdit::setScrollWidth(sptr_t pixelWidth) { - send(SCI_SETSCROLLWIDTH, pixelWidth, 0); -} - -sptr_t ScintillaEdit::scrollWidth() const { - return send(SCI_GETSCROLLWIDTH, 0, 0); -} - -void ScintillaEdit::setScrollWidthTracking(bool tracking) { - send(SCI_SETSCROLLWIDTHTRACKING, tracking, 0); -} - -bool ScintillaEdit::scrollWidthTracking() const { - return send(SCI_GETSCROLLWIDTHTRACKING, 0, 0); -} - -sptr_t ScintillaEdit::textWidth(sptr_t style, const char * text) { - return send(SCI_TEXTWIDTH, style, (sptr_t)text); -} - -void ScintillaEdit::setEndAtLastLine(bool endAtLastLine) { - send(SCI_SETENDATLASTLINE, endAtLastLine, 0); -} - -bool ScintillaEdit::endAtLastLine() const { - return send(SCI_GETENDATLASTLINE, 0, 0); -} - -sptr_t ScintillaEdit::textHeight(sptr_t line) { - return send(SCI_TEXTHEIGHT, line, 0); -} - -void ScintillaEdit::setVScrollBar(bool visible) { - send(SCI_SETVSCROLLBAR, visible, 0); -} - -bool ScintillaEdit::vScrollBar() const { - return send(SCI_GETVSCROLLBAR, 0, 0); -} - -void ScintillaEdit::appendText(sptr_t length, const char * text) { - send(SCI_APPENDTEXT, length, (sptr_t)text); -} - -bool ScintillaEdit::twoPhaseDraw() const { - return send(SCI_GETTWOPHASEDRAW, 0, 0); -} - -void ScintillaEdit::setTwoPhaseDraw(bool twoPhase) { - send(SCI_SETTWOPHASEDRAW, twoPhase, 0); -} - -sptr_t ScintillaEdit::phasesDraw() const { - return send(SCI_GETPHASESDRAW, 0, 0); -} - -void ScintillaEdit::setPhasesDraw(sptr_t phases) { - send(SCI_SETPHASESDRAW, phases, 0); -} - -void ScintillaEdit::setFontQuality(sptr_t fontQuality) { - send(SCI_SETFONTQUALITY, fontQuality, 0); -} - -sptr_t ScintillaEdit::fontQuality() const { - return send(SCI_GETFONTQUALITY, 0, 0); -} - -void ScintillaEdit::setFirstVisibleLine(sptr_t displayLine) { - send(SCI_SETFIRSTVISIBLELINE, displayLine, 0); -} - -void ScintillaEdit::setMultiPaste(sptr_t multiPaste) { - send(SCI_SETMULTIPASTE, multiPaste, 0); -} - -sptr_t ScintillaEdit::multiPaste() const { - return send(SCI_GETMULTIPASTE, 0, 0); -} - -QByteArray ScintillaEdit::tag(sptr_t tagNumber) const { - return TextReturner(SCI_GETTAG, tagNumber); -} - -void ScintillaEdit::linesJoin() { - send(SCI_LINESJOIN, 0, 0); -} - -void ScintillaEdit::linesSplit(sptr_t pixelWidth) { - send(SCI_LINESSPLIT, pixelWidth, 0); -} - -void ScintillaEdit::setFoldMarginColour(bool useSetting, sptr_t back) { - send(SCI_SETFOLDMARGINCOLOUR, useSetting, back); -} - -void ScintillaEdit::setFoldMarginHiColour(bool useSetting, sptr_t fore) { - send(SCI_SETFOLDMARGINHICOLOUR, useSetting, fore); -} - -void ScintillaEdit::lineDown() { - send(SCI_LINEDOWN, 0, 0); -} - -void ScintillaEdit::lineDownExtend() { - send(SCI_LINEDOWNEXTEND, 0, 0); -} - -void ScintillaEdit::lineUp() { - send(SCI_LINEUP, 0, 0); -} - -void ScintillaEdit::lineUpExtend() { - send(SCI_LINEUPEXTEND, 0, 0); -} - -void ScintillaEdit::charLeft() { - send(SCI_CHARLEFT, 0, 0); -} - -void ScintillaEdit::charLeftExtend() { - send(SCI_CHARLEFTEXTEND, 0, 0); -} - -void ScintillaEdit::charRight() { - send(SCI_CHARRIGHT, 0, 0); -} - -void ScintillaEdit::charRightExtend() { - send(SCI_CHARRIGHTEXTEND, 0, 0); -} - -void ScintillaEdit::wordLeft() { - send(SCI_WORDLEFT, 0, 0); -} - -void ScintillaEdit::wordLeftExtend() { - send(SCI_WORDLEFTEXTEND, 0, 0); -} - -void ScintillaEdit::wordRight() { - send(SCI_WORDRIGHT, 0, 0); -} - -void ScintillaEdit::wordRightExtend() { - send(SCI_WORDRIGHTEXTEND, 0, 0); -} - -void ScintillaEdit::home() { - send(SCI_HOME, 0, 0); -} - -void ScintillaEdit::homeExtend() { - send(SCI_HOMEEXTEND, 0, 0); -} - -void ScintillaEdit::lineEnd() { - send(SCI_LINEEND, 0, 0); -} - -void ScintillaEdit::lineEndExtend() { - send(SCI_LINEENDEXTEND, 0, 0); -} - -void ScintillaEdit::documentStart() { - send(SCI_DOCUMENTSTART, 0, 0); -} - -void ScintillaEdit::documentStartExtend() { - send(SCI_DOCUMENTSTARTEXTEND, 0, 0); -} - -void ScintillaEdit::documentEnd() { - send(SCI_DOCUMENTEND, 0, 0); -} - -void ScintillaEdit::documentEndExtend() { - send(SCI_DOCUMENTENDEXTEND, 0, 0); -} - -void ScintillaEdit::pageUp() { - send(SCI_PAGEUP, 0, 0); -} - -void ScintillaEdit::pageUpExtend() { - send(SCI_PAGEUPEXTEND, 0, 0); -} - -void ScintillaEdit::pageDown() { - send(SCI_PAGEDOWN, 0, 0); -} - -void ScintillaEdit::pageDownExtend() { - send(SCI_PAGEDOWNEXTEND, 0, 0); -} - -void ScintillaEdit::editToggleOvertype() { - send(SCI_EDITTOGGLEOVERTYPE, 0, 0); -} - -void ScintillaEdit::cancel() { - send(SCI_CANCEL, 0, 0); -} - -void ScintillaEdit::deleteBack() { - send(SCI_DELETEBACK, 0, 0); -} - -void ScintillaEdit::tab() { - send(SCI_TAB, 0, 0); -} - -void ScintillaEdit::backTab() { - send(SCI_BACKTAB, 0, 0); -} - -void ScintillaEdit::newLine() { - send(SCI_NEWLINE, 0, 0); -} - -void ScintillaEdit::formFeed() { - send(SCI_FORMFEED, 0, 0); -} - -void ScintillaEdit::vCHome() { - send(SCI_VCHOME, 0, 0); -} - -void ScintillaEdit::vCHomeExtend() { - send(SCI_VCHOMEEXTEND, 0, 0); -} - -void ScintillaEdit::zoomIn() { - send(SCI_ZOOMIN, 0, 0); -} - -void ScintillaEdit::zoomOut() { - send(SCI_ZOOMOUT, 0, 0); -} - -void ScintillaEdit::delWordLeft() { - send(SCI_DELWORDLEFT, 0, 0); -} - -void ScintillaEdit::delWordRight() { - send(SCI_DELWORDRIGHT, 0, 0); -} - -void ScintillaEdit::delWordRightEnd() { - send(SCI_DELWORDRIGHTEND, 0, 0); -} - -void ScintillaEdit::lineCut() { - send(SCI_LINECUT, 0, 0); -} - -void ScintillaEdit::lineDelete() { - send(SCI_LINEDELETE, 0, 0); -} - -void ScintillaEdit::lineTranspose() { - send(SCI_LINETRANSPOSE, 0, 0); -} - -void ScintillaEdit::lineDuplicate() { - send(SCI_LINEDUPLICATE, 0, 0); -} - -void ScintillaEdit::lowerCase() { - send(SCI_LOWERCASE, 0, 0); -} - -void ScintillaEdit::upperCase() { - send(SCI_UPPERCASE, 0, 0); -} - -void ScintillaEdit::lineScrollDown() { - send(SCI_LINESCROLLDOWN, 0, 0); -} - -void ScintillaEdit::lineScrollUp() { - send(SCI_LINESCROLLUP, 0, 0); -} - -void ScintillaEdit::deleteBackNotLine() { - send(SCI_DELETEBACKNOTLINE, 0, 0); -} - -void ScintillaEdit::homeDisplay() { - send(SCI_HOMEDISPLAY, 0, 0); -} - -void ScintillaEdit::homeDisplayExtend() { - send(SCI_HOMEDISPLAYEXTEND, 0, 0); -} - -void ScintillaEdit::lineEndDisplay() { - send(SCI_LINEENDDISPLAY, 0, 0); -} - -void ScintillaEdit::lineEndDisplayExtend() { - send(SCI_LINEENDDISPLAYEXTEND, 0, 0); -} - -void ScintillaEdit::homeWrap() { - send(SCI_HOMEWRAP, 0, 0); -} - -void ScintillaEdit::homeWrapExtend() { - send(SCI_HOMEWRAPEXTEND, 0, 0); -} - -void ScintillaEdit::lineEndWrap() { - send(SCI_LINEENDWRAP, 0, 0); -} - -void ScintillaEdit::lineEndWrapExtend() { - send(SCI_LINEENDWRAPEXTEND, 0, 0); -} - -void ScintillaEdit::vCHomeWrap() { - send(SCI_VCHOMEWRAP, 0, 0); -} - -void ScintillaEdit::vCHomeWrapExtend() { - send(SCI_VCHOMEWRAPEXTEND, 0, 0); -} - -void ScintillaEdit::lineCopy() { - send(SCI_LINECOPY, 0, 0); -} - -void ScintillaEdit::moveCaretInsideView() { - send(SCI_MOVECARETINSIDEVIEW, 0, 0); -} - -sptr_t ScintillaEdit::lineLength(sptr_t line) { - return send(SCI_LINELENGTH, line, 0); -} - -void ScintillaEdit::braceHighlight(sptr_t posA, sptr_t posB) { - send(SCI_BRACEHIGHLIGHT, posA, posB); -} - -void ScintillaEdit::braceHighlightIndicator(bool useSetting, sptr_t indicator) { - send(SCI_BRACEHIGHLIGHTINDICATOR, useSetting, indicator); -} - -void ScintillaEdit::braceBadLight(sptr_t pos) { - send(SCI_BRACEBADLIGHT, pos, 0); -} - -void ScintillaEdit::braceBadLightIndicator(bool useSetting, sptr_t indicator) { - send(SCI_BRACEBADLIGHTINDICATOR, useSetting, indicator); -} - -sptr_t ScintillaEdit::braceMatch(sptr_t pos, sptr_t maxReStyle) { - return send(SCI_BRACEMATCH, pos, maxReStyle); -} - -bool ScintillaEdit::viewEOL() const { - return send(SCI_GETVIEWEOL, 0, 0); -} - -void ScintillaEdit::setViewEOL(bool visible) { - send(SCI_SETVIEWEOL, visible, 0); -} - -sptr_t ScintillaEdit::docPointer() const { - return send(SCI_GETDOCPOINTER, 0, 0); -} - -void ScintillaEdit::setDocPointer(sptr_t doc) { - send(SCI_SETDOCPOINTER, 0, doc); -} - -void ScintillaEdit::setModEventMask(sptr_t eventMask) { - send(SCI_SETMODEVENTMASK, eventMask, 0); -} - -sptr_t ScintillaEdit::edgeColumn() const { - return send(SCI_GETEDGECOLUMN, 0, 0); -} - -void ScintillaEdit::setEdgeColumn(sptr_t column) { - send(SCI_SETEDGECOLUMN, column, 0); -} - -sptr_t ScintillaEdit::edgeMode() const { - return send(SCI_GETEDGEMODE, 0, 0); -} - -void ScintillaEdit::setEdgeMode(sptr_t edgeMode) { - send(SCI_SETEDGEMODE, edgeMode, 0); -} - -sptr_t ScintillaEdit::edgeColour() const { - return send(SCI_GETEDGECOLOUR, 0, 0); -} - -void ScintillaEdit::setEdgeColour(sptr_t edgeColour) { - send(SCI_SETEDGECOLOUR, edgeColour, 0); -} - -void ScintillaEdit::multiEdgeAddLine(sptr_t column, sptr_t edgeColour) { - send(SCI_MULTIEDGEADDLINE, column, edgeColour); -} - -void ScintillaEdit::multiEdgeClearAll() { - send(SCI_MULTIEDGECLEARALL, 0, 0); -} - -void ScintillaEdit::searchAnchor() { - send(SCI_SEARCHANCHOR, 0, 0); -} - -sptr_t ScintillaEdit::searchNext(sptr_t searchFlags, const char * text) { - return send(SCI_SEARCHNEXT, searchFlags, (sptr_t)text); -} - -sptr_t ScintillaEdit::searchPrev(sptr_t searchFlags, const char * text) { - return send(SCI_SEARCHPREV, searchFlags, (sptr_t)text); -} - -sptr_t ScintillaEdit::linesOnScreen() const { - return send(SCI_LINESONSCREEN, 0, 0); -} - -void ScintillaEdit::usePopUp(sptr_t popUpMode) { - send(SCI_USEPOPUP, popUpMode, 0); -} - -bool ScintillaEdit::selectionIsRectangle() const { - return send(SCI_SELECTIONISRECTANGLE, 0, 0); -} - -void ScintillaEdit::setZoom(sptr_t zoomInPoints) { - send(SCI_SETZOOM, zoomInPoints, 0); -} - -sptr_t ScintillaEdit::zoom() const { - return send(SCI_GETZOOM, 0, 0); -} - -sptr_t ScintillaEdit::createDocument() { - return send(SCI_CREATEDOCUMENT, 0, 0); -} - -void ScintillaEdit::addRefDocument(sptr_t doc) { - send(SCI_ADDREFDOCUMENT, 0, doc); -} - -void ScintillaEdit::releaseDocument(sptr_t doc) { - send(SCI_RELEASEDOCUMENT, 0, doc); -} - -sptr_t ScintillaEdit::modEventMask() const { - return send(SCI_GETMODEVENTMASK, 0, 0); -} - -void ScintillaEdit::setFocus(bool focus) { - send(SCI_SETFOCUS, focus, 0); -} - -bool ScintillaEdit::focus() const { - return send(SCI_GETFOCUS, 0, 0); -} - -void ScintillaEdit::setStatus(sptr_t status) { - send(SCI_SETSTATUS, status, 0); -} - -sptr_t ScintillaEdit::status() const { - return send(SCI_GETSTATUS, 0, 0); -} - -void ScintillaEdit::setMouseDownCaptures(bool captures) { - send(SCI_SETMOUSEDOWNCAPTURES, captures, 0); -} - -bool ScintillaEdit::mouseDownCaptures() const { - return send(SCI_GETMOUSEDOWNCAPTURES, 0, 0); -} - -void ScintillaEdit::setMouseWheelCaptures(bool captures) { - send(SCI_SETMOUSEWHEELCAPTURES, captures, 0); -} - -bool ScintillaEdit::mouseWheelCaptures() const { - return send(SCI_GETMOUSEWHEELCAPTURES, 0, 0); -} - -void ScintillaEdit::setCursor(sptr_t cursorType) { - send(SCI_SETCURSOR, cursorType, 0); -} - -sptr_t ScintillaEdit::cursor() const { - return send(SCI_GETCURSOR, 0, 0); -} - -void ScintillaEdit::setControlCharSymbol(sptr_t symbol) { - send(SCI_SETCONTROLCHARSYMBOL, symbol, 0); -} - -sptr_t ScintillaEdit::controlCharSymbol() const { - return send(SCI_GETCONTROLCHARSYMBOL, 0, 0); -} - -void ScintillaEdit::wordPartLeft() { - send(SCI_WORDPARTLEFT, 0, 0); -} - -void ScintillaEdit::wordPartLeftExtend() { - send(SCI_WORDPARTLEFTEXTEND, 0, 0); -} - -void ScintillaEdit::wordPartRight() { - send(SCI_WORDPARTRIGHT, 0, 0); -} - -void ScintillaEdit::wordPartRightExtend() { - send(SCI_WORDPARTRIGHTEXTEND, 0, 0); -} - -void ScintillaEdit::setVisiblePolicy(sptr_t visiblePolicy, sptr_t visibleSlop) { - send(SCI_SETVISIBLEPOLICY, visiblePolicy, visibleSlop); -} - -void ScintillaEdit::delLineLeft() { - send(SCI_DELLINELEFT, 0, 0); -} - -void ScintillaEdit::delLineRight() { - send(SCI_DELLINERIGHT, 0, 0); -} - -void ScintillaEdit::setXOffset(sptr_t xOffset) { - send(SCI_SETXOFFSET, xOffset, 0); -} - -sptr_t ScintillaEdit::xOffset() const { - return send(SCI_GETXOFFSET, 0, 0); -} - -void ScintillaEdit::chooseCaretX() { - send(SCI_CHOOSECARETX, 0, 0); -} - -void ScintillaEdit::grabFocus() { - send(SCI_GRABFOCUS, 0, 0); -} - -void ScintillaEdit::setXCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop) { - send(SCI_SETXCARETPOLICY, caretPolicy, caretSlop); -} - -void ScintillaEdit::setYCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop) { - send(SCI_SETYCARETPOLICY, caretPolicy, caretSlop); -} - -void ScintillaEdit::setPrintWrapMode(sptr_t wrapMode) { - send(SCI_SETPRINTWRAPMODE, wrapMode, 0); -} - -sptr_t ScintillaEdit::printWrapMode() const { - return send(SCI_GETPRINTWRAPMODE, 0, 0); -} - -void ScintillaEdit::setHotspotActiveFore(bool useSetting, sptr_t fore) { - send(SCI_SETHOTSPOTACTIVEFORE, useSetting, fore); -} - -sptr_t ScintillaEdit::hotspotActiveFore() const { - return send(SCI_GETHOTSPOTACTIVEFORE, 0, 0); -} - -void ScintillaEdit::setHotspotActiveBack(bool useSetting, sptr_t back) { - send(SCI_SETHOTSPOTACTIVEBACK, useSetting, back); -} - -sptr_t ScintillaEdit::hotspotActiveBack() const { - return send(SCI_GETHOTSPOTACTIVEBACK, 0, 0); -} - -void ScintillaEdit::setHotspotActiveUnderline(bool underline) { - send(SCI_SETHOTSPOTACTIVEUNDERLINE, underline, 0); -} - -bool ScintillaEdit::hotspotActiveUnderline() const { - return send(SCI_GETHOTSPOTACTIVEUNDERLINE, 0, 0); -} - -void ScintillaEdit::setHotspotSingleLine(bool singleLine) { - send(SCI_SETHOTSPOTSINGLELINE, singleLine, 0); -} - -bool ScintillaEdit::hotspotSingleLine() const { - return send(SCI_GETHOTSPOTSINGLELINE, 0, 0); -} - -void ScintillaEdit::paraDown() { - send(SCI_PARADOWN, 0, 0); -} - -void ScintillaEdit::paraDownExtend() { - send(SCI_PARADOWNEXTEND, 0, 0); -} - -void ScintillaEdit::paraUp() { - send(SCI_PARAUP, 0, 0); -} - -void ScintillaEdit::paraUpExtend() { - send(SCI_PARAUPEXTEND, 0, 0); -} - -sptr_t ScintillaEdit::positionBefore(sptr_t pos) { - return send(SCI_POSITIONBEFORE, pos, 0); -} - -sptr_t ScintillaEdit::positionAfter(sptr_t pos) { - return send(SCI_POSITIONAFTER, pos, 0); -} - -sptr_t ScintillaEdit::positionRelative(sptr_t pos, sptr_t relative) { - return send(SCI_POSITIONRELATIVE, pos, relative); -} - -void ScintillaEdit::copyRange(sptr_t start, sptr_t end) { - send(SCI_COPYRANGE, start, end); -} - -void ScintillaEdit::copyText(sptr_t length, const char * text) { - send(SCI_COPYTEXT, length, (sptr_t)text); -} - -void ScintillaEdit::setSelectionMode(sptr_t selectionMode) { - send(SCI_SETSELECTIONMODE, selectionMode, 0); -} - -sptr_t ScintillaEdit::selectionMode() const { - return send(SCI_GETSELECTIONMODE, 0, 0); -} - -sptr_t ScintillaEdit::getLineSelStartPosition(sptr_t line) { - return send(SCI_GETLINESELSTARTPOSITION, line, 0); -} - -sptr_t ScintillaEdit::getLineSelEndPosition(sptr_t line) { - return send(SCI_GETLINESELENDPOSITION, line, 0); -} - -void ScintillaEdit::lineDownRectExtend() { - send(SCI_LINEDOWNRECTEXTEND, 0, 0); -} - -void ScintillaEdit::lineUpRectExtend() { - send(SCI_LINEUPRECTEXTEND, 0, 0); -} - -void ScintillaEdit::charLeftRectExtend() { - send(SCI_CHARLEFTRECTEXTEND, 0, 0); -} - -void ScintillaEdit::charRightRectExtend() { - send(SCI_CHARRIGHTRECTEXTEND, 0, 0); -} - -void ScintillaEdit::homeRectExtend() { - send(SCI_HOMERECTEXTEND, 0, 0); -} - -void ScintillaEdit::vCHomeRectExtend() { - send(SCI_VCHOMERECTEXTEND, 0, 0); -} - -void ScintillaEdit::lineEndRectExtend() { - send(SCI_LINEENDRECTEXTEND, 0, 0); -} - -void ScintillaEdit::pageUpRectExtend() { - send(SCI_PAGEUPRECTEXTEND, 0, 0); -} - -void ScintillaEdit::pageDownRectExtend() { - send(SCI_PAGEDOWNRECTEXTEND, 0, 0); -} - -void ScintillaEdit::stutteredPageUp() { - send(SCI_STUTTEREDPAGEUP, 0, 0); -} - -void ScintillaEdit::stutteredPageUpExtend() { - send(SCI_STUTTEREDPAGEUPEXTEND, 0, 0); -} - -void ScintillaEdit::stutteredPageDown() { - send(SCI_STUTTEREDPAGEDOWN, 0, 0); -} - -void ScintillaEdit::stutteredPageDownExtend() { - send(SCI_STUTTEREDPAGEDOWNEXTEND, 0, 0); -} - -void ScintillaEdit::wordLeftEnd() { - send(SCI_WORDLEFTEND, 0, 0); -} - -void ScintillaEdit::wordLeftEndExtend() { - send(SCI_WORDLEFTENDEXTEND, 0, 0); -} - -void ScintillaEdit::wordRightEnd() { - send(SCI_WORDRIGHTEND, 0, 0); -} - -void ScintillaEdit::wordRightEndExtend() { - send(SCI_WORDRIGHTENDEXTEND, 0, 0); -} - -void ScintillaEdit::setWhitespaceChars(const char * characters) { - send(SCI_SETWHITESPACECHARS, 0, (sptr_t)characters); -} - -QByteArray ScintillaEdit::whitespaceChars() const { - return TextReturner(SCI_GETWHITESPACECHARS, 0); -} - -void ScintillaEdit::setPunctuationChars(const char * characters) { - send(SCI_SETPUNCTUATIONCHARS, 0, (sptr_t)characters); -} - -QByteArray ScintillaEdit::punctuationChars() const { - return TextReturner(SCI_GETPUNCTUATIONCHARS, 0); -} - -void ScintillaEdit::setCharsDefault() { - send(SCI_SETCHARSDEFAULT, 0, 0); -} - -sptr_t ScintillaEdit::autoCCurrent() const { - return send(SCI_AUTOCGETCURRENT, 0, 0); -} - -QByteArray ScintillaEdit::autoCCurrentText() const { - return TextReturner(SCI_AUTOCGETCURRENTTEXT, 0); -} - -void ScintillaEdit::autoCSetCaseInsensitiveBehaviour(sptr_t behaviour) { - send(SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR, behaviour, 0); -} - -sptr_t ScintillaEdit::autoCCaseInsensitiveBehaviour() const { - return send(SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR, 0, 0); -} - -void ScintillaEdit::autoCSetMulti(sptr_t multi) { - send(SCI_AUTOCSETMULTI, multi, 0); -} - -sptr_t ScintillaEdit::autoCMulti() const { - return send(SCI_AUTOCGETMULTI, 0, 0); -} - -void ScintillaEdit::autoCSetOrder(sptr_t order) { - send(SCI_AUTOCSETORDER, order, 0); -} - -sptr_t ScintillaEdit::autoCOrder() const { - return send(SCI_AUTOCGETORDER, 0, 0); -} - -void ScintillaEdit::allocate(sptr_t bytes) { - send(SCI_ALLOCATE, bytes, 0); -} - -QByteArray ScintillaEdit::targetAsUTF8() { - return TextReturner(SCI_TARGETASUTF8, 0); -} - -void ScintillaEdit::setLengthForEncode(sptr_t bytes) { - send(SCI_SETLENGTHFORENCODE, bytes, 0); -} - -QByteArray ScintillaEdit::encodedFromUTF8(const char * utf8) { - return TextReturner(SCI_ENCODEDFROMUTF8, (sptr_t)utf8); -} - -sptr_t ScintillaEdit::findColumn(sptr_t line, sptr_t column) { - return send(SCI_FINDCOLUMN, line, column); -} - -sptr_t ScintillaEdit::caretSticky() const { - return send(SCI_GETCARETSTICKY, 0, 0); -} - -void ScintillaEdit::setCaretSticky(sptr_t useCaretStickyBehaviour) { - send(SCI_SETCARETSTICKY, useCaretStickyBehaviour, 0); -} - -void ScintillaEdit::toggleCaretSticky() { - send(SCI_TOGGLECARETSTICKY, 0, 0); -} - -void ScintillaEdit::setPasteConvertEndings(bool convert) { - send(SCI_SETPASTECONVERTENDINGS, convert, 0); -} - -bool ScintillaEdit::pasteConvertEndings() const { - return send(SCI_GETPASTECONVERTENDINGS, 0, 0); -} - -void ScintillaEdit::selectionDuplicate() { - send(SCI_SELECTIONDUPLICATE, 0, 0); -} - -void ScintillaEdit::setCaretLineBackAlpha(sptr_t alpha) { - send(SCI_SETCARETLINEBACKALPHA, alpha, 0); -} - -sptr_t ScintillaEdit::caretLineBackAlpha() const { - return send(SCI_GETCARETLINEBACKALPHA, 0, 0); -} - -void ScintillaEdit::setCaretStyle(sptr_t caretStyle) { - send(SCI_SETCARETSTYLE, caretStyle, 0); -} - -sptr_t ScintillaEdit::caretStyle() const { - return send(SCI_GETCARETSTYLE, 0, 0); -} - -void ScintillaEdit::setIndicatorCurrent(sptr_t indicator) { - send(SCI_SETINDICATORCURRENT, indicator, 0); -} - -sptr_t ScintillaEdit::indicatorCurrent() const { - return send(SCI_GETINDICATORCURRENT, 0, 0); -} - -void ScintillaEdit::setIndicatorValue(sptr_t value) { - send(SCI_SETINDICATORVALUE, value, 0); -} - -sptr_t ScintillaEdit::indicatorValue() const { - return send(SCI_GETINDICATORVALUE, 0, 0); -} - -void ScintillaEdit::indicatorFillRange(sptr_t start, sptr_t lengthFill) { - send(SCI_INDICATORFILLRANGE, start, lengthFill); -} - -void ScintillaEdit::indicatorClearRange(sptr_t start, sptr_t lengthClear) { - send(SCI_INDICATORCLEARRANGE, start, lengthClear); -} - -sptr_t ScintillaEdit::indicatorAllOnFor(sptr_t pos) { - return send(SCI_INDICATORALLONFOR, pos, 0); -} - -sptr_t ScintillaEdit::indicatorValueAt(sptr_t indicator, sptr_t pos) { - return send(SCI_INDICATORVALUEAT, indicator, pos); -} - -sptr_t ScintillaEdit::indicatorStart(sptr_t indicator, sptr_t pos) { - return send(SCI_INDICATORSTART, indicator, pos); -} - -sptr_t ScintillaEdit::indicatorEnd(sptr_t indicator, sptr_t pos) { - return send(SCI_INDICATOREND, indicator, pos); -} - -void ScintillaEdit::setPositionCache(sptr_t size) { - send(SCI_SETPOSITIONCACHE, size, 0); -} - -sptr_t ScintillaEdit::positionCache() const { - return send(SCI_GETPOSITIONCACHE, 0, 0); -} - -void ScintillaEdit::copyAllowLine() { - send(SCI_COPYALLOWLINE, 0, 0); -} - -sptr_t ScintillaEdit::characterPointer() const { - return send(SCI_GETCHARACTERPOINTER, 0, 0); -} - -sptr_t ScintillaEdit::rangePointer(sptr_t start, sptr_t lengthRange) const { - return send(SCI_GETRANGEPOINTER, start, lengthRange); -} - -sptr_t ScintillaEdit::gapPosition() const { - return send(SCI_GETGAPPOSITION, 0, 0); -} - -void ScintillaEdit::indicSetAlpha(sptr_t indicator, sptr_t alpha) { - send(SCI_INDICSETALPHA, indicator, alpha); -} - -sptr_t ScintillaEdit::indicAlpha(sptr_t indicator) const { - return send(SCI_INDICGETALPHA, indicator, 0); -} - -void ScintillaEdit::indicSetOutlineAlpha(sptr_t indicator, sptr_t alpha) { - send(SCI_INDICSETOUTLINEALPHA, indicator, alpha); -} - -sptr_t ScintillaEdit::indicOutlineAlpha(sptr_t indicator) const { - return send(SCI_INDICGETOUTLINEALPHA, indicator, 0); -} - -void ScintillaEdit::setExtraAscent(sptr_t extraAscent) { - send(SCI_SETEXTRAASCENT, extraAscent, 0); -} - -sptr_t ScintillaEdit::extraAscent() const { - return send(SCI_GETEXTRAASCENT, 0, 0); -} - -void ScintillaEdit::setExtraDescent(sptr_t extraDescent) { - send(SCI_SETEXTRADESCENT, extraDescent, 0); -} - -sptr_t ScintillaEdit::extraDescent() const { - return send(SCI_GETEXTRADESCENT, 0, 0); -} - -sptr_t ScintillaEdit::markerSymbolDefined(sptr_t markerNumber) { - return send(SCI_MARKERSYMBOLDEFINED, markerNumber, 0); -} - -void ScintillaEdit::marginSetText(sptr_t line, const char * text) { - send(SCI_MARGINSETTEXT, line, (sptr_t)text); -} - -QByteArray ScintillaEdit::marginText(sptr_t line) const { - return TextReturner(SCI_MARGINGETTEXT, line); -} - -void ScintillaEdit::marginSetStyle(sptr_t line, sptr_t style) { - send(SCI_MARGINSETSTYLE, line, style); -} - -sptr_t ScintillaEdit::marginStyle(sptr_t line) const { - return send(SCI_MARGINGETSTYLE, line, 0); -} - -void ScintillaEdit::marginSetStyles(sptr_t line, const char * styles) { - send(SCI_MARGINSETSTYLES, line, (sptr_t)styles); -} - -QByteArray ScintillaEdit::marginStyles(sptr_t line) const { - return TextReturner(SCI_MARGINGETSTYLES, line); -} - -void ScintillaEdit::marginTextClearAll() { - send(SCI_MARGINTEXTCLEARALL, 0, 0); -} - -void ScintillaEdit::marginSetStyleOffset(sptr_t style) { - send(SCI_MARGINSETSTYLEOFFSET, style, 0); -} - -sptr_t ScintillaEdit::marginStyleOffset() const { - return send(SCI_MARGINGETSTYLEOFFSET, 0, 0); -} - -void ScintillaEdit::setMarginOptions(sptr_t marginOptions) { - send(SCI_SETMARGINOPTIONS, marginOptions, 0); -} - -sptr_t ScintillaEdit::marginOptions() const { - return send(SCI_GETMARGINOPTIONS, 0, 0); -} - -void ScintillaEdit::annotationSetText(sptr_t line, const char * text) { - send(SCI_ANNOTATIONSETTEXT, line, (sptr_t)text); -} - -QByteArray ScintillaEdit::annotationText(sptr_t line) const { - return TextReturner(SCI_ANNOTATIONGETTEXT, line); -} - -void ScintillaEdit::annotationSetStyle(sptr_t line, sptr_t style) { - send(SCI_ANNOTATIONSETSTYLE, line, style); -} - -sptr_t ScintillaEdit::annotationStyle(sptr_t line) const { - return send(SCI_ANNOTATIONGETSTYLE, line, 0); -} - -void ScintillaEdit::annotationSetStyles(sptr_t line, const char * styles) { - send(SCI_ANNOTATIONSETSTYLES, line, (sptr_t)styles); -} - -QByteArray ScintillaEdit::annotationStyles(sptr_t line) const { - return TextReturner(SCI_ANNOTATIONGETSTYLES, line); -} - -sptr_t ScintillaEdit::annotationLines(sptr_t line) const { - return send(SCI_ANNOTATIONGETLINES, line, 0); -} - -void ScintillaEdit::annotationClearAll() { - send(SCI_ANNOTATIONCLEARALL, 0, 0); -} - -void ScintillaEdit::annotationSetVisible(sptr_t visible) { - send(SCI_ANNOTATIONSETVISIBLE, visible, 0); -} - -sptr_t ScintillaEdit::annotationVisible() const { - return send(SCI_ANNOTATIONGETVISIBLE, 0, 0); -} - -void ScintillaEdit::annotationSetStyleOffset(sptr_t style) { - send(SCI_ANNOTATIONSETSTYLEOFFSET, style, 0); -} - -sptr_t ScintillaEdit::annotationStyleOffset() const { - return send(SCI_ANNOTATIONGETSTYLEOFFSET, 0, 0); -} - -void ScintillaEdit::releaseAllExtendedStyles() { - send(SCI_RELEASEALLEXTENDEDSTYLES, 0, 0); -} - -sptr_t ScintillaEdit::allocateExtendedStyles(sptr_t numberStyles) { - return send(SCI_ALLOCATEEXTENDEDSTYLES, numberStyles, 0); -} - -void ScintillaEdit::addUndoAction(sptr_t token, sptr_t flags) { - send(SCI_ADDUNDOACTION, token, flags); -} - -sptr_t ScintillaEdit::charPositionFromPoint(sptr_t x, sptr_t y) { - return send(SCI_CHARPOSITIONFROMPOINT, x, y); -} - -sptr_t ScintillaEdit::charPositionFromPointClose(sptr_t x, sptr_t y) { - return send(SCI_CHARPOSITIONFROMPOINTCLOSE, x, y); -} - -void ScintillaEdit::setMouseSelectionRectangularSwitch(bool mouseSelectionRectangularSwitch) { - send(SCI_SETMOUSESELECTIONRECTANGULARSWITCH, mouseSelectionRectangularSwitch, 0); -} - -bool ScintillaEdit::mouseSelectionRectangularSwitch() const { - return send(SCI_GETMOUSESELECTIONRECTANGULARSWITCH, 0, 0); -} - -void ScintillaEdit::setMultipleSelection(bool multipleSelection) { - send(SCI_SETMULTIPLESELECTION, multipleSelection, 0); -} - -bool ScintillaEdit::multipleSelection() const { - return send(SCI_GETMULTIPLESELECTION, 0, 0); -} - -void ScintillaEdit::setAdditionalSelectionTyping(bool additionalSelectionTyping) { - send(SCI_SETADDITIONALSELECTIONTYPING, additionalSelectionTyping, 0); -} - -bool ScintillaEdit::additionalSelectionTyping() const { - return send(SCI_GETADDITIONALSELECTIONTYPING, 0, 0); -} - -void ScintillaEdit::setAdditionalCaretsBlink(bool additionalCaretsBlink) { - send(SCI_SETADDITIONALCARETSBLINK, additionalCaretsBlink, 0); -} - -bool ScintillaEdit::additionalCaretsBlink() const { - return send(SCI_GETADDITIONALCARETSBLINK, 0, 0); -} - -void ScintillaEdit::setAdditionalCaretsVisible(bool additionalCaretsVisible) { - send(SCI_SETADDITIONALCARETSVISIBLE, additionalCaretsVisible, 0); -} - -bool ScintillaEdit::additionalCaretsVisible() const { - return send(SCI_GETADDITIONALCARETSVISIBLE, 0, 0); -} - -sptr_t ScintillaEdit::selections() const { - return send(SCI_GETSELECTIONS, 0, 0); -} - -bool ScintillaEdit::selectionEmpty() const { - return send(SCI_GETSELECTIONEMPTY, 0, 0); -} - -void ScintillaEdit::clearSelections() { - send(SCI_CLEARSELECTIONS, 0, 0); -} - -sptr_t ScintillaEdit::setSelection(sptr_t caret, sptr_t anchor) { - return send(SCI_SETSELECTION, caret, anchor); -} - -sptr_t ScintillaEdit::addSelection(sptr_t caret, sptr_t anchor) { - return send(SCI_ADDSELECTION, caret, anchor); -} - -void ScintillaEdit::dropSelectionN(sptr_t selection) { - send(SCI_DROPSELECTIONN, selection, 0); -} - -void ScintillaEdit::setMainSelection(sptr_t selection) { - send(SCI_SETMAINSELECTION, selection, 0); -} - -sptr_t ScintillaEdit::mainSelection() const { - return send(SCI_GETMAINSELECTION, 0, 0); -} - -void ScintillaEdit::setSelectionNCaret(sptr_t selection, sptr_t caret) { - send(SCI_SETSELECTIONNCARET, selection, caret); -} - -sptr_t ScintillaEdit::selectionNCaret(sptr_t selection) const { - return send(SCI_GETSELECTIONNCARET, selection, 0); -} - -void ScintillaEdit::setSelectionNAnchor(sptr_t selection, sptr_t anchor) { - send(SCI_SETSELECTIONNANCHOR, selection, anchor); -} - -sptr_t ScintillaEdit::selectionNAnchor(sptr_t selection) const { - return send(SCI_GETSELECTIONNANCHOR, selection, 0); -} - -void ScintillaEdit::setSelectionNCaretVirtualSpace(sptr_t selection, sptr_t space) { - send(SCI_SETSELECTIONNCARETVIRTUALSPACE, selection, space); -} - -sptr_t ScintillaEdit::selectionNCaretVirtualSpace(sptr_t selection) const { - return send(SCI_GETSELECTIONNCARETVIRTUALSPACE, selection, 0); -} - -void ScintillaEdit::setSelectionNAnchorVirtualSpace(sptr_t selection, sptr_t space) { - send(SCI_SETSELECTIONNANCHORVIRTUALSPACE, selection, space); -} - -sptr_t ScintillaEdit::selectionNAnchorVirtualSpace(sptr_t selection) const { - return send(SCI_GETSELECTIONNANCHORVIRTUALSPACE, selection, 0); -} - -void ScintillaEdit::setSelectionNStart(sptr_t selection, sptr_t anchor) { - send(SCI_SETSELECTIONNSTART, selection, anchor); -} - -sptr_t ScintillaEdit::selectionNStart(sptr_t selection) const { - return send(SCI_GETSELECTIONNSTART, selection, 0); -} - -void ScintillaEdit::setSelectionNEnd(sptr_t selection, sptr_t caret) { - send(SCI_SETSELECTIONNEND, selection, caret); -} - -sptr_t ScintillaEdit::selectionNEnd(sptr_t selection) const { - return send(SCI_GETSELECTIONNEND, selection, 0); -} - -void ScintillaEdit::setRectangularSelectionCaret(sptr_t caret) { - send(SCI_SETRECTANGULARSELECTIONCARET, caret, 0); -} - -sptr_t ScintillaEdit::rectangularSelectionCaret() const { - return send(SCI_GETRECTANGULARSELECTIONCARET, 0, 0); -} - -void ScintillaEdit::setRectangularSelectionAnchor(sptr_t anchor) { - send(SCI_SETRECTANGULARSELECTIONANCHOR, anchor, 0); -} - -sptr_t ScintillaEdit::rectangularSelectionAnchor() const { - return send(SCI_GETRECTANGULARSELECTIONANCHOR, 0, 0); -} - -void ScintillaEdit::setRectangularSelectionCaretVirtualSpace(sptr_t space) { - send(SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE, space, 0); -} - -sptr_t ScintillaEdit::rectangularSelectionCaretVirtualSpace() const { - return send(SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE, 0, 0); -} - -void ScintillaEdit::setRectangularSelectionAnchorVirtualSpace(sptr_t space) { - send(SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE, space, 0); -} - -sptr_t ScintillaEdit::rectangularSelectionAnchorVirtualSpace() const { - return send(SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE, 0, 0); -} - -void ScintillaEdit::setVirtualSpaceOptions(sptr_t virtualSpaceOptions) { - send(SCI_SETVIRTUALSPACEOPTIONS, virtualSpaceOptions, 0); -} - -sptr_t ScintillaEdit::virtualSpaceOptions() const { - return send(SCI_GETVIRTUALSPACEOPTIONS, 0, 0); -} - -void ScintillaEdit::setRectangularSelectionModifier(sptr_t modifier) { - send(SCI_SETRECTANGULARSELECTIONMODIFIER, modifier, 0); -} - -sptr_t ScintillaEdit::rectangularSelectionModifier() const { - return send(SCI_GETRECTANGULARSELECTIONMODIFIER, 0, 0); -} - -void ScintillaEdit::setAdditionalSelFore(sptr_t fore) { - send(SCI_SETADDITIONALSELFORE, fore, 0); -} - -void ScintillaEdit::setAdditionalSelBack(sptr_t back) { - send(SCI_SETADDITIONALSELBACK, back, 0); -} - -void ScintillaEdit::setAdditionalSelAlpha(sptr_t alpha) { - send(SCI_SETADDITIONALSELALPHA, alpha, 0); -} - -sptr_t ScintillaEdit::additionalSelAlpha() const { - return send(SCI_GETADDITIONALSELALPHA, 0, 0); -} - -void ScintillaEdit::setAdditionalCaretFore(sptr_t fore) { - send(SCI_SETADDITIONALCARETFORE, fore, 0); -} - -sptr_t ScintillaEdit::additionalCaretFore() const { - return send(SCI_GETADDITIONALCARETFORE, 0, 0); -} - -void ScintillaEdit::rotateSelection() { - send(SCI_ROTATESELECTION, 0, 0); -} - -void ScintillaEdit::swapMainAnchorCaret() { - send(SCI_SWAPMAINANCHORCARET, 0, 0); -} - -void ScintillaEdit::multipleSelectAddNext() { - send(SCI_MULTIPLESELECTADDNEXT, 0, 0); -} - -void ScintillaEdit::multipleSelectAddEach() { - send(SCI_MULTIPLESELECTADDEACH, 0, 0); -} - -sptr_t ScintillaEdit::changeLexerState(sptr_t start, sptr_t end) { - return send(SCI_CHANGELEXERSTATE, start, end); -} - -sptr_t ScintillaEdit::contractedFoldNext(sptr_t lineStart) { - return send(SCI_CONTRACTEDFOLDNEXT, lineStart, 0); -} - -void ScintillaEdit::verticalCentreCaret() { - send(SCI_VERTICALCENTRECARET, 0, 0); -} - -void ScintillaEdit::moveSelectedLinesUp() { - send(SCI_MOVESELECTEDLINESUP, 0, 0); -} - -void ScintillaEdit::moveSelectedLinesDown() { - send(SCI_MOVESELECTEDLINESDOWN, 0, 0); -} - -void ScintillaEdit::setIdentifier(sptr_t identifier) { - send(SCI_SETIDENTIFIER, identifier, 0); -} - -sptr_t ScintillaEdit::identifier() const { - return send(SCI_GETIDENTIFIER, 0, 0); -} - -void ScintillaEdit::rGBAImageSetWidth(sptr_t width) { - send(SCI_RGBAIMAGESETWIDTH, width, 0); -} - -void ScintillaEdit::rGBAImageSetHeight(sptr_t height) { - send(SCI_RGBAIMAGESETHEIGHT, height, 0); -} - -void ScintillaEdit::rGBAImageSetScale(sptr_t scalePercent) { - send(SCI_RGBAIMAGESETSCALE, scalePercent, 0); -} - -void ScintillaEdit::markerDefineRGBAImage(sptr_t markerNumber, const char * pixels) { - send(SCI_MARKERDEFINERGBAIMAGE, markerNumber, (sptr_t)pixels); -} - -void ScintillaEdit::registerRGBAImage(sptr_t type, const char * pixels) { - send(SCI_REGISTERRGBAIMAGE, type, (sptr_t)pixels); -} - -void ScintillaEdit::scrollToStart() { - send(SCI_SCROLLTOSTART, 0, 0); -} - -void ScintillaEdit::scrollToEnd() { - send(SCI_SCROLLTOEND, 0, 0); -} - -void ScintillaEdit::setTechnology(sptr_t technology) { - send(SCI_SETTECHNOLOGY, technology, 0); -} - -sptr_t ScintillaEdit::technology() const { - return send(SCI_GETTECHNOLOGY, 0, 0); -} - -sptr_t ScintillaEdit::createLoader(sptr_t bytes) { - return send(SCI_CREATELOADER, bytes, 0); -} - -void ScintillaEdit::findIndicatorShow(sptr_t start, sptr_t end) { - send(SCI_FINDINDICATORSHOW, start, end); -} - -void ScintillaEdit::findIndicatorFlash(sptr_t start, sptr_t end) { - send(SCI_FINDINDICATORFLASH, start, end); -} - -void ScintillaEdit::findIndicatorHide() { - send(SCI_FINDINDICATORHIDE, 0, 0); -} - -void ScintillaEdit::vCHomeDisplay() { - send(SCI_VCHOMEDISPLAY, 0, 0); -} - -void ScintillaEdit::vCHomeDisplayExtend() { - send(SCI_VCHOMEDISPLAYEXTEND, 0, 0); -} - -bool ScintillaEdit::caretLineVisibleAlways() const { - return send(SCI_GETCARETLINEVISIBLEALWAYS, 0, 0); -} - -void ScintillaEdit::setCaretLineVisibleAlways(bool alwaysVisible) { - send(SCI_SETCARETLINEVISIBLEALWAYS, alwaysVisible, 0); -} - -void ScintillaEdit::setLineEndTypesAllowed(sptr_t lineEndBitSet) { - send(SCI_SETLINEENDTYPESALLOWED, lineEndBitSet, 0); -} - -sptr_t ScintillaEdit::lineEndTypesAllowed() const { - return send(SCI_GETLINEENDTYPESALLOWED, 0, 0); -} - -sptr_t ScintillaEdit::lineEndTypesActive() const { - return send(SCI_GETLINEENDTYPESACTIVE, 0, 0); -} - -void ScintillaEdit::setRepresentation(const char * encodedCharacter, const char * representation) { - send(SCI_SETREPRESENTATION, (sptr_t)encodedCharacter, (sptr_t)representation); -} - -QByteArray ScintillaEdit::representation(const char * encodedCharacter) const { - return TextReturner(SCI_GETREPRESENTATION, (sptr_t)encodedCharacter); -} - -void ScintillaEdit::clearRepresentation(const char * encodedCharacter) { - send(SCI_CLEARREPRESENTATION, (sptr_t)encodedCharacter, 0); -} - -void ScintillaEdit::startRecord() { - send(SCI_STARTRECORD, 0, 0); -} - -void ScintillaEdit::stopRecord() { - send(SCI_STOPRECORD, 0, 0); -} - -void ScintillaEdit::setLexer(sptr_t lexer) { - send(SCI_SETLEXER, lexer, 0); -} - -sptr_t ScintillaEdit::lexer() const { - return send(SCI_GETLEXER, 0, 0); -} - -void ScintillaEdit::colourise(sptr_t start, sptr_t end) { - send(SCI_COLOURISE, start, end); -} - -void ScintillaEdit::setProperty(const char * key, const char * value) { - send(SCI_SETPROPERTY, (sptr_t)key, (sptr_t)value); -} - -void ScintillaEdit::setKeyWords(sptr_t keyWordSet, const char * keyWords) { - send(SCI_SETKEYWORDS, keyWordSet, (sptr_t)keyWords); -} - -void ScintillaEdit::setLexerLanguage(const char * language) { - send(SCI_SETLEXERLANGUAGE, 0, (sptr_t)language); -} - -void ScintillaEdit::loadLexerLibrary(const char * path) { - send(SCI_LOADLEXERLIBRARY, 0, (sptr_t)path); -} - -QByteArray ScintillaEdit::property(const char * key) const { - return TextReturner(SCI_GETPROPERTY, (sptr_t)key); -} - -QByteArray ScintillaEdit::propertyExpanded(const char * key) const { - return TextReturner(SCI_GETPROPERTYEXPANDED, (sptr_t)key); -} - -sptr_t ScintillaEdit::propertyInt(const char * key, sptr_t defaultValue) const { - return send(SCI_GETPROPERTYINT, (sptr_t)key, defaultValue); -} - -sptr_t ScintillaEdit::styleBitsNeeded() const { - return send(SCI_GETSTYLEBITSNEEDED, 0, 0); -} - -QByteArray ScintillaEdit::lexerLanguage() const { - return TextReturner(SCI_GETLEXERLANGUAGE, 0); -} - -sptr_t ScintillaEdit::privateLexerCall(sptr_t operation, sptr_t pointer) { - return send(SCI_PRIVATELEXERCALL, operation, pointer); -} - -QByteArray ScintillaEdit::propertyNames() { - return TextReturner(SCI_PROPERTYNAMES, 0); -} - -sptr_t ScintillaEdit::propertyType(const char * name) { - return send(SCI_PROPERTYTYPE, (sptr_t)name, 0); -} - -QByteArray ScintillaEdit::describeProperty(const char * name) { - return TextReturner(SCI_DESCRIBEPROPERTY, (sptr_t)name); -} - -QByteArray ScintillaEdit::describeKeyWordSets() { - return TextReturner(SCI_DESCRIBEKEYWORDSETS, 0); -} - -sptr_t ScintillaEdit::lineEndTypesSupported() const { - return send(SCI_GETLINEENDTYPESSUPPORTED, 0, 0); -} - -sptr_t ScintillaEdit::allocateSubStyles(sptr_t styleBase, sptr_t numberStyles) { - return send(SCI_ALLOCATESUBSTYLES, styleBase, numberStyles); -} - -sptr_t ScintillaEdit::subStylesStart(sptr_t styleBase) const { - return send(SCI_GETSUBSTYLESSTART, styleBase, 0); -} - -sptr_t ScintillaEdit::subStylesLength(sptr_t styleBase) const { - return send(SCI_GETSUBSTYLESLENGTH, styleBase, 0); -} - -sptr_t ScintillaEdit::styleFromSubStyle(sptr_t subStyle) const { - return send(SCI_GETSTYLEFROMSUBSTYLE, subStyle, 0); -} - -sptr_t ScintillaEdit::primaryStyleFromStyle(sptr_t style) const { - return send(SCI_GETPRIMARYSTYLEFROMSTYLE, style, 0); -} - -void ScintillaEdit::freeSubStyles() { - send(SCI_FREESUBSTYLES, 0, 0); -} - -void ScintillaEdit::setIdentifiers(sptr_t style, const char * identifiers) { - send(SCI_SETIDENTIFIERS, style, (sptr_t)identifiers); -} - -sptr_t ScintillaEdit::distanceToSecondaryStyles() const { - return send(SCI_DISTANCETOSECONDARYSTYLES, 0, 0); -} - -QByteArray ScintillaEdit::subStyleBases() const { - return TextReturner(SCI_GETSUBSTYLEBASES, 0); -} - -/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.h b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.h deleted file mode 100644 index 56d2cfe46..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEdit/ScintillaEdit.h +++ /dev/null @@ -1,766 +0,0 @@ -// ScintillaEdit.h -// Extended version of ScintillaEditBase with a method for each API -// Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware - -#ifndef SCINTILLAEDIT_H -#define SCINTILLAEDIT_H - -#include - -#include "ScintillaEditBase.h" -#include "ScintillaDocument.h" - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#ifndef EXPORT_IMPORT_API -#ifdef WIN32 -#ifdef MAKING_LIBRARY -#define EXPORT_IMPORT_API __declspec(dllexport) -#else -// Defining dllimport upsets moc -#define EXPORT_IMPORT_API __declspec(dllimport) -//#define EXPORT_IMPORT_API -#endif -#else -#define EXPORT_IMPORT_API -#endif -#endif - -class EXPORT_IMPORT_API ScintillaEdit : public ScintillaEditBase { - Q_OBJECT - -public: - ScintillaEdit(QWidget *parent = 0); - virtual ~ScintillaEdit(); - - QByteArray TextReturner(int message, uptr_t wParam) const; - - QPairfind_text(int flags, const char *text, int cpMin, int cpMax); - QByteArray get_text_range(int start, int end); - ScintillaDocument *get_doc(); - void set_doc(ScintillaDocument *pdoc_); - - // Same as previous two methods but with Qt style names - QPairfindText(int flags, const char *text, int cpMin, int cpMax) { - return find_text(flags, text, cpMin, cpMax); - } - - QByteArray textRange(int start, int end) { - return get_text_range(start, end); - } - - // Exposing the FORMATRANGE api with both underscore & qt style names - long format_range(bool draw, QPaintDevice* target, QPaintDevice* measure, - const QRect& print_rect, const QRect& page_rect, - long range_start, long range_end); - long formatRange(bool draw, QPaintDevice* target, QPaintDevice* measure, - const QRect& print_rect, const QRect& page_rect, - long range_start, long range_end) { - return format_range(draw, target, measure, print_rect, page_rect, - range_start, range_end); - } - -/* ++Autogenerated -- start of section automatically generated from Scintilla.iface */ - void addText(sptr_t length, const char * text); - void addStyledText(sptr_t length, const char * c); - void insertText(sptr_t pos, const char * text); - void changeInsertion(sptr_t length, const char * text); - void clearAll(); - void deleteRange(sptr_t start, sptr_t lengthDelete); - void clearDocumentStyle(); - sptr_t length() const; - sptr_t charAt(sptr_t pos) const; - sptr_t currentPos() const; - sptr_t anchor() const; - sptr_t styleAt(sptr_t pos) const; - void redo(); - void setUndoCollection(bool collectUndo); - void selectAll(); - void setSavePoint(); - bool canRedo(); - sptr_t markerLineFromHandle(sptr_t markerHandle); - void markerDeleteHandle(sptr_t markerHandle); - bool undoCollection() const; - sptr_t viewWS() const; - void setViewWS(sptr_t viewWS); - sptr_t tabDrawMode() const; - void setTabDrawMode(sptr_t tabDrawMode); - sptr_t positionFromPoint(sptr_t x, sptr_t y); - sptr_t positionFromPointClose(sptr_t x, sptr_t y); - void gotoLine(sptr_t line); - void gotoPos(sptr_t caret); - void setAnchor(sptr_t anchor); - QByteArray getCurLine(sptr_t length); - sptr_t endStyled() const; - void convertEOLs(sptr_t eolMode); - sptr_t eOLMode() const; - void setEOLMode(sptr_t eolMode); - void startStyling(sptr_t start, sptr_t unused); - void setStyling(sptr_t length, sptr_t style); - bool bufferedDraw() const; - void setBufferedDraw(bool buffered); - void setTabWidth(sptr_t tabWidth); - sptr_t tabWidth() const; - void clearTabStops(sptr_t line); - void addTabStop(sptr_t line, sptr_t x); - sptr_t getNextTabStop(sptr_t line, sptr_t x); - void setCodePage(sptr_t codePage); - sptr_t iMEInteraction() const; - void setIMEInteraction(sptr_t imeInteraction); - void markerDefine(sptr_t markerNumber, sptr_t markerSymbol); - void markerSetFore(sptr_t markerNumber, sptr_t fore); - void markerSetBack(sptr_t markerNumber, sptr_t back); - void markerSetBackSelected(sptr_t markerNumber, sptr_t back); - void markerEnableHighlight(bool enabled); - sptr_t markerAdd(sptr_t line, sptr_t markerNumber); - void markerDelete(sptr_t line, sptr_t markerNumber); - void markerDeleteAll(sptr_t markerNumber); - sptr_t markerGet(sptr_t line); - sptr_t markerNext(sptr_t lineStart, sptr_t markerMask); - sptr_t markerPrevious(sptr_t lineStart, sptr_t markerMask); - void markerDefinePixmap(sptr_t markerNumber, const char * pixmap); - void markerAddSet(sptr_t line, sptr_t markerSet); - void markerSetAlpha(sptr_t markerNumber, sptr_t alpha); - void setMarginTypeN(sptr_t margin, sptr_t marginType); - sptr_t marginTypeN(sptr_t margin) const; - void setMarginWidthN(sptr_t margin, sptr_t pixelWidth); - sptr_t marginWidthN(sptr_t margin) const; - void setMarginMaskN(sptr_t margin, sptr_t mask); - sptr_t marginMaskN(sptr_t margin) const; - void setMarginSensitiveN(sptr_t margin, bool sensitive); - bool marginSensitiveN(sptr_t margin) const; - void setMarginCursorN(sptr_t margin, sptr_t cursor); - sptr_t marginCursorN(sptr_t margin) const; - void setMarginBackN(sptr_t margin, sptr_t back); - sptr_t marginBackN(sptr_t margin) const; - void setMargins(sptr_t margins); - sptr_t margins() const; - void styleClearAll(); - void styleSetFore(sptr_t style, sptr_t fore); - void styleSetBack(sptr_t style, sptr_t back); - void styleSetBold(sptr_t style, bool bold); - void styleSetItalic(sptr_t style, bool italic); - void styleSetSize(sptr_t style, sptr_t sizePoints); - void styleSetFont(sptr_t style, const char * fontName); - void styleSetEOLFilled(sptr_t style, bool eolFilled); - void styleResetDefault(); - void styleSetUnderline(sptr_t style, bool underline); - sptr_t styleFore(sptr_t style) const; - sptr_t styleBack(sptr_t style) const; - bool styleBold(sptr_t style) const; - bool styleItalic(sptr_t style) const; - sptr_t styleSize(sptr_t style) const; - QByteArray styleFont(sptr_t style) const; - bool styleEOLFilled(sptr_t style) const; - bool styleUnderline(sptr_t style) const; - sptr_t styleCase(sptr_t style) const; - sptr_t styleCharacterSet(sptr_t style) const; - bool styleVisible(sptr_t style) const; - bool styleChangeable(sptr_t style) const; - bool styleHotSpot(sptr_t style) const; - void styleSetCase(sptr_t style, sptr_t caseVisible); - void styleSetSizeFractional(sptr_t style, sptr_t sizeHundredthPoints); - sptr_t styleSizeFractional(sptr_t style) const; - void styleSetWeight(sptr_t style, sptr_t weight); - sptr_t styleWeight(sptr_t style) const; - void styleSetCharacterSet(sptr_t style, sptr_t characterSet); - void styleSetHotSpot(sptr_t style, bool hotspot); - void setSelFore(bool useSetting, sptr_t fore); - void setSelBack(bool useSetting, sptr_t back); - sptr_t selAlpha() const; - void setSelAlpha(sptr_t alpha); - bool selEOLFilled() const; - void setSelEOLFilled(bool filled); - void setCaretFore(sptr_t fore); - void assignCmdKey(sptr_t keyDefinition, sptr_t sciCommand); - void clearCmdKey(sptr_t keyDefinition); - void clearAllCmdKeys(); - void setStylingEx(sptr_t length, const char * styles); - void styleSetVisible(sptr_t style, bool visible); - sptr_t caretPeriod() const; - void setCaretPeriod(sptr_t periodMilliseconds); - void setWordChars(const char * characters); - QByteArray wordChars() const; - void beginUndoAction(); - void endUndoAction(); - void indicSetStyle(sptr_t indicator, sptr_t indicatorStyle); - sptr_t indicStyle(sptr_t indicator) const; - void indicSetFore(sptr_t indicator, sptr_t fore); - sptr_t indicFore(sptr_t indicator) const; - void indicSetUnder(sptr_t indicator, bool under); - bool indicUnder(sptr_t indicator) const; - void indicSetHoverStyle(sptr_t indicator, sptr_t indicatorStyle); - sptr_t indicHoverStyle(sptr_t indicator) const; - void indicSetHoverFore(sptr_t indicator, sptr_t fore); - sptr_t indicHoverFore(sptr_t indicator) const; - void indicSetFlags(sptr_t indicator, sptr_t flags); - sptr_t indicFlags(sptr_t indicator) const; - void setWhitespaceFore(bool useSetting, sptr_t fore); - void setWhitespaceBack(bool useSetting, sptr_t back); - void setWhitespaceSize(sptr_t size); - sptr_t whitespaceSize() const; - void setStyleBits(sptr_t bits); - sptr_t styleBits() const; - void setLineState(sptr_t line, sptr_t state); - sptr_t lineState(sptr_t line) const; - sptr_t maxLineState() const; - bool caretLineVisible() const; - void setCaretLineVisible(bool show); - sptr_t caretLineBack() const; - void setCaretLineBack(sptr_t back); - void styleSetChangeable(sptr_t style, bool changeable); - void autoCShow(sptr_t lengthEntered, const char * itemList); - void autoCCancel(); - bool autoCActive(); - sptr_t autoCPosStart(); - void autoCComplete(); - void autoCStops(const char * characterSet); - void autoCSetSeparator(sptr_t separatorCharacter); - sptr_t autoCSeparator() const; - void autoCSelect(const char * select); - void autoCSetCancelAtStart(bool cancel); - bool autoCCancelAtStart() const; - void autoCSetFillUps(const char * characterSet); - void autoCSetChooseSingle(bool chooseSingle); - bool autoCChooseSingle() const; - void autoCSetIgnoreCase(bool ignoreCase); - bool autoCIgnoreCase() const; - void userListShow(sptr_t listType, const char * itemList); - void autoCSetAutoHide(bool autoHide); - bool autoCAutoHide() const; - void autoCSetDropRestOfWord(bool dropRestOfWord); - bool autoCDropRestOfWord() const; - void registerImage(sptr_t type, const char * xpmData); - void clearRegisteredImages(); - sptr_t autoCTypeSeparator() const; - void autoCSetTypeSeparator(sptr_t separatorCharacter); - void autoCSetMaxWidth(sptr_t characterCount); - sptr_t autoCMaxWidth() const; - void autoCSetMaxHeight(sptr_t rowCount); - sptr_t autoCMaxHeight() const; - void setIndent(sptr_t indentSize); - sptr_t indent() const; - void setUseTabs(bool useTabs); - bool useTabs() const; - void setLineIndentation(sptr_t line, sptr_t indentation); - sptr_t lineIndentation(sptr_t line) const; - sptr_t lineIndentPosition(sptr_t line) const; - sptr_t column(sptr_t pos) const; - sptr_t countCharacters(sptr_t start, sptr_t end); - void setHScrollBar(bool visible); - bool hScrollBar() const; - void setIndentationGuides(sptr_t indentView); - sptr_t indentationGuides() const; - void setHighlightGuide(sptr_t column); - sptr_t highlightGuide() const; - sptr_t lineEndPosition(sptr_t line) const; - sptr_t codePage() const; - sptr_t caretFore() const; - bool readOnly() const; - void setCurrentPos(sptr_t caret); - void setSelectionStart(sptr_t anchor); - sptr_t selectionStart() const; - void setSelectionEnd(sptr_t caret); - sptr_t selectionEnd() const; - void setEmptySelection(sptr_t caret); - void setPrintMagnification(sptr_t magnification); - sptr_t printMagnification() const; - void setPrintColourMode(sptr_t mode); - sptr_t printColourMode() const; - sptr_t firstVisibleLine() const; - QByteArray getLine(sptr_t line); - sptr_t lineCount() const; - void setMarginLeft(sptr_t pixelWidth); - sptr_t marginLeft() const; - void setMarginRight(sptr_t pixelWidth); - sptr_t marginRight() const; - bool modify() const; - void setSel(sptr_t anchor, sptr_t caret); - QByteArray getSelText(); - void hideSelection(bool hide); - sptr_t pointXFromPosition(sptr_t pos); - sptr_t pointYFromPosition(sptr_t pos); - sptr_t lineFromPosition(sptr_t pos); - sptr_t positionFromLine(sptr_t line); - void lineScroll(sptr_t columns, sptr_t lines); - void scrollCaret(); - void scrollRange(sptr_t secondary, sptr_t primary); - void replaceSel(const char * text); - void setReadOnly(bool readOnly); - void null(); - bool canPaste(); - bool canUndo(); - void emptyUndoBuffer(); - void undo(); - void cut(); - void copy(); - void paste(); - void clear(); - void setText(const char * text); - QByteArray getText(sptr_t length); - sptr_t textLength() const; - sptr_t directFunction() const; - sptr_t directPointer() const; - void setOvertype(bool overType); - bool overtype() const; - void setCaretWidth(sptr_t pixelWidth); - sptr_t caretWidth() const; - void setTargetStart(sptr_t start); - sptr_t targetStart() const; - void setTargetEnd(sptr_t end); - sptr_t targetEnd() const; - void setTargetRange(sptr_t start, sptr_t end); - QByteArray targetText() const; - void targetFromSelection(); - void targetWholeDocument(); - sptr_t replaceTarget(sptr_t length, const char * text); - sptr_t replaceTargetRE(sptr_t length, const char * text); - sptr_t searchInTarget(sptr_t length, const char * text); - void setSearchFlags(sptr_t searchFlags); - sptr_t searchFlags() const; - void callTipShow(sptr_t pos, const char * definition); - void callTipCancel(); - bool callTipActive(); - sptr_t callTipPosStart(); - void callTipSetPosStart(sptr_t posStart); - void callTipSetHlt(sptr_t highlightStart, sptr_t highlightEnd); - void callTipSetBack(sptr_t back); - void callTipSetFore(sptr_t fore); - void callTipSetForeHlt(sptr_t fore); - void callTipUseStyle(sptr_t tabSize); - void callTipSetPosition(bool above); - sptr_t visibleFromDocLine(sptr_t docLine); - sptr_t docLineFromVisible(sptr_t displayLine); - sptr_t wrapCount(sptr_t docLine); - void setFoldLevel(sptr_t line, sptr_t level); - sptr_t foldLevel(sptr_t line) const; - sptr_t lastChild(sptr_t line, sptr_t level) const; - sptr_t foldParent(sptr_t line) const; - void showLines(sptr_t lineStart, sptr_t lineEnd); - void hideLines(sptr_t lineStart, sptr_t lineEnd); - bool lineVisible(sptr_t line) const; - bool allLinesVisible() const; - void setFoldExpanded(sptr_t line, bool expanded); - bool foldExpanded(sptr_t line) const; - void toggleFold(sptr_t line); - void toggleFoldShowText(sptr_t line, const char * text); - void foldDisplayTextSetStyle(sptr_t style); - void foldLine(sptr_t line, sptr_t action); - void foldChildren(sptr_t line, sptr_t action); - void expandChildren(sptr_t line, sptr_t level); - void foldAll(sptr_t action); - void ensureVisible(sptr_t line); - void setAutomaticFold(sptr_t automaticFold); - sptr_t automaticFold() const; - void setFoldFlags(sptr_t flags); - void ensureVisibleEnforcePolicy(sptr_t line); - void setTabIndents(bool tabIndents); - bool tabIndents() const; - void setBackSpaceUnIndents(bool bsUnIndents); - bool backSpaceUnIndents() const; - void setMouseDwellTime(sptr_t periodMilliseconds); - sptr_t mouseDwellTime() const; - sptr_t wordStartPosition(sptr_t pos, bool onlyWordCharacters); - sptr_t wordEndPosition(sptr_t pos, bool onlyWordCharacters); - bool isRangeWord(sptr_t start, sptr_t end); - void setIdleStyling(sptr_t idleStyling); - sptr_t idleStyling() const; - void setWrapMode(sptr_t wrapMode); - sptr_t wrapMode() const; - void setWrapVisualFlags(sptr_t wrapVisualFlags); - sptr_t wrapVisualFlags() const; - void setWrapVisualFlagsLocation(sptr_t wrapVisualFlagsLocation); - sptr_t wrapVisualFlagsLocation() const; - void setWrapStartIndent(sptr_t indent); - sptr_t wrapStartIndent() const; - void setWrapIndentMode(sptr_t wrapIndentMode); - sptr_t wrapIndentMode() const; - void setLayoutCache(sptr_t cacheMode); - sptr_t layoutCache() const; - void setScrollWidth(sptr_t pixelWidth); - sptr_t scrollWidth() const; - void setScrollWidthTracking(bool tracking); - bool scrollWidthTracking() const; - sptr_t textWidth(sptr_t style, const char * text); - void setEndAtLastLine(bool endAtLastLine); - bool endAtLastLine() const; - sptr_t textHeight(sptr_t line); - void setVScrollBar(bool visible); - bool vScrollBar() const; - void appendText(sptr_t length, const char * text); - bool twoPhaseDraw() const; - void setTwoPhaseDraw(bool twoPhase); - sptr_t phasesDraw() const; - void setPhasesDraw(sptr_t phases); - void setFontQuality(sptr_t fontQuality); - sptr_t fontQuality() const; - void setFirstVisibleLine(sptr_t displayLine); - void setMultiPaste(sptr_t multiPaste); - sptr_t multiPaste() const; - QByteArray tag(sptr_t tagNumber) const; - void linesJoin(); - void linesSplit(sptr_t pixelWidth); - void setFoldMarginColour(bool useSetting, sptr_t back); - void setFoldMarginHiColour(bool useSetting, sptr_t fore); - void lineDown(); - void lineDownExtend(); - void lineUp(); - void lineUpExtend(); - void charLeft(); - void charLeftExtend(); - void charRight(); - void charRightExtend(); - void wordLeft(); - void wordLeftExtend(); - void wordRight(); - void wordRightExtend(); - void home(); - void homeExtend(); - void lineEnd(); - void lineEndExtend(); - void documentStart(); - void documentStartExtend(); - void documentEnd(); - void documentEndExtend(); - void pageUp(); - void pageUpExtend(); - void pageDown(); - void pageDownExtend(); - void editToggleOvertype(); - void cancel(); - void deleteBack(); - void tab(); - void backTab(); - void newLine(); - void formFeed(); - void vCHome(); - void vCHomeExtend(); - void zoomIn(); - void zoomOut(); - void delWordLeft(); - void delWordRight(); - void delWordRightEnd(); - void lineCut(); - void lineDelete(); - void lineTranspose(); - void lineDuplicate(); - void lowerCase(); - void upperCase(); - void lineScrollDown(); - void lineScrollUp(); - void deleteBackNotLine(); - void homeDisplay(); - void homeDisplayExtend(); - void lineEndDisplay(); - void lineEndDisplayExtend(); - void homeWrap(); - void homeWrapExtend(); - void lineEndWrap(); - void lineEndWrapExtend(); - void vCHomeWrap(); - void vCHomeWrapExtend(); - void lineCopy(); - void moveCaretInsideView(); - sptr_t lineLength(sptr_t line); - void braceHighlight(sptr_t posA, sptr_t posB); - void braceHighlightIndicator(bool useSetting, sptr_t indicator); - void braceBadLight(sptr_t pos); - void braceBadLightIndicator(bool useSetting, sptr_t indicator); - sptr_t braceMatch(sptr_t pos, sptr_t maxReStyle); - bool viewEOL() const; - void setViewEOL(bool visible); - sptr_t docPointer() const; - void setDocPointer(sptr_t doc); - void setModEventMask(sptr_t eventMask); - sptr_t edgeColumn() const; - void setEdgeColumn(sptr_t column); - sptr_t edgeMode() const; - void setEdgeMode(sptr_t edgeMode); - sptr_t edgeColour() const; - void setEdgeColour(sptr_t edgeColour); - void multiEdgeAddLine(sptr_t column, sptr_t edgeColour); - void multiEdgeClearAll(); - void searchAnchor(); - sptr_t searchNext(sptr_t searchFlags, const char * text); - sptr_t searchPrev(sptr_t searchFlags, const char * text); - sptr_t linesOnScreen() const; - void usePopUp(sptr_t popUpMode); - bool selectionIsRectangle() const; - void setZoom(sptr_t zoomInPoints); - sptr_t zoom() const; - sptr_t createDocument(); - void addRefDocument(sptr_t doc); - void releaseDocument(sptr_t doc); - sptr_t modEventMask() const; - void setFocus(bool focus); - bool focus() const; - void setStatus(sptr_t status); - sptr_t status() const; - void setMouseDownCaptures(bool captures); - bool mouseDownCaptures() const; - void setMouseWheelCaptures(bool captures); - bool mouseWheelCaptures() const; - void setCursor(sptr_t cursorType); - sptr_t cursor() const; - void setControlCharSymbol(sptr_t symbol); - sptr_t controlCharSymbol() const; - void wordPartLeft(); - void wordPartLeftExtend(); - void wordPartRight(); - void wordPartRightExtend(); - void setVisiblePolicy(sptr_t visiblePolicy, sptr_t visibleSlop); - void delLineLeft(); - void delLineRight(); - void setXOffset(sptr_t xOffset); - sptr_t xOffset() const; - void chooseCaretX(); - void grabFocus(); - void setXCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop); - void setYCaretPolicy(sptr_t caretPolicy, sptr_t caretSlop); - void setPrintWrapMode(sptr_t wrapMode); - sptr_t printWrapMode() const; - void setHotspotActiveFore(bool useSetting, sptr_t fore); - sptr_t hotspotActiveFore() const; - void setHotspotActiveBack(bool useSetting, sptr_t back); - sptr_t hotspotActiveBack() const; - void setHotspotActiveUnderline(bool underline); - bool hotspotActiveUnderline() const; - void setHotspotSingleLine(bool singleLine); - bool hotspotSingleLine() const; - void paraDown(); - void paraDownExtend(); - void paraUp(); - void paraUpExtend(); - sptr_t positionBefore(sptr_t pos); - sptr_t positionAfter(sptr_t pos); - sptr_t positionRelative(sptr_t pos, sptr_t relative); - void copyRange(sptr_t start, sptr_t end); - void copyText(sptr_t length, const char * text); - void setSelectionMode(sptr_t selectionMode); - sptr_t selectionMode() const; - sptr_t getLineSelStartPosition(sptr_t line); - sptr_t getLineSelEndPosition(sptr_t line); - void lineDownRectExtend(); - void lineUpRectExtend(); - void charLeftRectExtend(); - void charRightRectExtend(); - void homeRectExtend(); - void vCHomeRectExtend(); - void lineEndRectExtend(); - void pageUpRectExtend(); - void pageDownRectExtend(); - void stutteredPageUp(); - void stutteredPageUpExtend(); - void stutteredPageDown(); - void stutteredPageDownExtend(); - void wordLeftEnd(); - void wordLeftEndExtend(); - void wordRightEnd(); - void wordRightEndExtend(); - void setWhitespaceChars(const char * characters); - QByteArray whitespaceChars() const; - void setPunctuationChars(const char * characters); - QByteArray punctuationChars() const; - void setCharsDefault(); - sptr_t autoCCurrent() const; - QByteArray autoCCurrentText() const; - void autoCSetCaseInsensitiveBehaviour(sptr_t behaviour); - sptr_t autoCCaseInsensitiveBehaviour() const; - void autoCSetMulti(sptr_t multi); - sptr_t autoCMulti() const; - void autoCSetOrder(sptr_t order); - sptr_t autoCOrder() const; - void allocate(sptr_t bytes); - QByteArray targetAsUTF8(); - void setLengthForEncode(sptr_t bytes); - QByteArray encodedFromUTF8(const char * utf8); - sptr_t findColumn(sptr_t line, sptr_t column); - sptr_t caretSticky() const; - void setCaretSticky(sptr_t useCaretStickyBehaviour); - void toggleCaretSticky(); - void setPasteConvertEndings(bool convert); - bool pasteConvertEndings() const; - void selectionDuplicate(); - void setCaretLineBackAlpha(sptr_t alpha); - sptr_t caretLineBackAlpha() const; - void setCaretStyle(sptr_t caretStyle); - sptr_t caretStyle() const; - void setIndicatorCurrent(sptr_t indicator); - sptr_t indicatorCurrent() const; - void setIndicatorValue(sptr_t value); - sptr_t indicatorValue() const; - void indicatorFillRange(sptr_t start, sptr_t lengthFill); - void indicatorClearRange(sptr_t start, sptr_t lengthClear); - sptr_t indicatorAllOnFor(sptr_t pos); - sptr_t indicatorValueAt(sptr_t indicator, sptr_t pos); - sptr_t indicatorStart(sptr_t indicator, sptr_t pos); - sptr_t indicatorEnd(sptr_t indicator, sptr_t pos); - void setPositionCache(sptr_t size); - sptr_t positionCache() const; - void copyAllowLine(); - sptr_t characterPointer() const; - sptr_t rangePointer(sptr_t start, sptr_t lengthRange) const; - sptr_t gapPosition() const; - void indicSetAlpha(sptr_t indicator, sptr_t alpha); - sptr_t indicAlpha(sptr_t indicator) const; - void indicSetOutlineAlpha(sptr_t indicator, sptr_t alpha); - sptr_t indicOutlineAlpha(sptr_t indicator) const; - void setExtraAscent(sptr_t extraAscent); - sptr_t extraAscent() const; - void setExtraDescent(sptr_t extraDescent); - sptr_t extraDescent() const; - sptr_t markerSymbolDefined(sptr_t markerNumber); - void marginSetText(sptr_t line, const char * text); - QByteArray marginText(sptr_t line) const; - void marginSetStyle(sptr_t line, sptr_t style); - sptr_t marginStyle(sptr_t line) const; - void marginSetStyles(sptr_t line, const char * styles); - QByteArray marginStyles(sptr_t line) const; - void marginTextClearAll(); - void marginSetStyleOffset(sptr_t style); - sptr_t marginStyleOffset() const; - void setMarginOptions(sptr_t marginOptions); - sptr_t marginOptions() const; - void annotationSetText(sptr_t line, const char * text); - QByteArray annotationText(sptr_t line) const; - void annotationSetStyle(sptr_t line, sptr_t style); - sptr_t annotationStyle(sptr_t line) const; - void annotationSetStyles(sptr_t line, const char * styles); - QByteArray annotationStyles(sptr_t line) const; - sptr_t annotationLines(sptr_t line) const; - void annotationClearAll(); - void annotationSetVisible(sptr_t visible); - sptr_t annotationVisible() const; - void annotationSetStyleOffset(sptr_t style); - sptr_t annotationStyleOffset() const; - void releaseAllExtendedStyles(); - sptr_t allocateExtendedStyles(sptr_t numberStyles); - void addUndoAction(sptr_t token, sptr_t flags); - sptr_t charPositionFromPoint(sptr_t x, sptr_t y); - sptr_t charPositionFromPointClose(sptr_t x, sptr_t y); - void setMouseSelectionRectangularSwitch(bool mouseSelectionRectangularSwitch); - bool mouseSelectionRectangularSwitch() const; - void setMultipleSelection(bool multipleSelection); - bool multipleSelection() const; - void setAdditionalSelectionTyping(bool additionalSelectionTyping); - bool additionalSelectionTyping() const; - void setAdditionalCaretsBlink(bool additionalCaretsBlink); - bool additionalCaretsBlink() const; - void setAdditionalCaretsVisible(bool additionalCaretsVisible); - bool additionalCaretsVisible() const; - sptr_t selections() const; - bool selectionEmpty() const; - void clearSelections(); - sptr_t setSelection(sptr_t caret, sptr_t anchor); - sptr_t addSelection(sptr_t caret, sptr_t anchor); - void dropSelectionN(sptr_t selection); - void setMainSelection(sptr_t selection); - sptr_t mainSelection() const; - void setSelectionNCaret(sptr_t selection, sptr_t caret); - sptr_t selectionNCaret(sptr_t selection) const; - void setSelectionNAnchor(sptr_t selection, sptr_t anchor); - sptr_t selectionNAnchor(sptr_t selection) const; - void setSelectionNCaretVirtualSpace(sptr_t selection, sptr_t space); - sptr_t selectionNCaretVirtualSpace(sptr_t selection) const; - void setSelectionNAnchorVirtualSpace(sptr_t selection, sptr_t space); - sptr_t selectionNAnchorVirtualSpace(sptr_t selection) const; - void setSelectionNStart(sptr_t selection, sptr_t anchor); - sptr_t selectionNStart(sptr_t selection) const; - void setSelectionNEnd(sptr_t selection, sptr_t caret); - sptr_t selectionNEnd(sptr_t selection) const; - void setRectangularSelectionCaret(sptr_t caret); - sptr_t rectangularSelectionCaret() const; - void setRectangularSelectionAnchor(sptr_t anchor); - sptr_t rectangularSelectionAnchor() const; - void setRectangularSelectionCaretVirtualSpace(sptr_t space); - sptr_t rectangularSelectionCaretVirtualSpace() const; - void setRectangularSelectionAnchorVirtualSpace(sptr_t space); - sptr_t rectangularSelectionAnchorVirtualSpace() const; - void setVirtualSpaceOptions(sptr_t virtualSpaceOptions); - sptr_t virtualSpaceOptions() const; - void setRectangularSelectionModifier(sptr_t modifier); - sptr_t rectangularSelectionModifier() const; - void setAdditionalSelFore(sptr_t fore); - void setAdditionalSelBack(sptr_t back); - void setAdditionalSelAlpha(sptr_t alpha); - sptr_t additionalSelAlpha() const; - void setAdditionalCaretFore(sptr_t fore); - sptr_t additionalCaretFore() const; - void rotateSelection(); - void swapMainAnchorCaret(); - void multipleSelectAddNext(); - void multipleSelectAddEach(); - sptr_t changeLexerState(sptr_t start, sptr_t end); - sptr_t contractedFoldNext(sptr_t lineStart); - void verticalCentreCaret(); - void moveSelectedLinesUp(); - void moveSelectedLinesDown(); - void setIdentifier(sptr_t identifier); - sptr_t identifier() const; - void rGBAImageSetWidth(sptr_t width); - void rGBAImageSetHeight(sptr_t height); - void rGBAImageSetScale(sptr_t scalePercent); - void markerDefineRGBAImage(sptr_t markerNumber, const char * pixels); - void registerRGBAImage(sptr_t type, const char * pixels); - void scrollToStart(); - void scrollToEnd(); - void setTechnology(sptr_t technology); - sptr_t technology() const; - sptr_t createLoader(sptr_t bytes); - void findIndicatorShow(sptr_t start, sptr_t end); - void findIndicatorFlash(sptr_t start, sptr_t end); - void findIndicatorHide(); - void vCHomeDisplay(); - void vCHomeDisplayExtend(); - bool caretLineVisibleAlways() const; - void setCaretLineVisibleAlways(bool alwaysVisible); - void setLineEndTypesAllowed(sptr_t lineEndBitSet); - sptr_t lineEndTypesAllowed() const; - sptr_t lineEndTypesActive() const; - void setRepresentation(const char * encodedCharacter, const char * representation); - QByteArray representation(const char * encodedCharacter) const; - void clearRepresentation(const char * encodedCharacter); - void startRecord(); - void stopRecord(); - void setLexer(sptr_t lexer); - sptr_t lexer() const; - void colourise(sptr_t start, sptr_t end); - void setProperty(const char * key, const char * value); - void setKeyWords(sptr_t keyWordSet, const char * keyWords); - void setLexerLanguage(const char * language); - void loadLexerLibrary(const char * path); - QByteArray property(const char * key) const; - QByteArray propertyExpanded(const char * key) const; - sptr_t propertyInt(const char * key, sptr_t defaultValue) const; - sptr_t styleBitsNeeded() const; - QByteArray lexerLanguage() const; - sptr_t privateLexerCall(sptr_t operation, sptr_t pointer); - QByteArray propertyNames(); - sptr_t propertyType(const char * name); - QByteArray describeProperty(const char * name); - QByteArray describeKeyWordSets(); - sptr_t lineEndTypesSupported() const; - sptr_t allocateSubStyles(sptr_t styleBase, sptr_t numberStyles); - sptr_t subStylesStart(sptr_t styleBase) const; - sptr_t subStylesLength(sptr_t styleBase) const; - sptr_t styleFromSubStyle(sptr_t subStyle) const; - sptr_t primaryStyleFromStyle(sptr_t style) const; - void freeSubStyles(); - void setIdentifiers(sptr_t style, const char * identifiers); - sptr_t distanceToSecondaryStyles() const; - QByteArray subStyleBases() const; -/* --Autogenerated -- end of section automatically generated from Scintilla.iface */ - -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#if defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif - -#endif /* SCINTILLAEDIT_H */ diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp deleted file mode 100644 index cfc8b9837..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.cpp +++ /dev/null @@ -1,1339 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// Scintilla platform layer for Qt - -#include "PlatQt.h" -#include "Scintilla.h" -#include "FontQuality.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -//---------------------------------------------------------------------- - -// Convert from a Scintilla characterSet value to a Qt codec name. -const char *CharacterSetID(int characterSet) -{ - switch (characterSet) { - //case SC_CHARSET_ANSI: - // return ""; - case SC_CHARSET_DEFAULT: - return "ISO 8859-1"; - case SC_CHARSET_BALTIC: - return "ISO 8859-13"; - case SC_CHARSET_CHINESEBIG5: - return "Big5"; - case SC_CHARSET_EASTEUROPE: - return "ISO 8859-2"; - case SC_CHARSET_GB2312: - return "GB18030-0"; - case SC_CHARSET_GREEK: - return "ISO 8859-7"; - case SC_CHARSET_HANGUL: - return "CP949"; - case SC_CHARSET_MAC: - return "Apple Roman"; - //case SC_CHARSET_OEM: - // return "ASCII"; - case SC_CHARSET_RUSSIAN: - return "KOI8-R"; - case SC_CHARSET_CYRILLIC: - return "Windows-1251"; - case SC_CHARSET_SHIFTJIS: - return "Shift-JIS"; - //case SC_CHARSET_SYMBOL: - // return ""; - case SC_CHARSET_TURKISH: - return "ISO 8859-9"; - //case SC_CHARSET_JOHAB: - // return "CP1361"; - case SC_CHARSET_HEBREW: - return "ISO 8859-8"; - case SC_CHARSET_ARABIC: - return "ISO 8859-6"; - case SC_CHARSET_VIETNAMESE: - return "Windows-1258"; - case SC_CHARSET_THAI: - return "TIS-620"; - case SC_CHARSET_8859_15: - return "ISO 8859-15"; - default: - return "ISO 8859-1"; - } -} - -class FontAndCharacterSet { -public: - int characterSet; - QFont *pfont; - FontAndCharacterSet(int characterSet_, QFont *pfont): - characterSet(characterSet_), pfont(pfont) { - } - ~FontAndCharacterSet() { - delete pfont; - pfont = 0; - } -}; - -static int FontCharacterSet(Font &f) -{ - return reinterpret_cast(f.GetID())->characterSet; -} - -static QFont *FontPointer(Font &f) -{ - return reinterpret_cast(f.GetID())->pfont; -} - -Font::Font() : fid(0) {} - -Font::~Font() -{ - delete reinterpret_cast(fid); - fid = 0; -} - -static QFont::StyleStrategy ChooseStrategy(int eff) -{ - switch (eff) { - case SC_EFF_QUALITY_DEFAULT: return QFont::PreferDefault; - case SC_EFF_QUALITY_NON_ANTIALIASED: return QFont::NoAntialias; - case SC_EFF_QUALITY_ANTIALIASED: return QFont::PreferAntialias; - case SC_EFF_QUALITY_LCD_OPTIMIZED: return QFont::PreferAntialias; - default: return QFont::PreferDefault; - } -} - -void Font::Create(const FontParameters &fp) -{ - Release(); - - QFont *font = new QFont; - font->setStyleStrategy(ChooseStrategy(fp.extraFontFlag)); - font->setFamily(QString::fromUtf8(fp.faceName)); - font->setPointSize(fp.size); - font->setBold(fp.weight > 500); - font->setItalic(fp.italic); - - fid = new FontAndCharacterSet(fp.characterSet, font); -} - -void Font::Release() -{ - if (fid) - delete reinterpret_cast(fid); - - fid = 0; -} - - -SurfaceImpl::SurfaceImpl() -: device(0), painter(0), deviceOwned(false), painterOwned(false), x(0), y(0), - unicodeMode(false), codePage(0), codecName(0), codec(0) -{} - -SurfaceImpl::~SurfaceImpl() -{ - Release(); -} - -void SurfaceImpl::Init(WindowID wid) -{ - Release(); - device = static_cast(wid); -} - -void SurfaceImpl::Init(SurfaceID sid, WindowID /*wid*/) -{ - Release(); - device = static_cast(sid); -} - -void SurfaceImpl::InitPixMap(int width, - int height, - Surface *surface, - WindowID /*wid*/) -{ - Release(); - if (width < 1) width = 1; - if (height < 1) height = 1; - deviceOwned = true; - device = new QPixmap(width, height); - SurfaceImpl *psurfOther = static_cast(surface); - SetUnicodeMode(psurfOther->unicodeMode); - SetDBCSMode(psurfOther->codePage); -} - -void SurfaceImpl::Release() -{ - if (painterOwned && painter) { - delete painter; - } - - if (deviceOwned && device) { - delete device; - } - - device = 0; - painter = 0; - deviceOwned = false; - painterOwned = false; -} - -bool SurfaceImpl::Initialised() -{ - return device != 0; -} - -void SurfaceImpl::PenColour(ColourDesired fore) -{ - QPen penOutline(QColorFromCA(fore)); - penOutline.setCapStyle(Qt::FlatCap); - GetPainter()->setPen(penOutline); -} - -void SurfaceImpl::BrushColour(ColourDesired back) -{ - GetPainter()->setBrush(QBrush(QColorFromCA(back))); -} - -void SurfaceImpl::SetCodec(Font &font) -{ - if (font.GetID()) { - const char *csid = "UTF-8"; - if (!unicodeMode) - csid = CharacterSetID(FontCharacterSet(font)); - if (csid != codecName) { - codecName = csid; - codec = QTextCodec::codecForName(csid); - } - } -} - -void SurfaceImpl::SetFont(Font &font) -{ - if (font.GetID()) { - GetPainter()->setFont(*FontPointer(font)); - SetCodec(font); - } -} - -int SurfaceImpl::LogPixelsY() -{ - return device->logicalDpiY(); -} - -int SurfaceImpl::DeviceHeightFont(int points) -{ - return points; -} - -void SurfaceImpl::MoveTo(int x_, int y_) -{ - x = x_; - y = y_; -} - -void SurfaceImpl::LineTo(int x_, int y_) -{ - QLineF line(x, y, x_, y_); - GetPainter()->drawLine(line); - x = x_; - y = y_; -} - -void SurfaceImpl::Polygon(Point *pts, - int npts, - ColourDesired fore, - ColourDesired back) -{ - PenColour(fore); - BrushColour(back); - - QPoint *qpts = new QPoint[npts]; - for (int i = 0; i < npts; i++) { - qpts[i] = QPoint(pts[i].x, pts[i].y); - } - - GetPainter()->drawPolygon(qpts, npts); - delete [] qpts; -} - -void SurfaceImpl::RectangleDraw(PRectangle rc, - ColourDesired fore, - ColourDesired back) -{ - PenColour(fore); - BrushColour(back); - QRectF rect(rc.left, rc.top, rc.Width() - 1, rc.Height() - 1); - GetPainter()->drawRect(rect); -} - -void SurfaceImpl::FillRectangle(PRectangle rc, ColourDesired back) -{ - GetPainter()->fillRect(QRectFFromPRect(rc), QColorFromCA(back)); -} - -void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) -{ - // Tile pattern over rectangle - SurfaceImpl *surface = static_cast(&surfacePattern); - // Currently assumes 8x8 pattern - int widthPat = 8; - int heightPat = 8; - for (int xTile = rc.left; xTile < rc.right; xTile += widthPat) { - int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat; - for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) { - int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat; - QRect source(0, 0, widthx, heighty); - QRect target(xTile, yTile, widthx, heighty); - QPixmap *pixmap = static_cast(surface->GetPaintDevice()); - GetPainter()->drawPixmap(target, *pixmap, source); - } - } -} - -void SurfaceImpl::RoundedRectangle(PRectangle rc, - ColourDesired fore, - ColourDesired back) -{ - PenColour(fore); - BrushColour(back); - GetPainter()->drawRoundRect(QRectFFromPRect(rc)); -} - -void SurfaceImpl::AlphaRectangle(PRectangle rc, - int cornerSize, - ColourDesired fill, - int alphaFill, - ColourDesired outline, - int alphaOutline, - int /*flags*/) -{ - QColor qOutline = QColorFromCA(outline); - qOutline.setAlpha(alphaOutline); - GetPainter()->setPen(QPen(qOutline)); - - QColor qFill = QColorFromCA(fill); - qFill.setAlpha(alphaFill); - GetPainter()->setBrush(QBrush(qFill)); - - // A radius of 1 shows no curve so add 1 - qreal radius = cornerSize+1; - QRectF rect(rc.left, rc.top, rc.Width() - 1, rc.Height() - 1); - GetPainter()->drawRoundedRect(rect, radius, radius); -} - -static std::vector ImageByteSwapped(int width, int height, const unsigned char *pixelsImage) -{ - // Input is RGBA, but Format_ARGB32 is BGRA, so swap the red bytes and blue bytes - size_t bytes = width * height * 4; - std::vector imageBytes(pixelsImage, pixelsImage+bytes); - for (size_t i=0; i imageBytes = ImageByteSwapped(width, height, pixelsImage); - QImage image(&imageBytes[0], width, height, QImage::Format_ARGB32); - QPoint pt(rc.left, rc.top); - GetPainter()->drawImage(pt, image); -} - -void SurfaceImpl::Ellipse(PRectangle rc, - ColourDesired fore, - ColourDesired back) -{ - PenColour(fore); - BrushColour(back); - GetPainter()->drawEllipse(QRectFFromPRect(rc)); -} - -void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) -{ - SurfaceImpl *source = static_cast(&surfaceSource); - QPixmap *pixmap = static_cast(source->GetPaintDevice()); - - GetPainter()->drawPixmap(rc.left, rc.top, *pixmap, from.x, from.y, -1, -1); -} - -void SurfaceImpl::DrawTextNoClip(PRectangle rc, - Font &font, - XYPOSITION ybase, - const char *s, - int len, - ColourDesired fore, - ColourDesired back) -{ - SetFont(font); - PenColour(fore); - - GetPainter()->setBackground(QColorFromCA(back)); - GetPainter()->setBackgroundMode(Qt::OpaqueMode); - QString su = codec->toUnicode(s, len); - GetPainter()->drawText(QPointF(rc.left, ybase), su); -} - -void SurfaceImpl::DrawTextClipped(PRectangle rc, - Font &font, - XYPOSITION ybase, - const char *s, - int len, - ColourDesired fore, - ColourDesired back) -{ - SetClip(rc); - DrawTextNoClip(rc, font, ybase, s, len, fore, back); - GetPainter()->setClipping(false); -} - -void SurfaceImpl::DrawTextTransparent(PRectangle rc, - Font &font, - XYPOSITION ybase, - const char *s, - int len, - ColourDesired fore) -{ - SetFont(font); - PenColour(fore); - - GetPainter()->setBackgroundMode(Qt::TransparentMode); - QString su = codec->toUnicode(s, len); - GetPainter()->drawText(QPointF(rc.left, ybase), su); -} - -void SurfaceImpl::SetClip(PRectangle rc) -{ - GetPainter()->setClipRect(QRectFFromPRect(rc)); -} - -static size_t utf8LengthFromLead(unsigned char uch) -{ - if (uch >= (0x80 + 0x40 + 0x20 + 0x10)) { - return 4; - } else if (uch >= (0x80 + 0x40 + 0x20)) { - return 3; - } else if (uch >= (0x80)) { - return 2; - } else { - return 1; - } -} - -void SurfaceImpl::MeasureWidths(Font &font, - const char *s, - int len, - XYPOSITION *positions) -{ - if (!font.GetID()) - return; - SetCodec(font); - QString su = codec->toUnicode(s, len); - QTextLayout tlay(su, *FontPointer(font), GetPaintDevice()); - tlay.beginLayout(); - QTextLine tl = tlay.createLine(); - tlay.endLayout(); - if (unicodeMode) { - int fit = su.size(); - int ui=0; - const unsigned char *us = reinterpret_cast(s); - int i=0; - while (ui 0) - lastPos = positions[i-1]; - while (itoUnicode(s, len); - return metrics.width(string); -} - -XYPOSITION SurfaceImpl::WidthChar(Font &font, char ch) -{ - QFontMetricsF metrics(*FontPointer(font), device); - return metrics.width(QChar::fromLatin1(ch)); -} - -XYPOSITION SurfaceImpl::Ascent(Font &font) -{ - QFontMetricsF metrics(*FontPointer(font), device); - return metrics.ascent(); -} - -XYPOSITION SurfaceImpl::Descent(Font &font) -{ - QFontMetricsF metrics(*FontPointer(font), device); - // Qt returns 1 less than true descent - // See: QFontEngineWin::descent which says: - // ### we subtract 1 to even out the historical +1 in QFontMetrics's - // ### height=asc+desc+1 equation. Fix in Qt5. - return metrics.descent() + 1; -} - -XYPOSITION SurfaceImpl::InternalLeading(Font & /* font */) -{ - return 0; -} - -XYPOSITION SurfaceImpl::ExternalLeading(Font &font) -{ - QFontMetricsF metrics(*FontPointer(font), device); - return metrics.leading(); -} - -XYPOSITION SurfaceImpl::Height(Font &font) -{ - QFontMetricsF metrics(*FontPointer(font), device); - return metrics.height(); -} - -XYPOSITION SurfaceImpl::AverageCharWidth(Font &font) -{ - QFontMetricsF metrics(*FontPointer(font), device); - return metrics.averageCharWidth(); -} - -void SurfaceImpl::FlushCachedState() -{ - if (device->paintingActive()) { - GetPainter()->setPen(QPen()); - GetPainter()->setBrush(QBrush()); - } -} - -void SurfaceImpl::SetUnicodeMode(bool unicodeMode_) -{ - unicodeMode=unicodeMode_; -} - -void SurfaceImpl::SetDBCSMode(int codePage_) -{ - codePage = codePage_; -} - -QPaintDevice *SurfaceImpl::GetPaintDevice() -{ - return device; -} - -QPainter *SurfaceImpl::GetPainter() -{ - Q_ASSERT(device); - - if (painter == 0) { - if (device->paintingActive()) { - painter = device->paintEngine()->painter(); - } else { - painterOwned = true; - painter = new QPainter(device); - } - - // Set text antialiasing unconditionally. - // The font's style strategy will override. - painter->setRenderHint(QPainter::TextAntialiasing, true); - } - - return painter; -} - -Surface *Surface::Allocate(int) -{ - return new SurfaceImpl; -} - - -//---------------------------------------------------------------------- - -namespace { -QWidget *window(WindowID wid) -{ - return static_cast(wid); -} -} - -Window::~Window() {} - -void Window::Destroy() -{ - if (wid) - delete window(wid); - - wid = 0; -} - -bool Window::HasFocus() -{ - return wid ? window(wid)->hasFocus() : false; -} - -PRectangle Window::GetPosition() -{ - // Before any size allocated pretend its 1000 wide so not scrolled - return wid ? PRectFromQRect(window(wid)->frameGeometry()) : PRectangle(0, 0, 1000, 1000); -} - -void Window::SetPosition(PRectangle rc) -{ - if (wid) - window(wid)->setGeometry(QRectFromPRect(rc)); -} - -void Window::SetPositionRelative(PRectangle rc, Window relativeTo) -{ - QPoint oPos = window(relativeTo.wid)->mapToGlobal(QPoint(0,0)); - int ox = oPos.x(); - int oy = oPos.y(); - ox += rc.left; - oy += rc.top; - - QDesktopWidget *desktop = QApplication::desktop(); - QRect rectDesk = desktop->availableGeometry(QPoint(ox, oy)); - /* do some corrections to fit into screen */ - int sizex = rc.right - rc.left; - int sizey = rc.bottom - rc.top; - int screenWidth = rectDesk.width(); - if (ox < rectDesk.x()) - ox = rectDesk.x(); - if (sizex > screenWidth) - ox = rectDesk.x(); /* the best we can do */ - else if (ox + sizex > rectDesk.right()) - ox = rectDesk.right() - sizex; - if (oy + sizey > rectDesk.bottom()) - oy = rectDesk.bottom() - sizey; - - Q_ASSERT(wid); - window(wid)->move(ox, oy); - window(wid)->resize(sizex, sizey); -} - -PRectangle Window::GetClientPosition() -{ - // The client position is the window position - return GetPosition(); -} - -void Window::Show(bool show) -{ - if (wid) - window(wid)->setVisible(show); -} - -void Window::InvalidateAll() -{ - if (wid) - window(wid)->update(); -} - -void Window::InvalidateRectangle(PRectangle rc) -{ - if (wid) - window(wid)->update(QRectFromPRect(rc)); -} - -void Window::SetFont(Font &font) -{ - if (wid) - window(wid)->setFont(*FontPointer(font)); -} - -void Window::SetCursor(Cursor curs) -{ - if (wid) { - Qt::CursorShape shape; - - switch (curs) { - case cursorText: shape = Qt::IBeamCursor; break; - case cursorArrow: shape = Qt::ArrowCursor; break; - case cursorUp: shape = Qt::UpArrowCursor; break; - case cursorWait: shape = Qt::WaitCursor; break; - case cursorHoriz: shape = Qt::SizeHorCursor; break; - case cursorVert: shape = Qt::SizeVerCursor; break; - case cursorHand: shape = Qt::PointingHandCursor; break; - default: shape = Qt::ArrowCursor; break; - } - - QCursor cursor = QCursor(shape); - - if (curs != cursorLast) { - window(wid)->setCursor(cursor); - cursorLast = curs; - } - } -} - -void Window::SetTitle(const char *s) -{ - if (wid) - window(wid)->setWindowTitle(QString::fromUtf8(s)); -} - -/* Returns rectangle of monitor pt is on, both rect and pt are in Window's - window coordinates */ -PRectangle Window::GetMonitorRect(Point pt) -{ - QPoint originGlobal = window(wid)->mapToGlobal(QPoint(0, 0)); - QPoint posGlobal = window(wid)->mapToGlobal(QPoint(pt.x, pt.y)); - QDesktopWidget *desktop = QApplication::desktop(); - QRect rectScreen = desktop->availableGeometry(posGlobal); - rectScreen.translate(-originGlobal.x(), -originGlobal.y()); - return PRectangle(rectScreen.left(), rectScreen.top(), - rectScreen.right(), rectScreen.bottom()); -} - - -//---------------------------------------------------------------------- - -class ListBoxImpl : public ListBox { -public: - ListBoxImpl(); - ~ListBoxImpl(); - - virtual void SetFont(Font &font); - virtual void Create(Window &parent, int ctrlID, Point location, - int lineHeight, bool unicodeMode, int technology); - virtual void SetAverageCharWidth(int width); - virtual void SetVisibleRows(int rows); - virtual int GetVisibleRows() const; - virtual PRectangle GetDesiredRect(); - virtual int CaretFromEdge(); - virtual void Clear(); - virtual void Append(char *s, int type = -1); - virtual int Length(); - virtual void Select(int n); - virtual int GetSelection(); - virtual int Find(const char *prefix); - virtual void GetValue(int n, char *value, int len); - virtual void RegisterImage(int type, const char *xpmData); - virtual void RegisterRGBAImage(int type, int width, int height, - const unsigned char *pixelsImage); - virtual void RegisterQPixmapImage(int type, const QPixmap& pm); - virtual void ClearRegisteredImages(); - virtual void SetDoubleClickAction(CallBackAction action, void *data); - virtual void SetList(const char *list, char separator, char typesep); -private: - bool unicodeMode; - int visibleRows; - QMap images; -}; - -class ListWidget : public QListWidget { -public: - explicit ListWidget(QWidget *parent); - virtual ~ListWidget(); - - void setDoubleClickAction(CallBackAction action, void *data); - -protected: - virtual void mouseDoubleClickEvent(QMouseEvent *event); - virtual QStyleOptionViewItem viewOptions() const; - -private: - CallBackAction doubleClickAction; - void *doubleClickActionData; -}; - - -ListBoxImpl::ListBoxImpl() -: unicodeMode(false), visibleRows(5) -{} - -ListBoxImpl::~ListBoxImpl() {} - -void ListBoxImpl::Create(Window &parent, - int /*ctrlID*/, - Point location, - int /*lineHeight*/, - bool unicodeMode_, - int) -{ - unicodeMode = unicodeMode_; - - QWidget *qparent = static_cast(parent.GetID()); - ListWidget *list = new ListWidget(qparent); - -#if defined(Q_OS_WIN) - // On Windows, Qt::ToolTip causes a crash when the list is clicked on - // so Qt::Tool is used. - list->setParent(0, Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - | Qt::WindowDoesNotAcceptFocus -#endif - ); -#else - // On OS X, Qt::Tool takes focus so main window loses focus so - // keyboard stops working. Qt::ToolTip works but its only really - // documented for tooltips. - // On Linux / X this setting allows clicking on list items. - list->setParent(0, Qt::ToolTip | Qt::FramelessWindowHint); -#endif - list->setAttribute(Qt::WA_ShowWithoutActivating); - list->setFocusPolicy(Qt::NoFocus); - list->setUniformItemSizes(true); - list->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - list->move(location.x, location.y); - - int maxIconWidth = 0; - int maxIconHeight = 0; - foreach (QPixmap im, images) { - if (maxIconWidth < im.width()) - maxIconWidth = im.width(); - if (maxIconHeight < im.height()) - maxIconHeight = im.height(); - } - list->setIconSize(QSize(maxIconWidth, maxIconHeight)); - - wid = list; -} - -void ListBoxImpl::SetFont(Font &font) -{ - ListWidget *list = static_cast(wid); - list->setFont(*FontPointer(font)); -} - -void ListBoxImpl::SetAverageCharWidth(int /*width*/) {} - -void ListBoxImpl::SetVisibleRows(int rows) -{ - visibleRows = rows; -} - -int ListBoxImpl::GetVisibleRows() const -{ - return visibleRows; -} - -PRectangle ListBoxImpl::GetDesiredRect() -{ - ListWidget *list = static_cast(wid); - - int rows = Length(); - if (rows == 0 || rows > visibleRows) { - rows = visibleRows; - } - int rowHeight = list->sizeHintForRow(0); - int height = (rows * rowHeight) + (2 * list->frameWidth()); - - QStyle *style = QApplication::style(); - int width = list->sizeHintForColumn(0) + (2 * list->frameWidth()); - if (Length() > rows) { - width += style->pixelMetric(QStyle::PM_ScrollBarExtent); - } - - return PRectangle(0, 0, width, height); -} - -int ListBoxImpl::CaretFromEdge() -{ - ListWidget *list = static_cast(wid); - - int maxIconWidth = 0; - foreach (QPixmap im, images) { - if (maxIconWidth < im.width()) - maxIconWidth = im.width(); - } - - int extra; - // The 12 is from trial and error on OS X and the 7 - // is from trial and error on Windows - there may be - // a better programmatic way to find any padding factors. -#ifdef Q_OS_DARWIN - extra = 12; -#else - extra = 7; -#endif - return maxIconWidth + (2 * list->frameWidth()) + extra; -} - -void ListBoxImpl::Clear() -{ - ListWidget *list = static_cast(wid); - list->clear(); -} - -void ListBoxImpl::Append(char *s, int type) -{ - ListWidget *list = static_cast(wid); - - QString str = unicodeMode ? QString::fromUtf8(s) : QString::fromLocal8Bit(s); - QIcon icon; - if (type >= 0) { - Q_ASSERT(images.contains(type)); - icon = images.value(type); - } - new QListWidgetItem(icon, str, list); -} - -int ListBoxImpl::Length() -{ - ListWidget *list = static_cast(wid); - return list->count(); -} - -void ListBoxImpl::Select(int n) -{ - ListWidget *list = static_cast(wid); - QModelIndex index = list->model()->index(n, 0); - if (index.isValid()) { - QRect row_rect = list->visualRect(index); - if (!list->viewport()->rect().contains(row_rect)) { - list->scrollTo(index, QAbstractItemView::PositionAtTop); - } - } - list->setCurrentRow(n); -} - -int ListBoxImpl::GetSelection() -{ - ListWidget *list = static_cast(wid); - return list->currentRow(); -} - -int ListBoxImpl::Find(const char *prefix) -{ - ListWidget *list = static_cast(wid); - QString sPrefix = unicodeMode ? QString::fromUtf8(prefix) : QString::fromLocal8Bit(prefix); - QList ms = list->findItems(sPrefix, Qt::MatchStartsWith); - - int result = -1; - if (!ms.isEmpty()) { - result = list->row(ms.first()); - } - - return result; -} - -void ListBoxImpl::GetValue(int n, char *value, int len) -{ - ListWidget *list = static_cast(wid); - QListWidgetItem *item = list->item(n); - QString str = item->data(Qt::DisplayRole).toString(); - QByteArray bytes = unicodeMode ? str.toUtf8() : str.toLocal8Bit(); - - strncpy(value, bytes.constData(), len); - value[len-1] = '\0'; -} - -void ListBoxImpl::RegisterQPixmapImage(int type, const QPixmap& pm) -{ - images[type] = pm; - - ListWidget *list = static_cast(wid); - if (list != NULL) { - QSize iconSize = list->iconSize(); - if (pm.width() > iconSize.width() || pm.height() > iconSize.height()) - list->setIconSize(QSize(qMax(pm.width(), iconSize.width()), - qMax(pm.height(), iconSize.height()))); - } - -} - -void ListBoxImpl::RegisterImage(int type, const char *xpmData) -{ - RegisterQPixmapImage(type, QPixmap(reinterpret_cast(xpmData))); -} - -void ListBoxImpl::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) -{ - std::vector imageBytes = ImageByteSwapped(width, height, pixelsImage); - QImage image(&imageBytes[0], width, height, QImage::Format_ARGB32); - RegisterQPixmapImage(type, QPixmap::fromImage(image)); -} - -void ListBoxImpl::ClearRegisteredImages() -{ - images.clear(); - - ListWidget *list = static_cast(wid); - if (list != NULL) - list->setIconSize(QSize(0, 0)); -} - -void ListBoxImpl::SetDoubleClickAction(CallBackAction action, void *data) -{ - ListWidget *list = static_cast(wid); - list->setDoubleClickAction(action, data); -} - -void ListBoxImpl::SetList(const char *list, char separator, char typesep) -{ - // This method is *not* platform dependent. - // It is borrowed from the GTK implementation. - Clear(); - size_t count = strlen(list) + 1; - std::vector words(list, list+count); - char *startword = &words[0]; - char *numword = NULL; - int i = 0; - for (; words[i]; i++) { - if (words[i] == separator) { - words[i] = '\0'; - if (numword) - *numword = '\0'; - Append(startword, numword?atoi(numword + 1):-1); - startword = &words[0] + i + 1; - numword = NULL; - } else if (words[i] == typesep) { - numword = &words[0] + i; - } - } - if (startword) { - if (numword) - *numword = '\0'; - Append(startword, numword?atoi(numword + 1):-1); - } -} - -ListBox::ListBox() {} - -ListBox::~ListBox() {} - -ListBox *ListBox::Allocate() -{ - return new ListBoxImpl(); -} - -ListWidget::ListWidget(QWidget *parent) -: QListWidget(parent), doubleClickAction(0), doubleClickActionData(0) -{} - -ListWidget::~ListWidget() {} - -void ListWidget::setDoubleClickAction(CallBackAction action, void *data) -{ - doubleClickAction = action; - doubleClickActionData = data; -} - -void ListWidget::mouseDoubleClickEvent(QMouseEvent * /* event */) -{ - if (doubleClickAction != 0) { - doubleClickAction(doubleClickActionData); - } -} - -QStyleOptionViewItem ListWidget::viewOptions() const -{ - QStyleOptionViewItem result = QListWidget::viewOptions(); - result.state |= QStyle::State_Active; - return result; -} - -//---------------------------------------------------------------------- - -Menu::Menu() : mid(0) {} - -void Menu::CreatePopUp() -{ - Destroy(); - mid = new QMenu(); -} - -void Menu::Destroy() -{ - if (mid) { - QMenu *menu = static_cast(mid); - delete menu; - } - mid = 0; -} - -void Menu::Show(Point pt, Window & /*w*/) -{ - QMenu *menu = static_cast(mid); - menu->exec(QPoint(pt.x, pt.y)); - Destroy(); -} - -//---------------------------------------------------------------------- - -class DynamicLibraryImpl : public DynamicLibrary { -protected: - QLibrary *lib; -public: - explicit DynamicLibraryImpl(const char *modulePath) { - QString path = QString::fromUtf8(modulePath); - lib = new QLibrary(path); - } - - virtual ~DynamicLibraryImpl() { - if (lib) - lib->unload(); - lib = 0; - } - - virtual Function FindFunction(const char *name) { - if (lib) { - // C++ standard doesn't like casts between function pointers and void pointers so use a union - union { -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) - QFunctionPointer fp; -#else - void *fp; -#endif - Function f; - } fnConv; - fnConv.fp = lib->resolve(name); - return fnConv.f; - } - return NULL; - } - - virtual bool IsValid() { - return lib != NULL; - } -}; - -DynamicLibrary *DynamicLibrary::Load(const char *modulePath) -{ - return static_cast(new DynamicLibraryImpl(modulePath)); -} - -ColourDesired Platform::Chrome() -{ - QColor c(Qt::gray); - return ColourDesired(c.red(), c.green(), c.blue()); -} - -ColourDesired Platform::ChromeHighlight() -{ - QColor c(Qt::lightGray); - return ColourDesired(c.red(), c.green(), c.blue()); -} - -const char *Platform::DefaultFont() -{ - static char fontNameDefault[200] = ""; - if (!fontNameDefault[0]) { - QFont font = QApplication::font(); - strcpy(fontNameDefault, font.family().toUtf8()); - } - return fontNameDefault; -} - -int Platform::DefaultFontSize() -{ - QFont font = QApplication::font(); - return font.pointSize(); -} - -unsigned int Platform::DoubleClickTime() -{ - return QApplication::doubleClickInterval(); -} - -bool Platform::MouseButtonBounce() -{ - return false; -} - -bool Platform::IsKeyDown(int /*key*/) -{ - return false; -} - -long Platform::SendScintilla(WindowID /*w*/, - unsigned int /*msg*/, - unsigned long /*wParam*/, - long /*lParam*/) -{ - return 0; -} - -long Platform::SendScintillaPointer(WindowID /*w*/, - unsigned int /*msg*/, - unsigned long /*wParam*/, - void * /*lParam*/) -{ - return 0; -} - -int Platform::Minimum(int a, int b) -{ - return qMin(a, b); -} - -int Platform::Maximum(int a, int b) -{ - return qMax(a, b); -} - -int Platform::Clamp(int val, int minVal, int maxVal) -{ - return qBound(minVal, val, maxVal); -} - -void Platform::DebugDisplay(const char *s) -{ - qWarning("Scintilla: %s", s); -} - -void Platform::DebugPrintf(const char *format, ...) -{ - char buffer[2000]; - va_list pArguments; - va_start(pArguments, format); - vsprintf(buffer, format, pArguments); - va_end(pArguments); - Platform::DebugDisplay(buffer); -} - -bool Platform::ShowAssertionPopUps(bool /*assertionPopUps*/) -{ - return false; -} - -void Platform::Assert(const char *c, const char *file, int line) -{ - char buffer[2000]; - sprintf(buffer, "Assertion [%s] failed at %s %d", c, file, line); - if (Platform::ShowAssertionPopUps(false)) { - QMessageBox mb(QStringLiteral("Assertion Failure"), QString::fromUtf8(buffer), QMessageBox::NoIcon, - QMessageBox::Ok, QMessageBox::NoButton, QMessageBox::NoButton); - mb.exec(); - } else { - strcat(buffer, "\n"); - Platform::DebugDisplay(buffer); - } -} - - -bool Platform::IsDBCSLeadByte(int codePage, char ch) -{ - // Byte ranges found in Wikipedia articles with relevant search strings in each case - unsigned char uch = static_cast(ch); - switch (codePage) { - case 932: - // Shift_jis - return ((uch >= 0x81) && (uch <= 0x9F)) || - ((uch >= 0xE0) && (uch <= 0xEF)); - case 936: - // GBK - return (uch >= 0x81) && (uch <= 0xFE); - case 949: - // Korean Wansung KS C-5601-1987 - return (uch >= 0x81) && (uch <= 0xFE); - case 950: - // Big5 - return (uch >= 0x81) && (uch <= 0xFE); - case 1361: - // Korean Johab KS C-5601-1992 - return - ((uch >= 0x84) && (uch <= 0xD3)) || - ((uch >= 0xD8) && (uch <= 0xDE)) || - ((uch >= 0xE0) && (uch <= 0xF9)); - } - return false; -} - -int Platform::DBCSCharLength(int codePage, const char *s) -{ - if (codePage == 932 || codePage == 936 || codePage == 949 || - codePage == 950 || codePage == 1361) { - return IsDBCSLeadByte(codePage, s[0]) ? 2 : 1; - } else { - return 1; - } -} - -int Platform::DBCSCharMaxLength() -{ - return 2; -} - - -//---------------------------------------------------------------------- - -static QElapsedTimer timer; - -ElapsedTime::ElapsedTime() : bigBit(0), littleBit(0) -{ - if (!timer.isValid()) { - timer.start(); - } - qint64 ns64Now = timer.nsecsElapsed(); - bigBit = static_cast(ns64Now >> 32); - littleBit = static_cast(ns64Now & 0xFFFFFFFF); -} - -double ElapsedTime::Duration(bool reset) -{ - qint64 ns64Now = timer.nsecsElapsed(); - qint64 ns64Start = (static_cast(static_cast(bigBit)) << 32) + static_cast(littleBit); - double result = ns64Now - ns64Start; - if (reset) { - bigBit = static_cast(ns64Now >> 32); - littleBit = static_cast(ns64Now & 0xFFFFFFFF); - } - return result / 1000000000.0; // 1 billion nanoseconds in a second -} - -#ifdef SCI_NAMESPACE -} -#endif diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.h b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.h deleted file mode 100644 index be35d818b..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/PlatQt.h +++ /dev/null @@ -1,132 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// Scintilla platform layer for Qt - -#ifndef PLATQT_H -#define PLATQT_H - -#include "Platform.h" - -#include -#include -#include - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -const char *CharacterSetID(int characterSet); - -inline QColor QColorFromCA(ColourDesired ca) -{ - long c = ca.AsLong(); - return QColor(c & 0xff, (c >> 8) & 0xff, (c >> 16) & 0xff); -} - -inline QRect QRectFromPRect(PRectangle pr) -{ - return QRect(pr.left, pr.top, pr.Width(), pr.Height()); -} - -inline QRectF QRectFFromPRect(PRectangle pr) -{ - return QRectF(pr.left, pr.top, pr.Width(), pr.Height()); -} - -inline PRectangle PRectFromQRect(QRect qr) -{ - return PRectangle(qr.x(), qr.y(), qr.x() + qr.width(), qr.y() + qr.height()); -} - -inline Point PointFromQPoint(QPoint qp) -{ - return Point(qp.x(), qp.y()); -} - -class SurfaceImpl : public Surface { -private: - QPaintDevice *device; - QPainter *painter; - bool deviceOwned; - bool painterOwned; - float x, y; - bool unicodeMode; - int codePage; - const char *codecName; - QTextCodec *codec; - -public: - SurfaceImpl(); - virtual ~SurfaceImpl(); - - virtual void Init(WindowID wid); - virtual void Init(SurfaceID sid, WindowID wid); - virtual void InitPixMap(int width, int height, - Surface *surface, WindowID wid); - - virtual void Release(); - virtual bool Initialised(); - virtual void PenColour(ColourDesired fore); - virtual int LogPixelsY(); - virtual int DeviceHeightFont(int points); - virtual void MoveTo(int x, int y); - virtual void LineTo(int x, int y); - virtual void Polygon(Point *pts, int npts, ColourDesired fore, - ColourDesired back); - virtual void RectangleDraw(PRectangle rc, ColourDesired fore, - ColourDesired back); - virtual void FillRectangle(PRectangle rc, ColourDesired back); - virtual void FillRectangle(PRectangle rc, Surface &surfacePattern); - virtual void RoundedRectangle(PRectangle rc, ColourDesired fore, - ColourDesired back); - virtual void AlphaRectangle(PRectangle rc, int corner, ColourDesired fill, - int alphaFill, ColourDesired outline, int alphaOutline, int flags); - virtual void DrawRGBAImage(PRectangle rc, int width, int height, - const unsigned char *pixelsImage); - virtual void Ellipse(PRectangle rc, ColourDesired fore, - ColourDesired back); - virtual void Copy(PRectangle rc, Point from, Surface &surfaceSource); - - virtual void DrawTextNoClip(PRectangle rc, Font &font, XYPOSITION ybase, - const char *s, int len, ColourDesired fore, ColourDesired back); - virtual void DrawTextClipped(PRectangle rc, Font &font, XYPOSITION ybase, - const char *s, int len, ColourDesired fore, ColourDesired back); - virtual void DrawTextTransparent(PRectangle rc, Font &font, XYPOSITION ybase, - const char *s, int len, ColourDesired fore); - virtual void MeasureWidths(Font &font, const char *s, int len, - XYPOSITION *positions); - virtual XYPOSITION WidthText(Font &font, const char *s, int len); - virtual XYPOSITION WidthChar(Font &font, char ch); - virtual XYPOSITION Ascent(Font &font); - virtual XYPOSITION Descent(Font &font); - virtual XYPOSITION InternalLeading(Font &font); - virtual XYPOSITION ExternalLeading(Font &font); - virtual XYPOSITION Height(Font &font); - virtual XYPOSITION AverageCharWidth(Font &font); - - virtual void SetClip(PRectangle rc); - virtual void FlushCachedState(); - - virtual void SetUnicodeMode(bool unicodeMode); - virtual void SetDBCSMode(int codePage); - - void BrushColour(ColourDesired back); - void SetCodec(Font &font); - void SetFont(Font &font); - - QPaintDevice *GetPaintDevice(); - void SetPainter(QPainter *painter); - QPainter *GetPainter(); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.cpp b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.cpp deleted file mode 100644 index 03ecb4fdc..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.cpp +++ /dev/null @@ -1,793 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// ScintillaEditBase.cpp - Qt widget that wraps ScintillaQt and provides events and scrolling - -#include "ScintillaEditBase.h" -#include "ScintillaQt.h" -#include "PlatQt.h" - -#include -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -#include -#endif -#include -#include -#include -#include - -#define INDIC_INPUTMETHOD 24 - -#define MAXLENINPUTIME 200 -#define SC_INDICATOR_INPUT INDIC_IME -#define SC_INDICATOR_TARGET INDIC_IME+1 -#define SC_INDICATOR_CONVERTED INDIC_IME+2 -#define SC_INDICATOR_UNKNOWN INDIC_IME_MAX - -// Q_WS_MAC and Q_WS_X11 aren't defined in Qt5 -#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) -#ifdef Q_OS_MAC -#define Q_WS_MAC 1 -#endif - -#if !defined(Q_OS_MAC) && !defined(Q_OS_WIN) -#define Q_WS_X11 1 -#endif -#endif // QT_VERSION >= 5.0.0 - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -ScintillaEditBase::ScintillaEditBase(QWidget *parent) -: QAbstractScrollArea(parent), sqt(0), preeditPos(-1), wheelDelta(0) -{ - sqt = new ScintillaQt(this); - - time.start(); - - // Set Qt defaults. - setAcceptDrops(true); - setMouseTracking(true); - setAutoFillBackground(false); - setFrameStyle(QFrame::NoFrame); - setFocusPolicy(Qt::StrongFocus); - setAttribute(Qt::WA_StaticContents); - viewport()->setAutoFillBackground(false); - setAttribute(Qt::WA_KeyCompression); - setAttribute(Qt::WA_InputMethodEnabled); - - sqt->vs.indicators[SC_INDICATOR_UNKNOWN] = Indicator(INDIC_HIDDEN, ColourDesired(0, 0, 0xff)); - sqt->vs.indicators[SC_INDICATOR_INPUT] = Indicator(INDIC_DOTS, ColourDesired(0, 0, 0xff)); - sqt->vs.indicators[SC_INDICATOR_CONVERTED] = Indicator(INDIC_COMPOSITIONTHICK, ColourDesired(0, 0, 0xff)); - sqt->vs.indicators[SC_INDICATOR_TARGET] = Indicator(INDIC_STRAIGHTBOX, ColourDesired(0, 0, 0xff)); - - connect(sqt, SIGNAL(notifyParent(SCNotification)), - this, SLOT(notifyParent(SCNotification))); - - // Connect scroll bars. - connect(verticalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(scrollVertical(int))); - connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(scrollHorizontal(int))); - - // Connect pass-through signals. - connect(sqt, SIGNAL(horizontalRangeChanged(int,int)), - this, SIGNAL(horizontalRangeChanged(int,int))); - connect(sqt, SIGNAL(verticalRangeChanged(int,int)), - this, SIGNAL(verticalRangeChanged(int,int))); - connect(sqt, SIGNAL(horizontalScrolled(int)), - this, SIGNAL(horizontalScrolled(int))); - connect(sqt, SIGNAL(verticalScrolled(int)), - this, SIGNAL(verticalScrolled(int))); - - connect(sqt, SIGNAL(notifyChange()), - this, SIGNAL(notifyChange())); - - connect(sqt, SIGNAL(command(uptr_t, sptr_t)), - this, SLOT(event_command(uptr_t, sptr_t))); - - connect(sqt, SIGNAL(aboutToCopy(QMimeData *)), - this, SIGNAL(aboutToCopy(QMimeData *))); -} - -ScintillaEditBase::~ScintillaEditBase() {} - -sptr_t ScintillaEditBase::send( - unsigned int iMessage, - uptr_t wParam, - sptr_t lParam) const -{ - return sqt->WndProc(iMessage, wParam, lParam); -} - -sptr_t ScintillaEditBase::sends( - unsigned int iMessage, - uptr_t wParam, - const char *s) const -{ - return sqt->WndProc(iMessage, wParam, (sptr_t)s); -} - -void ScintillaEditBase::scrollHorizontal(int value) -{ - sqt->HorizontalScrollTo(value); -} - -void ScintillaEditBase::scrollVertical(int value) -{ - sqt->ScrollTo(value); -} - -bool ScintillaEditBase::event(QEvent *event) -{ - bool result = false; - - if (event->type() == QEvent::KeyPress) { - // Circumvent the tab focus convention. - keyPressEvent(static_cast(event)); - result = event->isAccepted(); - } else if (event->type() == QEvent::Show) { - setMouseTracking(true); - result = QAbstractScrollArea::event(event); - } else if (event->type() == QEvent::Hide) { - setMouseTracking(false); - result = QAbstractScrollArea::event(event); - } else { - result = QAbstractScrollArea::event(event); - } - - return result; -} - -void ScintillaEditBase::paintEvent(QPaintEvent *event) -{ - sqt->PartialPaint(PRectFromQRect(event->rect())); -} - -void ScintillaEditBase::wheelEvent(QWheelEvent *event) -{ - if (event->orientation() == Qt::Horizontal) { - if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) - event->ignore(); - else - QAbstractScrollArea::wheelEvent(event); - } else { - if (QApplication::keyboardModifiers() & Qt::ControlModifier) { - // Zoom! We play with the font sizes in the styles. - // Number of steps/line is ignored, we just care if sizing up or down - if (event->delta() > 0) { - sqt->KeyCommand(SCI_ZOOMIN); - } else { - sqt->KeyCommand(SCI_ZOOMOUT); - } - } else { - // Ignore wheel events when the scroll bars are disabled. - if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOff) { - event->ignore(); - } else { - // Scroll - QAbstractScrollArea::wheelEvent(event); - } - } - } -} - -void ScintillaEditBase::focusInEvent(QFocusEvent *event) -{ - sqt->SetFocusState(true); - emit updateUi(); - - QAbstractScrollArea::focusInEvent(event); -} - -void ScintillaEditBase::focusOutEvent(QFocusEvent *event) -{ - sqt->SetFocusState(false); - - QAbstractScrollArea::focusOutEvent(event); -} - -void ScintillaEditBase::resizeEvent(QResizeEvent *) -{ - sqt->ChangeSize(); - emit resized(); -} - -void ScintillaEditBase::keyPressEvent(QKeyEvent *event) -{ - // All keystrokes containing the meta modifier are - // assumed to be shortcuts not handled by scintilla. - if (QApplication::keyboardModifiers() & Qt::MetaModifier) { - QAbstractScrollArea::keyPressEvent(event); - emit keyPressed(event); - return; - } - - int key = 0; - switch (event->key()) { - case Qt::Key_Down: key = SCK_DOWN; break; - case Qt::Key_Up: key = SCK_UP; break; - case Qt::Key_Left: key = SCK_LEFT; break; - case Qt::Key_Right: key = SCK_RIGHT; break; - case Qt::Key_Home: key = SCK_HOME; break; - case Qt::Key_End: key = SCK_END; break; - case Qt::Key_PageUp: key = SCK_PRIOR; break; - case Qt::Key_PageDown: key = SCK_NEXT; break; - case Qt::Key_Delete: key = SCK_DELETE; break; - case Qt::Key_Insert: key = SCK_INSERT; break; - case Qt::Key_Escape: key = SCK_ESCAPE; break; - case Qt::Key_Backspace: key = SCK_BACK; break; - case Qt::Key_Plus: key = SCK_ADD; break; - case Qt::Key_Minus: key = SCK_SUBTRACT; break; - case Qt::Key_Backtab: // fall through - case Qt::Key_Tab: key = SCK_TAB; break; - case Qt::Key_Enter: // fall through - case Qt::Key_Return: key = SCK_RETURN; break; - case Qt::Key_Control: key = 0; break; - case Qt::Key_Alt: key = 0; break; - case Qt::Key_Shift: key = 0; break; - case Qt::Key_Meta: key = 0; break; - default: key = event->key(); break; - } - - bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier; - bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier; - bool alt = QApplication::keyboardModifiers() & Qt::AltModifier; - - bool consumed = false; - bool added = sqt->KeyDown(key, shift, ctrl, alt, &consumed) != 0; - if (!consumed) - consumed = added; - - if (!consumed) { - // Don't insert text if the control key was pressed unless - // it was pressed in conjunction with alt for AltGr emulation. - bool input = (!ctrl || alt); - - // Additionally, on non-mac platforms, don't insert text - // if the alt key was pressed unless control is also present. - // On mac alt can be used to insert special characters. -#ifndef Q_WS_MAC - input &= (!alt || ctrl); -#endif - - QString text = event->text(); - if (input && !text.isEmpty() && text[0].isPrint()) { - QByteArray utext = sqt->BytesForDocument(text); - sqt->AddCharUTF(utext.data(), utext.size()); - } else { - event->ignore(); - } - } - - emit keyPressed(event); -} - -#ifdef Q_WS_X11 -static int modifierTranslated(int sciModifier) -{ - switch (sciModifier) { - case SCMOD_SHIFT: - return Qt::ShiftModifier; - case SCMOD_CTRL: - return Qt::ControlModifier; - case SCMOD_ALT: - return Qt::AltModifier; - case SCMOD_SUPER: - return Qt::MetaModifier; - default: - return 0; - } -} -#endif - -void ScintillaEditBase::mousePressEvent(QMouseEvent *event) -{ - Point pos = PointFromQPoint(event->pos()); - - emit buttonPressed(event); - - if (event->button() == Qt::MidButton && - QApplication::clipboard()->supportsSelection()) { - SelectionPosition selPos = sqt->SPositionFromLocation( - pos, false, false, sqt->UserVirtualSpace()); - sqt->sel.Clear(); - sqt->SetSelection(selPos, selPos); - sqt->PasteFromMode(QClipboard::Selection); - return; - } - - if (event->button() == Qt::LeftButton) { - bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier; - bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier; -#ifdef Q_WS_X11 - // On X allow choice of rectangular modifier since most window - // managers grab alt + click for moving windows. - bool alt = QApplication::keyboardModifiers() & modifierTranslated(sqt->rectangularSelectionModifier); -#else - bool alt = QApplication::keyboardModifiers() & Qt::AltModifier; -#endif - - sqt->ButtonDown(pos, time.elapsed(), shift, ctrl, alt); - } - - if (event->button() == Qt::RightButton) { - bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier; - bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier; - bool alt = QApplication::keyboardModifiers() & Qt::AltModifier; - - sqt->RightButtonDownWithModifiers(pos, time.elapsed(), ScintillaQt::ModifierFlags(shift, ctrl, alt)); - } -} - -void ScintillaEditBase::mouseReleaseEvent(QMouseEvent *event) -{ - Point point = PointFromQPoint(event->pos()); - bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier; - if (event->button() == Qt::LeftButton) - sqt->ButtonUp(point, time.elapsed(), ctrl); - - int pos = send(SCI_POSITIONFROMPOINT, point.x, point.y); - int line = send(SCI_LINEFROMPOSITION, pos); - int modifiers = QApplication::keyboardModifiers(); - - emit textAreaClicked(line, modifiers); - emit buttonReleased(event); -} - -void ScintillaEditBase::mouseDoubleClickEvent(QMouseEvent *event) -{ - // Scintilla does its own double-click detection. - mousePressEvent(event); -} - -void ScintillaEditBase::mouseMoveEvent(QMouseEvent *event) -{ - Point pos = PointFromQPoint(event->pos()); - - bool shift = QApplication::keyboardModifiers() & Qt::ShiftModifier; - bool ctrl = QApplication::keyboardModifiers() & Qt::ControlModifier; -#ifdef Q_WS_X11 - // On X allow choice of rectangular modifier since most window - // managers grab alt + click for moving windows. - bool alt = QApplication::keyboardModifiers() & modifierTranslated(sqt->rectangularSelectionModifier); -#else - bool alt = QApplication::keyboardModifiers() & Qt::AltModifier; -#endif - - int modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) | (alt ? SCI_ALT : 0); - - sqt->ButtonMoveWithModifiers(pos, modifiers); -} - -void ScintillaEditBase::contextMenuEvent(QContextMenuEvent *event) -{ - Point pos = PointFromQPoint(event->globalPos()); - Point pt = PointFromQPoint(event->pos()); - if (!sqt->PointInSelection(pt)) { - sqt->SetEmptySelection(sqt->PositionFromLocation(pt)); - } - if (sqt->ShouldDisplayPopup(pt)) { - sqt->ContextMenu(pos); - } -} - -void ScintillaEditBase::dragEnterEvent(QDragEnterEvent *event) -{ - if (event->mimeData()->hasText()) { - event->acceptProposedAction(); - - Point point = PointFromQPoint(event->pos()); - sqt->DragEnter(point); - } else { - event->ignore(); - } -} - -void ScintillaEditBase::dragLeaveEvent(QDragLeaveEvent * /* event */) -{ - sqt->DragLeave(); -} - -void ScintillaEditBase::dragMoveEvent(QDragMoveEvent *event) -{ - if (event->mimeData()->hasText()) { - event->acceptProposedAction(); - - Point point = PointFromQPoint(event->pos()); - sqt->DragMove(point); - } else { - event->ignore(); - } -} - -void ScintillaEditBase::dropEvent(QDropEvent *event) -{ - if (event->mimeData()->hasText()) { - event->acceptProposedAction(); - - Point point = PointFromQPoint(event->pos()); - bool move = (event->source() == this && - event->proposedAction() == Qt::MoveAction); - sqt->Drop(point, event->mimeData(), move); - } else { - event->ignore(); - } -} - -bool ScintillaEditBase::IsHangul(const QChar qchar) -{ - int unicode = (int)qchar.unicode(); - // Korean character ranges used for preedit chars. - // http://www.programminginkorean.com/programming/hangul-in-unicode/ - const bool HangulJamo = (0x1100 <= unicode && unicode <= 0x11FF); - const bool HangulCompatibleJamo = (0x3130 <= unicode && unicode <= 0x318F); - const bool HangulJamoExtendedA = (0xA960 <= unicode && unicode <= 0xA97F); - const bool HangulJamoExtendedB = (0xD7B0 <= unicode && unicode <= 0xD7FF); - const bool HangulSyllable = (0xAC00 <= unicode && unicode <= 0xD7A3); - return HangulJamo || HangulCompatibleJamo || HangulSyllable || - HangulJamoExtendedA || HangulJamoExtendedB; -} - -void ScintillaEditBase::MoveImeCarets(int offset) -{ - // Move carets relatively by bytes - for (size_t r=0; r < sqt->sel.Count(); r++) { - int positionInsert = sqt->sel.Range(r).Start().Position(); - sqt->sel.Range(r).caret.SetPosition(positionInsert + offset); - sqt->sel.Range(r).anchor.SetPosition(positionInsert + offset); - } -} - -void ScintillaEditBase::DrawImeIndicator(int indicator, int len) -{ - // Emulate the visual style of IME characters with indicators. - // Draw an indicator on the character before caret by the character bytes of len - // so it should be called after AddCharUTF(). - // It does not affect caret positions. - if (indicator < 8 || indicator > INDIC_MAX) { - return; - } - sqt->pdoc->decorations.SetCurrentIndicator(indicator); - for (size_t r=0; r< sqt-> sel.Count(); r++) { - int positionInsert = sqt->sel.Range(r).Start().Position(); - sqt->pdoc->DecorationFillRange(positionInsert - len, 1, len); - } -} - -static int GetImeCaretPos(QInputMethodEvent *event) -{ - foreach (QInputMethodEvent::Attribute attr, event->attributes()) { - if (attr.type == QInputMethodEvent::Cursor) - return attr.start; - } - return 0; -} - -static std::vector MapImeIndicators(QInputMethodEvent *event) -{ - std::vector imeIndicator(event->preeditString().size(), SC_INDICATOR_UNKNOWN); - foreach (QInputMethodEvent::Attribute attr, event->attributes()) { - if (attr.type == QInputMethodEvent::TextFormat) { - QTextFormat format = attr.value.value(); - QTextCharFormat charFormat = format.toCharFormat(); - - int indicator = SC_INDICATOR_UNKNOWN; - switch (charFormat.underlineStyle()) { - case QTextCharFormat::NoUnderline: // win32, linux - indicator = SC_INDICATOR_TARGET; - break; - case QTextCharFormat::SingleUnderline: // osx - case QTextCharFormat::DashUnderline: // win32, linux - indicator = SC_INDICATOR_INPUT; - break; - case QTextCharFormat::DotLine: - case QTextCharFormat::DashDotLine: - case QTextCharFormat::WaveUnderline: - case QTextCharFormat::SpellCheckUnderline: - indicator = SC_INDICATOR_CONVERTED; - break; - - default: - indicator = SC_INDICATOR_UNKNOWN; - } - - if (format.hasProperty(QTextFormat::BackgroundBrush)) // win32, linux - indicator = SC_INDICATOR_TARGET; - -#ifdef Q_OS_OSX - if (charFormat.underlineStyle() == QTextCharFormat::SingleUnderline) { - QColor uc = charFormat.underlineColor(); - if (uc.lightness() < 2) { // osx - indicator = SC_INDICATOR_TARGET; - } - } -#endif - - for (int i = attr.start; i < attr.start+attr.length; i++) { - imeIndicator[i] = indicator; - } - } - } - return imeIndicator; -} - -void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event) -{ - // Copy & paste by johnsonj with a lot of helps of Neil - // Great thanks for my forerunners, jiniya and BLUEnLIVE - - if (sqt->pdoc->IsReadOnly() || sqt->SelectionContainsProtected()) { - // Here, a canceling and/or completing composition function is needed. - return; - } - - if (sqt->pdoc->TentativeActive()) { - sqt->pdoc->TentativeUndo(); - } else { - // No tentative undo means start of this composition so - // Fill in any virtual spaces. - sqt->ClearBeforeTentativeStart(); - } - - sqt->view.imeCaretBlockOverride = false; - - if (!event->commitString().isEmpty()) { - const QString commitStr = event->commitString(); - const unsigned int commitStrLen = commitStr.length(); - - for (unsigned int i = 0; i < commitStrLen;) { - const unsigned int ucWidth = commitStr.at(i).isHighSurrogate() ? 2 : 1; - const QString oneCharUTF16 = commitStr.mid(i, ucWidth); - const QByteArray oneChar = sqt->BytesForDocument(oneCharUTF16); - const int oneCharLen = oneChar.length(); - - sqt->AddCharUTF(oneChar.data(), oneCharLen); - i += ucWidth; - } - - } else if (!event->preeditString().isEmpty()) { - const QString preeditStr = event->preeditString(); - const unsigned int preeditStrLen = preeditStr.length(); - if ((preeditStrLen == 0) || (preeditStrLen > MAXLENINPUTIME)) { - sqt->ShowCaretAtCurrentPosition(); - return; - } - - sqt->pdoc->TentativeStart(); // TentativeActive() from now on. - - std::vector imeIndicator = MapImeIndicators(event); - - const bool recording = sqt->recordingMacro; - sqt->recordingMacro = false; - for (unsigned int i = 0; i < preeditStrLen;) { - const unsigned int ucWidth = preeditStr.at(i).isHighSurrogate() ? 2 : 1; - const QString oneCharUTF16 = preeditStr.mid(i, ucWidth); - const QByteArray oneChar = sqt->BytesForDocument(oneCharUTF16); - const int oneCharLen = oneChar.length(); - - sqt->AddCharUTF(oneChar.data(), oneCharLen); - - DrawImeIndicator(imeIndicator[i], oneCharLen); - i += ucWidth; - } - sqt->recordingMacro = recording; - - // Move IME carets. - int imeCaretPos = GetImeCaretPos(event); - int imeEndToImeCaretU16 = imeCaretPos - preeditStrLen; - int imeCaretPosDoc = sqt->pdoc->GetRelativePositionUTF16(sqt->CurrentPosition(), imeEndToImeCaretU16); - - MoveImeCarets(- sqt->CurrentPosition() + imeCaretPosDoc); - - if (IsHangul(preeditStr.at(0))) { -#ifndef Q_OS_WIN - if (imeCaretPos > 0) { - int oneCharBefore = sqt->pdoc->GetRelativePosition(sqt->CurrentPosition(), -1); - MoveImeCarets(- sqt->CurrentPosition() + oneCharBefore); - } -#endif - sqt->view.imeCaretBlockOverride = true; - } - - // Set candidate box position for Qt::ImMicroFocus. - preeditPos = sqt->CurrentPosition(); - sqt->EnsureCaretVisible(); - updateMicroFocus(); - } - sqt->ShowCaretAtCurrentPosition(); -} - -QVariant ScintillaEditBase::inputMethodQuery(Qt::InputMethodQuery query) const -{ - int pos = send(SCI_GETCURRENTPOS); - int line = send(SCI_LINEFROMPOSITION, pos); - - switch (query) { - case Qt::ImMicroFocus: - { - int startPos = (preeditPos >= 0) ? preeditPos : pos; - Point pt = sqt->LocationFromPosition(startPos); - int width = send(SCI_GETCARETWIDTH); - int height = send(SCI_TEXTHEIGHT, line); - return QRect(pt.x, pt.y, width, height); - } - - case Qt::ImFont: - { - char fontName[64]; - int style = send(SCI_GETSTYLEAT, pos); - int len = send(SCI_STYLEGETFONT, style, (sptr_t)fontName); - int size = send(SCI_STYLEGETSIZE, style); - bool italic = send(SCI_STYLEGETITALIC, style); - int weight = send(SCI_STYLEGETBOLD, style) ? QFont::Bold : -1; - return QFont(QString::fromUtf8(fontName, len), size, weight, italic); - } - - case Qt::ImCursorPosition: - { - int paraStart = sqt->pdoc->ParaUp(pos); - return pos - paraStart; - } - - case Qt::ImSurroundingText: - { - int paraStart = sqt->pdoc->ParaUp(pos); - int paraEnd = sqt->pdoc->ParaDown(pos); - QVarLengthArray buffer(paraEnd - paraStart + 1); - - Sci_CharacterRange charRange; - charRange.cpMin = paraStart; - charRange.cpMax = paraEnd; - - Sci_TextRange textRange; - textRange.chrg = charRange; - textRange.lpstrText = buffer.data(); - - send(SCI_GETTEXTRANGE, 0, (sptr_t)&textRange); - - return sqt->StringFromDocument(buffer.constData()); - } - - case Qt::ImCurrentSelection: - { - QVarLengthArray buffer(send(SCI_GETSELTEXT)); - send(SCI_GETSELTEXT, 0, (sptr_t)buffer.data()); - - return sqt->StringFromDocument(buffer.constData()); - } - - default: - return QVariant(); - } -} - -void ScintillaEditBase::notifyParent(SCNotification scn) -{ - emit notify(&scn); - switch (scn.nmhdr.code) { - case SCN_STYLENEEDED: - emit styleNeeded(scn.position); - break; - - case SCN_CHARADDED: - emit charAdded(scn.ch); - break; - - case SCN_SAVEPOINTREACHED: - emit savePointChanged(false); - break; - - case SCN_SAVEPOINTLEFT: - emit savePointChanged(true); - break; - - case SCN_MODIFYATTEMPTRO: - emit modifyAttemptReadOnly(); - break; - - case SCN_KEY: - emit key(scn.ch); - break; - - case SCN_DOUBLECLICK: - emit doubleClick(scn.position, scn.line); - break; - - case SCN_UPDATEUI: - emit updateUi(); - break; - - case SCN_MODIFIED: - { - bool added = scn.modificationType & SC_MOD_INSERTTEXT; - bool deleted = scn.modificationType & SC_MOD_DELETETEXT; - - int length = send(SCI_GETTEXTLENGTH); - bool firstLineAdded = (added && length == 1) || - (deleted && length == 0); - - if (scn.linesAdded != 0) { - emit linesAdded(scn.linesAdded); - } else if (firstLineAdded) { - emit linesAdded(added ? 1 : -1); - } - - const QByteArray bytes = QByteArray::fromRawData(scn.text, scn.length); - emit modified(scn.modificationType, scn.position, scn.length, - scn.linesAdded, bytes, scn.line, - scn.foldLevelNow, scn.foldLevelPrev); - break; - } - - case SCN_MACRORECORD: - emit macroRecord(scn.message, scn.wParam, scn.lParam); - break; - - case SCN_MARGINCLICK: - emit marginClicked(scn.position, scn.modifiers, scn.margin); - break; - - case SCN_NEEDSHOWN: - emit needShown(scn.position, scn.length); - break; - - case SCN_PAINTED: - emit painted(); - break; - - case SCN_USERLISTSELECTION: - emit userListSelection(); - break; - - case SCN_URIDROPPED: - emit uriDropped(); - break; - - case SCN_DWELLSTART: - emit dwellStart(scn.x, scn.y); - break; - - case SCN_DWELLEND: - emit dwellEnd(scn.x, scn.y); - break; - - case SCN_ZOOM: - emit zoom(send(SCI_GETZOOM)); - break; - - case SCN_HOTSPOTCLICK: - emit hotSpotClick(scn.position, scn.modifiers); - break; - - case SCN_HOTSPOTDOUBLECLICK: - emit hotSpotDoubleClick(scn.position, scn.modifiers); - break; - - case SCN_CALLTIPCLICK: - emit callTipClick(); - break; - - case SCN_AUTOCSELECTION: - emit autoCompleteSelection(scn.lParam, QString::fromUtf8(scn.text)); - break; - - case SCN_AUTOCCANCELLED: - emit autoCompleteCancelled(); - break; - - default: - return; - } -} - -void ScintillaEditBase::event_command(uptr_t wParam, sptr_t lParam) -{ - emit command(wParam, lParam); -} diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.h b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.h deleted file mode 100644 index 7c52e5690..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaEditBase.h +++ /dev/null @@ -1,156 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// ScintillaWidget.h - Qt widget that wraps ScintillaQt and provides events and scrolling - - -#ifndef SCINTILLAEDITBASE_H -#define SCINTILLAEDITBASE_H - -#include "Platform.h" -#include "Scintilla.h" - -#include -#include -#include - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class ScintillaQt; -class SurfaceImpl; -struct SCNotification; - -#ifdef WIN32 -#ifdef MAKING_LIBRARY -#define EXPORT_IMPORT_API __declspec(dllexport) -#else -// Defining dllimport upsets moc -#define EXPORT_IMPORT_API __declspec(dllimport) -//#define EXPORT_IMPORT_API -#endif -#else -#define EXPORT_IMPORT_API -#endif - -class EXPORT_IMPORT_API ScintillaEditBase : public QAbstractScrollArea { - Q_OBJECT - -public: - explicit ScintillaEditBase(QWidget *parent = 0); - virtual ~ScintillaEditBase(); - - virtual sptr_t send( - unsigned int iMessage, - uptr_t wParam = 0, - sptr_t lParam = 0) const; - - virtual sptr_t sends( - unsigned int iMessage, - uptr_t wParam = 0, - const char *s = 0) const; - -public slots: - // Scroll events coming from GUI to be sent to Scintilla. - void scrollHorizontal(int value); - void scrollVertical(int value); - - // Emit Scintilla notifications as signals. - void notifyParent(SCNotification scn); - void event_command(uptr_t wParam, sptr_t lParam); - -signals: - void horizontalScrolled(int value); - void verticalScrolled(int value); - void horizontalRangeChanged(int max, int page); - void verticalRangeChanged(int max, int page); - void notifyChange(); - void linesAdded(int linesAdded); - - // Clients can use this hook to add additional - // formats (e.g. rich text) to the MIME data. - void aboutToCopy(QMimeData *data); - - // Scintilla Notifications - void styleNeeded(int position); - void charAdded(int ch); - void savePointChanged(bool dirty); - void modifyAttemptReadOnly(); - void key(int key); - void doubleClick(int position, int line); - void updateUi(); - void modified(int type, int position, int length, int linesAdded, - const QByteArray &text, int line, int foldNow, int foldPrev); - void macroRecord(int message, uptr_t wParam, sptr_t lParam); - void marginClicked(int position, int modifiers, int margin); - void textAreaClicked(int line, int modifiers); - void needShown(int position, int length); - void painted(); - void userListSelection(); // Wants some args. - void uriDropped(); // Wants some args. - void dwellStart(int x, int y); - void dwellEnd(int x, int y); - void zoom(int zoom); - void hotSpotClick(int position, int modifiers); - void hotSpotDoubleClick(int position, int modifiers); - void callTipClick(); - void autoCompleteSelection(int position, const QString &text); - void autoCompleteCancelled(); - - // Base notifications for compatibility with other Scintilla implementations - void notify(SCNotification *pscn); - void command(uptr_t wParam, sptr_t lParam); - - // GUI event notifications needed under Qt - void buttonPressed(QMouseEvent *event); - void buttonReleased(QMouseEvent *event); - void keyPressed(QKeyEvent *event); - void resized(); - -protected: - virtual bool event(QEvent *event); - virtual void paintEvent(QPaintEvent *event); - virtual void wheelEvent(QWheelEvent *event); - virtual void focusInEvent(QFocusEvent *event); - virtual void focusOutEvent(QFocusEvent *event); - virtual void resizeEvent(QResizeEvent *event); - virtual void keyPressEvent(QKeyEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void mouseDoubleClickEvent(QMouseEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void contextMenuEvent(QContextMenuEvent *event); - virtual void dragEnterEvent(QDragEnterEvent *event); - virtual void dragLeaveEvent(QDragLeaveEvent *event); - virtual void dragMoveEvent(QDragMoveEvent *event); - virtual void dropEvent(QDropEvent *event); - virtual void inputMethodEvent(QInputMethodEvent *event); - virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; - virtual void scrollContentsBy(int, int) {} - -private: - ScintillaQt *sqt; - - QTime time; - - int preeditPos; - QString preeditString; - - int wheelDelta; - - static bool IsHangul(const QChar qchar); - void MoveImeCarets(int offset); - void DrawImeIndicator(int indicator, int len); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif /* SCINTILLAEDITBASE_H */ diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.cpp b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.cpp deleted file mode 100644 index b872b1363..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.cpp +++ /dev/null @@ -1,766 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// ScintillaQt.cpp - Qt specific subclass of ScintillaBase - -#include "PlatQt.h" -#include "ScintillaQt.h" -#ifdef SCI_LEXER -#include "LexerModule.h" -#include "ExternalLexer.h" -#endif - -#include -#include -#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) -#include -#endif -#include -#include -#include -#include -#include - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - - -ScintillaQt::ScintillaQt(QAbstractScrollArea *parent) -: QObject(parent), scrollArea(parent), vMax(0), hMax(0), vPage(0), hPage(0), - haveMouseCapture(false), dragWasDropped(false) -{ - - wMain = scrollArea->viewport(); - - imeInteraction = imeInline; - - // On OS X drawing text into a pixmap moves it around 1 pixel to - // the right compared to drawing it directly onto a window. - // Buffered drawing turned off by default to avoid this. - WndProc(SCI_SETBUFFEREDDRAW, false, 0); - - Initialise(); - - for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast(tr + 1)) { - timers[tr] = 0; - } -} - -ScintillaQt::~ScintillaQt() -{ - for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast(tr + 1)) { - FineTickerCancel(tr); - } - SetIdle(false); -} - -void ScintillaQt::execCommand(QAction *action) -{ - int command = action->data().toInt(); - Command(command); -} - -#if defined(Q_OS_WIN) -static const QString sMSDEVColumnSelect(QStringLiteral("MSDEVColumnSelect")); -static const QString sWrappedMSDEVColumnSelect(QStringLiteral("application/x-qt-windows-mime;value=\"MSDEVColumnSelect\"")); -#elif defined(Q_OS_MAC) -static const QString sScintillaRecPboardType(QStringLiteral("com.scintilla.utf16-plain-text.rectangular")); -static const QString sScintillaRecMimeType(QStringLiteral("text/x-scintilla.utf16-plain-text.rectangular")); -#else -// Linux -static const QString sMimeRectangularMarker(QStringLiteral("text/x-rectangular-marker")); -#endif - -#if defined(Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - -class ScintillaRectangularMime : public QMacPasteboardMime { -public: - ScintillaRectangularMime() : QMacPasteboardMime(MIME_ALL) { - } - - QString convertorName() { - return QString("ScintillaRectangularMime"); - } - - bool canConvert(const QString &mime, QString flav) { - return mimeFor(flav) == mime; - } - - QString mimeFor(QString flav) { - if (flav == sScintillaRecPboardType) - return sScintillaRecMimeType; - return QString(); - } - - QString flavorFor(const QString &mime) { - if (mime == sScintillaRecMimeType) - return sScintillaRecPboardType; - return QString(); - } - - QVariant convertToMime(const QString & /* mime */, QList data, QString /* flav */) { - QByteArray all; - foreach (QByteArray i, data) { - all += i; - } - return QVariant(all); - } - - QList convertFromMime(const QString & /* mime */, QVariant data, QString /* flav */) { - QByteArray a = data.toByteArray(); - QList l; - l.append(a); - return l; - } - -}; - -// The Mime object registers itself but only want one for all Scintilla instances. -// Should delete at exit to help memory leak detection but that would be extra work -// and, since the clipboard exists after last Scintilla instance, may be complex. -static ScintillaRectangularMime *singletonMime = 0; - -#endif - -void ScintillaQt::Initialise() -{ -#if defined(Q_OS_WIN) || defined(Q_OS_MAC) - rectangularSelectionModifier = SCMOD_ALT; -#else - rectangularSelectionModifier = SCMOD_CTRL; -#endif - -#if defined(Q_OS_MAC) && QT_VERSION < QT_VERSION_CHECK(5, 0, 0) - if (!singletonMime) { - singletonMime = new ScintillaRectangularMime(); - - QStringList slTypes(sScintillaRecPboardType); - qRegisterDraggedTypes(slTypes); - } -#endif - - connect(QApplication::clipboard(), SIGNAL(selectionChanged()), - this, SLOT(SelectionChanged())); -} - -void ScintillaQt::Finalise() -{ - for (TickReason tr = tickCaret; tr <= tickDwell; tr = static_cast(tr + 1)) { - FineTickerCancel(tr); - } - ScintillaBase::Finalise(); -} - -void ScintillaQt::SelectionChanged() -{ - bool nowPrimary = QApplication::clipboard()->ownsSelection(); - if (nowPrimary != primarySelection) { - primarySelection = nowPrimary; - Redraw(); - } -} - -bool ScintillaQt::DragThreshold(Point ptStart, Point ptNow) -{ - int xMove = std::abs(ptStart.x - ptNow.x); - int yMove = std::abs(ptStart.y - ptNow.y); - return (xMove > QApplication::startDragDistance()) || - (yMove > QApplication::startDragDistance()); -} - -static QString StringFromSelectedText(const SelectionText &selectedText) -{ - if (selectedText.codePage == SC_CP_UTF8) { - return QString::fromUtf8(selectedText.Data(), static_cast(selectedText.Length())); - } else { - QTextCodec *codec = QTextCodec::codecForName( - CharacterSetID(selectedText.characterSet)); - return codec->toUnicode(selectedText.Data(), static_cast(selectedText.Length())); - } -} - -static void AddRectangularToMime(QMimeData *mimeData, QString su) -{ -#if defined(Q_OS_WIN) - // Add an empty marker - mimeData->setData(sMSDEVColumnSelect, QByteArray()); -#elif defined(Q_OS_MAC) - // OS X gets marker + data to work with other implementations. - // Don't understand how this works but it does - the - // clipboard format is supposed to be UTF-16, not UTF-8. - mimeData->setData(sScintillaRecMimeType, su.toUtf8()); -#else - Q_UNUSED(su); - // Linux - // Add an empty marker - mimeData->setData(sMimeRectangularMarker, QByteArray()); -#endif -} - -static bool IsRectangularInMime(const QMimeData *mimeData) -{ - QStringList formats = mimeData->formats(); - for (int i = 0; i < formats.size(); ++i) { -#if defined(Q_OS_WIN) - // Windows rectangular markers - // If rectangular copies made by this application, see base name. - if (formats[i] == sMSDEVColumnSelect) - return true; - // Otherwise see wrapped name. - if (formats[i] == sWrappedMSDEVColumnSelect) - return true; -#elif defined(Q_OS_MAC) - if (formats[i] == sScintillaRecMimeType) - return true; -#else - // Linux - if (formats[i] == sMimeRectangularMarker) - return true; -#endif - } - return false; -} - -bool ScintillaQt::ValidCodePage(int codePage) const -{ - return codePage == 0 - || codePage == SC_CP_UTF8 - || codePage == 932 - || codePage == 936 - || codePage == 949 - || codePage == 950 - || codePage == 1361; -} - - -void ScintillaQt::ScrollText(int linesToMove) -{ - int dy = vs.lineHeight * (linesToMove); - scrollArea->viewport()->scroll(0, dy); -} - -void ScintillaQt::SetVerticalScrollPos() -{ - scrollArea->verticalScrollBar()->setValue(topLine); - emit verticalScrolled(topLine); -} - -void ScintillaQt::SetHorizontalScrollPos() -{ - scrollArea->horizontalScrollBar()->setValue(xOffset); - emit horizontalScrolled(xOffset); -} - -bool ScintillaQt::ModifyScrollBars(int nMax, int nPage) -{ - bool modified = false; - - int vNewPage = nPage; - int vNewMax = nMax - vNewPage + 1; - if (vMax != vNewMax || vPage != vNewPage) { - vMax = vNewMax; - vPage = vNewPage; - modified = true; - - scrollArea->verticalScrollBar()->setMaximum(vMax); - scrollArea->verticalScrollBar()->setPageStep(vPage); - emit verticalRangeChanged(vMax, vPage); - } - - int hNewPage = GetTextRectangle().Width(); - int hNewMax = (scrollWidth > hNewPage) ? scrollWidth - hNewPage : 0; - int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth; - if (hMax != hNewMax || hPage != hNewPage || - scrollArea->horizontalScrollBar()->singleStep() != charWidth) { - hMax = hNewMax; - hPage = hNewPage; - modified = true; - - scrollArea->horizontalScrollBar()->setMaximum(hMax); - scrollArea->horizontalScrollBar()->setPageStep(hPage); - scrollArea->horizontalScrollBar()->setSingleStep(charWidth); - emit horizontalRangeChanged(hMax, hPage); - } - - return modified; -} - -void ScintillaQt::ReconfigureScrollBars() -{ - if (verticalScrollBarVisible) { - scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - } else { - scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - } - - if (horizontalScrollBarVisible && !Wrapping()) { - scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); - } else { - scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - } -} - -void ScintillaQt::CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_) -{ - QClipboard *clipboard = QApplication::clipboard(); - clipboard->clear(clipboardMode_); - QString su = StringFromSelectedText(selectedText); - QMimeData *mimeData = new QMimeData(); - mimeData->setText(su); - if (selectedText.rectangular) { - AddRectangularToMime(mimeData, su); - } - - // Allow client code to add additional data (e.g rich text). - emit aboutToCopy(mimeData); - - clipboard->setMimeData(mimeData, clipboardMode_); -} - -void ScintillaQt::Copy() -{ - if (!sel.Empty()) { - SelectionText st; - CopySelectionRange(&st); - CopyToClipboard(st); - } -} - -void ScintillaQt::CopyToClipboard(const SelectionText &selectedText) -{ - CopyToModeClipboard(selectedText, QClipboard::Clipboard); -} - -void ScintillaQt::PasteFromMode(QClipboard::Mode clipboardMode_) -{ - QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(clipboardMode_); - bool isRectangular = IsRectangularInMime(mimeData); - QString text = clipboard->text(clipboardMode_); - QByteArray utext = BytesForDocument(text); - std::string dest(utext.constData(), utext.length()); - SelectionText selText; - selText.Copy(dest, pdoc->dbcsCodePage, CharacterSetOfDocument(), isRectangular, false); - - UndoGroup ug(pdoc); - ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH); - InsertPasteShape(selText.Data(), static_cast(selText.Length()), - selText.rectangular ? pasteRectangular : pasteStream); - EnsureCaretVisible(); -} - -void ScintillaQt::Paste() -{ - PasteFromMode(QClipboard::Clipboard); -} - -void ScintillaQt::ClaimSelection() -{ - if (QApplication::clipboard()->supportsSelection()) { - // X Windows has a 'primary selection' as well as the clipboard. - // Whenever the user selects some text, we become the primary selection - if (!sel.Empty()) { - primarySelection = true; - SelectionText st; - CopySelectionRange(&st); - CopyToModeClipboard(st, QClipboard::Selection); - } else { - primarySelection = false; - } - } -} - -void ScintillaQt::NotifyChange() -{ - emit notifyChange(); - emit command( - Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), - reinterpret_cast(wMain.GetID())); -} - -void ScintillaQt::NotifyFocus(bool focus) -{ - emit command( - Platform::LongFromTwoShorts - (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), - reinterpret_cast(wMain.GetID())); - - Editor::NotifyFocus(focus); -} - -void ScintillaQt::NotifyParent(SCNotification scn) -{ - scn.nmhdr.hwndFrom = wMain.GetID(); - scn.nmhdr.idFrom = GetCtrlID(); - emit notifyParent(scn); -} - -/** -* Report that this Editor subclass has a working implementation of FineTickerStart. -*/ -bool ScintillaQt::FineTickerAvailable() -{ - return true; -} - -bool ScintillaQt::FineTickerRunning(TickReason reason) -{ - return timers[reason] != 0; -} - -void ScintillaQt::FineTickerStart(TickReason reason, int millis, int /* tolerance */) -{ - FineTickerCancel(reason); - timers[reason] = startTimer(millis); -} - -void ScintillaQt::FineTickerCancel(TickReason reason) -{ - if (timers[reason]) { - killTimer(timers[reason]); - timers[reason] = 0; - } -} - -void ScintillaQt::onIdle() -{ - bool continueIdling = Idle(); - if (!continueIdling) { - SetIdle(false); - } -} - -bool ScintillaQt::SetIdle(bool on) -{ - QTimer *qIdle; - if (on) { - // Start idler, if it's not running. - if (!idler.state) { - idler.state = true; - qIdle = new QTimer; - connect(qIdle, SIGNAL(timeout()), this, SLOT(onIdle())); - qIdle->start(0); - idler.idlerID = qIdle; - } - } else { - // Stop idler, if it's running - if (idler.state) { - idler.state = false; - qIdle = static_cast(idler.idlerID); - qIdle->stop(); - disconnect(qIdle, SIGNAL(timeout()), 0, 0); - delete qIdle; - idler.idlerID = 0; - } - } - return true; -} - -int ScintillaQt::CharacterSetOfDocument() const -{ - return vs.styles[STYLE_DEFAULT].characterSet; -} - -const char *ScintillaQt::CharacterSetIDOfDocument() const -{ - return CharacterSetID(CharacterSetOfDocument()); -} - -QString ScintillaQt::StringFromDocument(const char *s) const -{ - if (IsUnicodeMode()) { - return QString::fromUtf8(s); - } else { - QTextCodec *codec = QTextCodec::codecForName( - CharacterSetID(CharacterSetOfDocument())); - return codec->toUnicode(s); - } -} - -QByteArray ScintillaQt::BytesForDocument(const QString &text) const -{ - if (IsUnicodeMode()) { - return text.toUtf8(); - } else { - QTextCodec *codec = QTextCodec::codecForName( - CharacterSetID(CharacterSetOfDocument())); - return codec->fromUnicode(text); - } -} - - -class CaseFolderDBCS : public CaseFolderTable { - QTextCodec *codec; -public: - explicit CaseFolderDBCS(QTextCodec *codec_) : codec(codec_) { - StandardASCII(); - } - virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { - if ((lenMixed == 1) && (sizeFolded > 0)) { - folded[0] = mapping[static_cast(mixed[0])]; - return 1; - } else if (codec) { - QString su = codec->toUnicode(mixed, static_cast(lenMixed)); - QString suFolded = su.toCaseFolded(); - QByteArray bytesFolded = codec->fromUnicode(suFolded); - - if (bytesFolded.length() < static_cast(sizeFolded)) { - memcpy(folded, bytesFolded, bytesFolded.length()); - return bytesFolded.length(); - } - } - // Something failed so return a single NUL byte - folded[0] = '\0'; - return 1; - } -}; - -CaseFolder *ScintillaQt::CaseFolderForEncoding() -{ - if (pdoc->dbcsCodePage == SC_CP_UTF8) { - return new CaseFolderUnicode(); - } else { - const char *charSetBuffer = CharacterSetIDOfDocument(); - if (charSetBuffer) { - if (pdoc->dbcsCodePage == 0) { - CaseFolderTable *pcf = new CaseFolderTable(); - pcf->StandardASCII(); - QTextCodec *codec = QTextCodec::codecForName(charSetBuffer); - // Only for single byte encodings - for (int i=0x80; i<0x100; i++) { - char sCharacter[2] = "A"; - sCharacter[0] = i; - QString su = codec->toUnicode(sCharacter, 1); - QString suFolded = su.toCaseFolded(); - QByteArray bytesFolded = codec->fromUnicode(suFolded); - if (bytesFolded.length() == 1) { - pcf->SetTranslation(sCharacter[0], bytesFolded[0]); - } - } - return pcf; - } else { - return new CaseFolderDBCS(QTextCodec::codecForName(charSetBuffer)); - } - } - return 0; - } -} - -std::string ScintillaQt::CaseMapString(const std::string &s, int caseMapping) -{ - if ((s.size() == 0) || (caseMapping == cmSame)) - return s; - - if (IsUnicodeMode()) { - std::string retMapped(s.length() * maxExpansionCaseConversion, 0); - size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), - (caseMapping == cmUpper) ? CaseConversionUpper : CaseConversionLower); - retMapped.resize(lenMapped); - return retMapped; - } - - QTextCodec *codec = QTextCodec::codecForName(CharacterSetIDOfDocument()); - QString text = codec->toUnicode(s.c_str(), static_cast(s.length())); - - if (caseMapping == cmUpper) { - text = text.toUpper(); - } else { - text = text.toLower(); - } - - QByteArray bytes = BytesForDocument(text); - return std::string(bytes.data(), bytes.length()); -} - -void ScintillaQt::SetMouseCapture(bool on) -{ - // This is handled automatically by Qt - if (mouseDownCaptures) { - haveMouseCapture = on; - } -} - -bool ScintillaQt::HaveMouseCapture() -{ - return haveMouseCapture; -} - -void ScintillaQt::StartDrag() -{ - inDragDrop = ddDragging; - dropWentOutside = true; - if (drag.Length()) { - QMimeData *mimeData = new QMimeData; - QString sText = StringFromSelectedText(drag); - mimeData->setText(sText); - if (drag.rectangular) { - AddRectangularToMime(mimeData, sText); - } - // This QDrag is not freed as that causes a crash on Linux - QDrag *dragon = new QDrag(scrollArea); - dragon->setMimeData(mimeData); - - Qt::DropAction dropAction = dragon->exec(Qt::CopyAction|Qt::MoveAction); - if ((dropAction == Qt::MoveAction) && dropWentOutside) { - // Remove dragged out text - ClearSelection(); - } - } - inDragDrop = ddNone; - SetDragPosition(SelectionPosition(invalidPosition)); -} - -void ScintillaQt::CreateCallTipWindow(PRectangle rc) -{ - - if (!ct.wCallTip.Created()) { - QWidget *pCallTip = new QWidget(0, Qt::ToolTip); - ct.wCallTip = pCallTip; - pCallTip->move(rc.left, rc.top); - pCallTip->resize(rc.Width(), rc.Height()); - } -} - -void ScintillaQt::AddToPopUp(const char *label, - int cmd, - bool enabled) -{ - QMenu *menu = static_cast(popup.GetID()); - QString text = QString::fromLatin1(label); - - if (text.isEmpty()) { - menu->addSeparator(); - } else { - QAction *action = menu->addAction(text); - action->setData(cmd); - action->setEnabled(enabled); - } - - // Make sure the menu's signal is connected only once. - menu->disconnect(); - connect(menu, SIGNAL(triggered(QAction *)), - this, SLOT(execCommand(QAction *))); -} - -sptr_t ScintillaQt::WndProc(unsigned int message, uptr_t wParam, sptr_t lParam) -{ - try { - switch (message) { - - case SCI_SETIMEINTERACTION: - // Only inline IME supported on Qt - break; - - case SCI_GRABFOCUS: - scrollArea->setFocus(Qt::OtherFocusReason); - break; - - case SCI_GETDIRECTFUNCTION: - return reinterpret_cast(DirectFunction); - - case SCI_GETDIRECTPOINTER: - return reinterpret_cast(this); - -#ifdef SCI_LEXER - case SCI_LOADLEXERLIBRARY: - LexerManager::GetInstance()->Load(reinterpret_cast(lParam)); - break; -#endif - - default: - return ScintillaBase::WndProc(message, wParam, lParam); - } - } catch (std::bad_alloc &) { - errorStatus = SC_STATUS_BADALLOC; - } catch (...) { - errorStatus = SC_STATUS_FAILURE; - } - return 0l; -} - -sptr_t ScintillaQt::DefWndProc(unsigned int, uptr_t, sptr_t) -{ - return 0; -} - -sptr_t ScintillaQt::DirectFunction( - sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam) -{ - return reinterpret_cast(ptr)->WndProc(iMessage, wParam, lParam); -} - -// Additions to merge in Scientific Toolworks widget structure - -void ScintillaQt::PartialPaint(const PRectangle &rect) -{ - rcPaint = rect; - paintState = painting; - PRectangle rcClient = GetClientRectangle(); - paintingAllText = rcPaint.Contains(rcClient); - - AutoSurface surface(this); - Paint(surface, rcPaint); - surface->Release(); - - if (paintState == paintAbandoned) { - // FIXME: Failure to paint the requested rectangle in each - // paint event causes flicker on some platforms (Mac?) - // Paint rect immediately. - paintState = painting; - paintingAllText = true; - - AutoSurface surface(this); - Paint(surface, rcPaint); - surface->Release(); - - // Queue a full repaint. - scrollArea->viewport()->update(); - } - - paintState = notPainting; -} - -void ScintillaQt::DragEnter(const Point &point) -{ - SetDragPosition(SPositionFromLocation(point, - false, false, UserVirtualSpace())); -} - -void ScintillaQt::DragMove(const Point &point) -{ - SetDragPosition(SPositionFromLocation(point, - false, false, UserVirtualSpace())); -} - -void ScintillaQt::DragLeave() -{ - SetDragPosition(SelectionPosition(invalidPosition)); -} - -void ScintillaQt::Drop(const Point &point, const QMimeData *data, bool move) -{ - QString text = data->text(); - bool rectangular = IsRectangularInMime(data); - QByteArray bytes = BytesForDocument(text); - int len = bytes.length(); - - SelectionPosition movePos = SPositionFromLocation(point, - false, false, UserVirtualSpace()); - - DropAt(movePos, bytes, len, move, rectangular); -} - -void ScintillaQt::timerEvent(QTimerEvent *event) -{ - for (TickReason tr=tickCaret; tr<=tickDwell; tr = static_cast(tr+1)) { - if (timers[tr] == event->timerId()) { - TickFor(tr); - } - } -} diff --git a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.h b/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.h deleted file mode 100644 index 6db30bdec..000000000 --- a/qrenderdoc/3rdparty/scintilla/qt/ScintillaEditBase/ScintillaQt.h +++ /dev/null @@ -1,172 +0,0 @@ -// -// Copyright (c) 1990-2011, Scientific Toolworks, Inc. -// -// The License.txt file describes the conditions under which this software may be distributed. -// -// Author: Jason Haslam -// -// Additions Copyright (c) 2011 Archaeopteryx Software, Inc. d/b/a Wingware -// ScintillaQt.h - Qt specific subclass of ScintillaBase - -#ifndef SCINTILLAQT_H -#define SCINTILLAQT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "Scintilla.h" -#include "Platform.h" -#include "ILexer.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "CallTip.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "AutoComplete.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "Selection.h" -#include "PositionCache.h" -#include "EditModel.h" -#include "MarginView.h" -#include "EditView.h" -#include "Editor.h" -#include "ScintillaBase.h" -#include "CaseConvert.h" - -#ifdef SCI_LEXER -#include "SciLexer.h" -#include "PropSetSimple.h" -#endif - -#include -#include -#include -#include -#include - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class ScintillaQt : public QObject, public ScintillaBase { - Q_OBJECT - -public: - explicit ScintillaQt(QAbstractScrollArea *parent); - virtual ~ScintillaQt(); - -signals: - void horizontalScrolled(int value); - void verticalScrolled(int value); - void horizontalRangeChanged(int max, int page); - void verticalRangeChanged(int max, int page); - - void notifyParent(SCNotification scn); - void notifyChange(); - - // Clients can use this hook to add additional - // formats (e.g. rich text) to the MIME data. - void aboutToCopy(QMimeData *data); - - void command(uptr_t wParam, sptr_t lParam); - -private slots: - void onIdle(); - void execCommand(QAction *action); - void SelectionChanged(); - -private: - virtual void Initialise(); - virtual void Finalise(); - virtual bool DragThreshold(Point ptStart, Point ptNow); - virtual bool ValidCodePage(int codePage) const; - -private: - virtual void ScrollText(int linesToMove); - virtual void SetVerticalScrollPos(); - virtual void SetHorizontalScrollPos(); - virtual bool ModifyScrollBars(int nMax, int nPage); - virtual void ReconfigureScrollBars(); - void CopyToModeClipboard(const SelectionText &selectedText, QClipboard::Mode clipboardMode_); - virtual void Copy(); - virtual void CopyToClipboard(const SelectionText &selectedText); - void PasteFromMode(QClipboard::Mode clipboardMode_); - virtual void Paste(); - virtual void ClaimSelection(); - virtual void NotifyChange(); - virtual void NotifyFocus(bool focus); - virtual void NotifyParent(SCNotification scn); - int timers[tickDwell+1]; - virtual bool FineTickerAvailable(); - virtual bool FineTickerRunning(TickReason reason); - virtual void FineTickerStart(TickReason reason, int millis, int tolerance); - virtual void FineTickerCancel(TickReason reason); - virtual bool SetIdle(bool on); - virtual void SetMouseCapture(bool on); - virtual bool HaveMouseCapture(); - virtual void StartDrag(); - int CharacterSetOfDocument() const; - const char *CharacterSetIDOfDocument() const; - QString StringFromDocument(const char *s) const; - QByteArray BytesForDocument(const QString &text) const; - virtual CaseFolder *CaseFolderForEncoding(); - virtual std::string CaseMapString(const std::string &s, int caseMapping); - - virtual void CreateCallTipWindow(PRectangle rc); - virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true); - virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - - static sptr_t DirectFunction(sptr_t ptr, - unsigned int iMessage, uptr_t wParam, sptr_t lParam); - -protected: - - void PartialPaint(const PRectangle &rect); - - void DragEnter(const Point &point); - void DragMove(const Point &point); - void DragLeave(); - void Drop(const Point &point, const QMimeData *data, bool move); - - void timerEvent(QTimerEvent *event); - -private: - QAbstractScrollArea *scrollArea; - - int vMax, hMax; // Scroll bar maximums. - int vPage, hPage; // Scroll bar page sizes. - - bool haveMouseCapture; - bool dragWasDropped; - int rectangularSelectionModifier; - - friend class ScintillaEditBase; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif // SCINTILLAQT_H diff --git a/qrenderdoc/3rdparty/scintilla/src/AutoComplete.cxx b/qrenderdoc/3rdparty/scintilla/src/AutoComplete.cxx deleted file mode 100644 index 3f3570283..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/AutoComplete.cxx +++ /dev/null @@ -1,296 +0,0 @@ -// Scintilla source code edit control -/** @file AutoComplete.cxx - ** Defines the auto completion list box. - **/ -// Copyright 1998-2003 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "CharacterSet.h" -#include "Position.h" -#include "AutoComplete.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -AutoComplete::AutoComplete() : - active(false), - separator(' '), - typesep('?'), - ignoreCase(false), - chooseSingle(false), - lb(0), - posStart(0), - startLen(0), - cancelAtStartPos(true), - autoHide(true), - dropRestOfWord(false), - ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE), - widthLBDefault(100), - heightLBDefault(100), - autoSort(SC_ORDER_PRESORTED) { - lb = ListBox::Allocate(); -} - -AutoComplete::~AutoComplete() { - if (lb) { - lb->Destroy(); - delete lb; - lb = 0; - } -} - -bool AutoComplete::Active() const { - return active; -} - -void AutoComplete::Start(Window &parent, int ctrlID, - int position, Point location, int startLen_, - int lineHeight, bool unicodeMode, int technology) { - if (active) { - Cancel(); - } - lb->Create(parent, ctrlID, location, lineHeight, unicodeMode, technology); - lb->Clear(); - active = true; - startLen = startLen_; - posStart = position; -} - -void AutoComplete::SetStopChars(const char *stopChars_) { - stopChars = stopChars_; -} - -bool AutoComplete::IsStopChar(char ch) { - return ch && (stopChars.find(ch) != std::string::npos); -} - -void AutoComplete::SetFillUpChars(const char *fillUpChars_) { - fillUpChars = fillUpChars_; -} - -bool AutoComplete::IsFillUpChar(char ch) { - return ch && (fillUpChars.find(ch) != std::string::npos); -} - -void AutoComplete::SetSeparator(char separator_) { - separator = separator_; -} - -char AutoComplete::GetSeparator() const { - return separator; -} - -void AutoComplete::SetTypesep(char separator_) { - typesep = separator_; -} - -char AutoComplete::GetTypesep() const { - return typesep; -} - -struct Sorter { - AutoComplete *ac; - const char *list; - std::vector indices; - - Sorter(AutoComplete *ac_, const char *list_) : ac(ac_), list(list_) { - int i = 0; - while (list[i]) { - indices.push_back(i); // word start - while (list[i] != ac->GetTypesep() && list[i] != ac->GetSeparator() && list[i]) - ++i; - indices.push_back(i); // word end - if (list[i] == ac->GetTypesep()) { - while (list[i] != ac->GetSeparator() && list[i]) - ++i; - } - if (list[i] == ac->GetSeparator()) { - ++i; - // preserve trailing separator as blank entry - if (!list[i]) { - indices.push_back(i); - indices.push_back(i); - } - } - } - indices.push_back(i); // index of last position - } - - bool operator()(int a, int b) { - int lenA = indices[a * 2 + 1] - indices[a * 2]; - int lenB = indices[b * 2 + 1] - indices[b * 2]; - int len = std::min(lenA, lenB); - int cmp; - if (ac->ignoreCase) - cmp = CompareNCaseInsensitive(list + indices[a * 2], list + indices[b * 2], len); - else - cmp = strncmp(list + indices[a * 2], list + indices[b * 2], len); - if (cmp == 0) - cmp = lenA - lenB; - return cmp < 0; - } -}; - -void AutoComplete::SetList(const char *list) { - if (autoSort == SC_ORDER_PRESORTED) { - lb->SetList(list, separator, typesep); - sortMatrix.clear(); - for (int i = 0; i < lb->Length(); ++i) - sortMatrix.push_back(i); - return; - } - - Sorter IndexSort(this, list); - sortMatrix.clear(); - for (int i = 0; i < (int)IndexSort.indices.size() / 2; ++i) - sortMatrix.push_back(i); - std::sort(sortMatrix.begin(), sortMatrix.end(), IndexSort); - if (autoSort == SC_ORDER_CUSTOM || sortMatrix.size() < 2) { - lb->SetList(list, separator, typesep); - PLATFORM_ASSERT(lb->Length() == static_cast(sortMatrix.size())); - return; - } - - std::string sortedList; - char item[maxItemLen]; - for (size_t i = 0; i < sortMatrix.size(); ++i) { - int wordLen = IndexSort.indices[sortMatrix[i] * 2 + 2] - IndexSort.indices[sortMatrix[i] * 2]; - if (wordLen > maxItemLen-2) - wordLen = maxItemLen - 2; - memcpy(item, list + IndexSort.indices[sortMatrix[i] * 2], wordLen); - if ((i+1) == sortMatrix.size()) { - // Last item so remove separator if present - if ((wordLen > 0) && (item[wordLen-1] == separator)) - wordLen--; - } else { - // Item before last needs a separator - if ((wordLen == 0) || (item[wordLen-1] != separator)) { - item[wordLen] = separator; - wordLen++; - } - } - item[wordLen] = '\0'; - sortedList += item; - } - for (int i = 0; i < (int)sortMatrix.size(); ++i) - sortMatrix[i] = i; - lb->SetList(sortedList.c_str(), separator, typesep); -} - -int AutoComplete::GetSelection() const { - return lb->GetSelection(); -} - -std::string AutoComplete::GetValue(int item) const { - char value[maxItemLen]; - lb->GetValue(item, value, sizeof(value)); - return std::string(value); -} - -void AutoComplete::Show(bool show) { - lb->Show(show); - if (show) - lb->Select(0); -} - -void AutoComplete::Cancel() { - if (lb->Created()) { - lb->Clear(); - lb->Destroy(); - active = false; - } -} - - -void AutoComplete::Move(int delta) { - int count = lb->Length(); - int current = lb->GetSelection(); - current += delta; - if (current >= count) - current = count - 1; - if (current < 0) - current = 0; - lb->Select(current); -} - -void AutoComplete::Select(const char *word) { - size_t lenWord = strlen(word); - int location = -1; - int start = 0; // lower bound of the api array block to search - int end = lb->Length() - 1; // upper bound of the api array block to search - while ((start <= end) && (location == -1)) { // Binary searching loop - int pivot = (start + end) / 2; - char item[maxItemLen]; - lb->GetValue(sortMatrix[pivot], item, maxItemLen); - int cond; - if (ignoreCase) - cond = CompareNCaseInsensitive(word, item, lenWord); - else - cond = strncmp(word, item, lenWord); - if (!cond) { - // Find first match - while (pivot > start) { - lb->GetValue(sortMatrix[pivot-1], item, maxItemLen); - if (ignoreCase) - cond = CompareNCaseInsensitive(word, item, lenWord); - else - cond = strncmp(word, item, lenWord); - if (0 != cond) - break; - --pivot; - } - location = pivot; - if (ignoreCase - && ignoreCaseBehaviour == SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) { - // Check for exact-case match - for (; pivot <= end; pivot++) { - lb->GetValue(sortMatrix[pivot], item, maxItemLen); - if (!strncmp(word, item, lenWord)) { - location = pivot; - break; - } - if (CompareNCaseInsensitive(word, item, lenWord)) - break; - } - } - } else if (cond < 0) { - end = pivot - 1; - } else if (cond > 0) { - start = pivot + 1; - } - } - if (location == -1) { - if (autoHide) - Cancel(); - else - lb->Select(-1); - } else { - if (autoSort == SC_ORDER_CUSTOM) { - // Check for a logically earlier match - char item[maxItemLen]; - for (int i = location + 1; i <= end; ++i) { - lb->GetValue(sortMatrix[i], item, maxItemLen); - if (CompareNCaseInsensitive(word, item, lenWord)) - break; - if (sortMatrix[i] < sortMatrix[location] && !strncmp(word, item, lenWord)) - location = i; - } - } - lb->Select(sortMatrix[location]); - } -} - diff --git a/qrenderdoc/3rdparty/scintilla/src/AutoComplete.h b/qrenderdoc/3rdparty/scintilla/src/AutoComplete.h deleted file mode 100644 index c35fa1a0e..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/AutoComplete.h +++ /dev/null @@ -1,95 +0,0 @@ -// Scintilla source code edit control -/** @file AutoComplete.h - ** Defines the auto completion list box. - **/ -// Copyright 1998-2003 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef AUTOCOMPLETE_H -#define AUTOCOMPLETE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - */ -class AutoComplete { - bool active; - std::string stopChars; - std::string fillUpChars; - char separator; - char typesep; // Type seperator - enum { maxItemLen=1000 }; - std::vector sortMatrix; - -public: - - bool ignoreCase; - bool chooseSingle; - ListBox *lb; - int posStart; - int startLen; - /// Should autocompletion be canceled if editor's currentPos <= startPos? - bool cancelAtStartPos; - bool autoHide; - bool dropRestOfWord; - unsigned int ignoreCaseBehaviour; - int widthLBDefault; - int heightLBDefault; - /** SC_ORDER_PRESORTED: Assume the list is presorted; selection will fail if it is not alphabetical
- * SC_ORDER_PERFORMSORT: Sort the list alphabetically; start up performance cost for sorting
- * SC_ORDER_CUSTOM: Handle non-alphabetical entries; start up performance cost for generating a sorted lookup table - */ - int autoSort; - - AutoComplete(); - ~AutoComplete(); - - /// Is the auto completion list displayed? - bool Active() const; - - /// Display the auto completion list positioned to be near a character position - void Start(Window &parent, int ctrlID, int position, Point location, - int startLen_, int lineHeight, bool unicodeMode, int technology); - - /// The stop chars are characters which, when typed, cause the auto completion list to disappear - void SetStopChars(const char *stopChars_); - bool IsStopChar(char ch); - - /// The fillup chars are characters which, when typed, fill up the selected word - void SetFillUpChars(const char *fillUpChars_); - bool IsFillUpChar(char ch); - - /// The separator character is used when interpreting the list in SetList - void SetSeparator(char separator_); - char GetSeparator() const; - - /// The typesep character is used for separating the word from the type - void SetTypesep(char separator_); - char GetTypesep() const; - - /// The list string contains a sequence of words separated by the separator character - void SetList(const char *list); - - /// Return the position of the currently selected list item - int GetSelection() const; - - /// Return the value of an item in the list - std::string GetValue(int item) const; - - void Show(bool show); - void Cancel(); - - /// Move the current list element by delta, scrolling appropriately - void Move(int delta); - - /// Select a list element that starts with word as the current element - void Select(const char *word); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/CallTip.cxx b/qrenderdoc/3rdparty/scintilla/src/CallTip.cxx deleted file mode 100644 index 541f4c683..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CallTip.cxx +++ /dev/null @@ -1,336 +0,0 @@ -// Scintilla source code edit control -/** @file CallTip.cxx - ** Code for displaying call tips. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include - -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" - -#include "StringCopy.h" -#include "Position.h" -#include "CallTip.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -CallTip::CallTip() { - wCallTip = 0; - inCallTipMode = false; - posStartCallTip = 0; - rectUp = PRectangle(0,0,0,0); - rectDown = PRectangle(0,0,0,0); - lineHeight = 1; - offsetMain = 0; - startHighlight = 0; - endHighlight = 0; - tabSize = 0; - above = false; - useStyleCallTip = false; // for backwards compatibility - - insetX = 5; - widthArrow = 14; - borderHeight = 2; // Extra line for border and an empty line at top and bottom. - verticalOffset = 1; - -#ifdef __APPLE__ - // proper apple colours for the default - colourBG = ColourDesired(0xff, 0xff, 0xc6); - colourUnSel = ColourDesired(0, 0, 0); -#else - colourBG = ColourDesired(0xff, 0xff, 0xff); - colourUnSel = ColourDesired(0x80, 0x80, 0x80); -#endif - colourSel = ColourDesired(0, 0, 0x80); - colourShade = ColourDesired(0, 0, 0); - colourLight = ColourDesired(0xc0, 0xc0, 0xc0); - codePage = 0; - clickPlace = 0; -} - -CallTip::~CallTip() { - font.Release(); - wCallTip.Destroy(); -} - -// Although this test includes 0, we should never see a \0 character. -static bool IsArrowCharacter(char ch) { - return (ch == 0) || (ch == '\001') || (ch == '\002'); -} - -// We ignore tabs unless a tab width has been set. -bool CallTip::IsTabCharacter(char ch) const { - return (tabSize > 0) && (ch == '\t'); -} - -int CallTip::NextTabPos(int x) const { - if (tabSize > 0) { // paranoia... not called unless this is true - x -= insetX; // position relative to text - x = (x + tabSize) / tabSize; // tab "number" - return tabSize*x + insetX; // position of next tab - } else { - return x + 1; // arbitrary - } -} - -// Draw a section of the call tip that does not include \n in one colour. -// The text may include up to numEnds tabs or arrow characters. -void CallTip::DrawChunk(Surface *surface, int &x, const char *s, - int posStart, int posEnd, int ytext, PRectangle rcClient, - bool highlight, bool draw) { - s += posStart; - int len = posEnd - posStart; - - // Divide the text into sections that are all text, or that are - // single arrows or single tab characters (if tabSize > 0). - int maxEnd = 0; - const int numEnds = 10; - int ends[numEnds + 2]; - for (int i=0; i 0) - ends[maxEnd++] = i; - ends[maxEnd++] = i+1; - } - } - ends[maxEnd++] = len; - int startSeg = 0; - int xEnd; - for (int seg = 0; seg startSeg) { - if (IsArrowCharacter(s[startSeg])) { - xEnd = x + widthArrow; - bool upArrow = s[startSeg] == '\001'; - rcClient.left = static_cast(x); - rcClient.right = static_cast(xEnd); - if (draw) { - const int halfWidth = widthArrow / 2 - 3; - const int quarterWidth = halfWidth / 2; - const int centreX = x + widthArrow / 2 - 1; - const int centreY = static_cast(rcClient.top + rcClient.bottom) / 2; - surface->FillRectangle(rcClient, colourBG); - PRectangle rcClientInner(rcClient.left + 1, rcClient.top + 1, - rcClient.right - 2, rcClient.bottom - 1); - surface->FillRectangle(rcClientInner, colourUnSel); - - if (upArrow) { // Up arrow - Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY + quarterWidth), - Point::FromInts(centreX + halfWidth, centreY + quarterWidth), - Point::FromInts(centreX, centreY - halfWidth + quarterWidth), - }; - surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG); - } else { // Down arrow - Point pts[] = { - Point::FromInts(centreX - halfWidth, centreY - quarterWidth), - Point::FromInts(centreX + halfWidth, centreY - quarterWidth), - Point::FromInts(centreX, centreY + halfWidth - quarterWidth), - }; - surface->Polygon(pts, ELEMENTS(pts), colourBG, colourBG); - } - } - offsetMain = xEnd; - if (upArrow) { - rectUp = rcClient; - } else { - rectDown = rcClient; - } - } else if (IsTabCharacter(s[startSeg])) { - xEnd = NextTabPos(x); - } else { - xEnd = x + RoundXYPosition(surface->WidthText(font, s + startSeg, endSeg - startSeg)); - if (draw) { - rcClient.left = static_cast(x); - rcClient.right = static_cast(xEnd); - surface->DrawTextTransparent(rcClient, font, static_cast(ytext), - s+startSeg, endSeg - startSeg, - highlight ? colourSel : colourUnSel); - } - } - x = xEnd; - startSeg = endSeg; - } - } -} - -int CallTip::PaintContents(Surface *surfaceWindow, bool draw) { - PRectangle rcClientPos = wCallTip.GetClientPosition(); - PRectangle rcClientSize(0.0f, 0.0f, rcClientPos.right - rcClientPos.left, - rcClientPos.bottom - rcClientPos.top); - PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1); - - // To make a nice small call tip window, it is only sized to fit most normal characters without accents - int ascent = RoundXYPosition(surfaceWindow->Ascent(font) - surfaceWindow->InternalLeading(font)); - - // For each line... - // Draw the definition in three parts: before highlight, highlighted, after highlight - int ytext = static_cast(rcClient.top) + ascent + 1; - rcClient.bottom = ytext + surfaceWindow->Descent(font) + 1; - const char *chunkVal = val.c_str(); - bool moreChunks = true; - int maxWidth = 0; - - while (moreChunks) { - const char *chunkEnd = strchr(chunkVal, '\n'); - if (chunkEnd == NULL) { - chunkEnd = chunkVal + strlen(chunkVal); - moreChunks = false; - } - int chunkOffset = static_cast(chunkVal - val.c_str()); - int chunkLength = static_cast(chunkEnd - chunkVal); - int chunkEndOffset = chunkOffset + chunkLength; - int thisStartHighlight = Platform::Maximum(startHighlight, chunkOffset); - thisStartHighlight = Platform::Minimum(thisStartHighlight, chunkEndOffset); - thisStartHighlight -= chunkOffset; - int thisEndHighlight = Platform::Maximum(endHighlight, chunkOffset); - thisEndHighlight = Platform::Minimum(thisEndHighlight, chunkEndOffset); - thisEndHighlight -= chunkOffset; - rcClient.top = static_cast(ytext - ascent - 1); - - int x = insetX; // start each line at this inset - - DrawChunk(surfaceWindow, x, chunkVal, 0, thisStartHighlight, - ytext, rcClient, false, draw); - DrawChunk(surfaceWindow, x, chunkVal, thisStartHighlight, thisEndHighlight, - ytext, rcClient, true, draw); - DrawChunk(surfaceWindow, x, chunkVal, thisEndHighlight, chunkLength, - ytext, rcClient, false, draw); - - chunkVal = chunkEnd + 1; - ytext += lineHeight; - rcClient.bottom += lineHeight; - maxWidth = Platform::Maximum(maxWidth, x); - } - return maxWidth; -} - -void CallTip::PaintCT(Surface *surfaceWindow) { - if (val.empty()) - return; - PRectangle rcClientPos = wCallTip.GetClientPosition(); - PRectangle rcClientSize(0.0f, 0.0f, rcClientPos.right - rcClientPos.left, - rcClientPos.bottom - rcClientPos.top); - PRectangle rcClient(1.0f, 1.0f, rcClientSize.right - 1, rcClientSize.bottom - 1); - - surfaceWindow->FillRectangle(rcClient, colourBG); - - offsetMain = insetX; // initial alignment assuming no arrows - PaintContents(surfaceWindow, true); - -#ifndef __APPLE__ - // OSX doesn't put borders on "help tags" - // Draw a raised border around the edges of the window - surfaceWindow->MoveTo(0, static_cast(rcClientSize.bottom) - 1); - surfaceWindow->PenColour(colourShade); - surfaceWindow->LineTo(static_cast(rcClientSize.right) - 1, static_cast(rcClientSize.bottom) - 1); - surfaceWindow->LineTo(static_cast(rcClientSize.right) - 1, 0); - surfaceWindow->PenColour(colourLight); - surfaceWindow->LineTo(0, 0); - surfaceWindow->LineTo(0, static_cast(rcClientSize.bottom) - 1); -#endif -} - -void CallTip::MouseClick(Point pt) { - clickPlace = 0; - if (rectUp.Contains(pt)) - clickPlace = 1; - if (rectDown.Contains(pt)) - clickPlace = 2; -} - -PRectangle CallTip::CallTipStart(int pos, Point pt, int textHeight, const char *defn, - const char *faceName, int size, - int codePage_, int characterSet, - int technology, Window &wParent) { - clickPlace = 0; - val = defn; - codePage = codePage_; - Surface *surfaceMeasure = Surface::Allocate(technology); - if (!surfaceMeasure) - return PRectangle(); - surfaceMeasure->Init(wParent.GetID()); - surfaceMeasure->SetUnicodeMode(SC_CP_UTF8 == codePage); - surfaceMeasure->SetDBCSMode(codePage); - startHighlight = 0; - endHighlight = 0; - inCallTipMode = true; - posStartCallTip = pos; - XYPOSITION deviceHeight = static_cast(surfaceMeasure->DeviceHeightFont(size)); - FontParameters fp(faceName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, SC_WEIGHT_NORMAL, false, 0, technology, characterSet); - font.Create(fp); - // Look for multiple lines in the text - // Only support \n here - simply means container must avoid \r! - int numLines = 1; - const char *newline; - const char *look = val.c_str(); - rectUp = PRectangle(0,0,0,0); - rectDown = PRectangle(0,0,0,0); - offsetMain = insetX; // changed to right edge of any arrows - int width = PaintContents(surfaceMeasure, false) + insetX; - while ((newline = strchr(look, '\n')) != NULL) { - look = newline + 1; - numLines++; - } - lineHeight = RoundXYPosition(surfaceMeasure->Height(font)); - - // The returned - // rectangle is aligned to the right edge of the last arrow encountered in - // the tip text, else to the tip text left edge. - int height = lineHeight * numLines - static_cast(surfaceMeasure->InternalLeading(font)) + borderHeight * 2; - delete surfaceMeasure; - if (above) { - return PRectangle(pt.x - offsetMain, pt.y - verticalOffset - height, pt.x + width - offsetMain, pt.y - verticalOffset); - } else { - return PRectangle(pt.x - offsetMain, pt.y + verticalOffset + textHeight, pt.x + width - offsetMain, pt.y + verticalOffset + textHeight + height); - } -} - -void CallTip::CallTipCancel() { - inCallTipMode = false; - if (wCallTip.Created()) { - wCallTip.Destroy(); - } -} - -void CallTip::SetHighlight(int start, int end) { - // Avoid flashing by checking something has really changed - if ((start != startHighlight) || (end != endHighlight)) { - startHighlight = start; - endHighlight = (end > start) ? end : start; - if (wCallTip.Created()) { - wCallTip.InvalidateAll(); - } - } -} - -// Set the tab size (sizes > 0 enable the use of tabs). This also enables the -// use of the STYLE_CALLTIP. -void CallTip::SetTabSize(int tabSz) { - tabSize = tabSz; - useStyleCallTip = true; -} - -// Set the calltip position, below the text by default or if above is false -// else above the text. -void CallTip::SetPosition(bool aboveText) { - above = aboveText; -} - -// It might be better to have two access functions for this and to use -// them for all settings of colours. -void CallTip::SetForeBack(const ColourDesired &fore, const ColourDesired &back) { - colourBG = back; - colourUnSel = fore; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/CallTip.h b/qrenderdoc/3rdparty/scintilla/src/CallTip.h deleted file mode 100644 index 840aa26ac..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CallTip.h +++ /dev/null @@ -1,93 +0,0 @@ -// Scintilla source code edit control -/** @file CallTip.h - ** Interface to the call tip control. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CALLTIP_H -#define CALLTIP_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - */ -class CallTip { - int startHighlight; // character offset to start and... - int endHighlight; // ...end of highlighted text - std::string val; - Font font; - PRectangle rectUp; // rectangle of last up angle in the tip - PRectangle rectDown; // rectangle of last down arrow in the tip - int lineHeight; // vertical line spacing - int offsetMain; // The alignment point of the call tip - int tabSize; // Tab size in pixels, <=0 no TAB expand - bool useStyleCallTip; // if true, STYLE_CALLTIP should be used - bool above; // if true, display calltip above text - - // Private so CallTip objects can not be copied - CallTip(const CallTip &); - CallTip &operator=(const CallTip &); - void DrawChunk(Surface *surface, int &x, const char *s, - int posStart, int posEnd, int ytext, PRectangle rcClient, - bool highlight, bool draw); - int PaintContents(Surface *surfaceWindow, bool draw); - bool IsTabCharacter(char c) const; - int NextTabPos(int x) const; - -public: - Window wCallTip; - Window wDraw; - bool inCallTipMode; - int posStartCallTip; - ColourDesired colourBG; - ColourDesired colourUnSel; - ColourDesired colourSel; - ColourDesired colourShade; - ColourDesired colourLight; - int codePage; - int clickPlace; - - int insetX; // text inset in x from calltip border - int widthArrow; - int borderHeight; - int verticalOffset; // pixel offset up or down of the calltip with respect to the line - - CallTip(); - ~CallTip(); - - void PaintCT(Surface *surfaceWindow); - - void MouseClick(Point pt); - - /// Setup the calltip and return a rectangle of the area required. - PRectangle CallTipStart(int pos, Point pt, int textHeight, const char *defn, - const char *faceName, int size, int codePage_, - int characterSet, int technology, Window &wParent); - - void CallTipCancel(); - - /// Set a range of characters to be displayed in a highlight style. - /// Commonly used to highlight the current parameter. - void SetHighlight(int start, int end); - - /// Set the tab size in pixels for the call tip. 0 or -ve means no tab expand. - void SetTabSize(int tabSz); - - /// Set calltip position. - void SetPosition(bool aboveText); - - /// Used to determine which STYLE_xxxx to use for call tip information - bool UseStyleCallTip() const { return useStyleCallTip;} - - // Modify foreground and background colours - void SetForeBack(const ColourDesired &fore, const ColourDesired &back); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/CaseConvert.cxx b/qrenderdoc/3rdparty/scintilla/src/CaseConvert.cxx deleted file mode 100644 index 4fb755903..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CaseConvert.cxx +++ /dev/null @@ -1,644 +0,0 @@ -// Scintilla source code edit control -// Encoding: UTF-8 -/** @file CaseConvert.cxx - ** Case fold characters and convert them to upper or lower case. - ** Tables automatically regenerated by scripts/GenerateCaseConvert.py - ** Should only be rarely regenerated for new versions of Unicode. - **/ -// Copyright 2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include -#include -#include -#include - -#include "StringCopy.h" -#include "CaseConvert.h" -#include "UniConversion.h" -#include "UnicodeFromUTF8.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -namespace { - // Use an unnamed namespace to protect the declarations from name conflicts - -// Unicode code points are ordered by groups and follow patterns. -// Most characters (pitch==1) are in ranges for a particular alphabet and their -// upper case forms are a fixed distance away. -// Another pattern (pitch==2) is where each lower case letter is preceded by -// the upper case form. These are also grouped into ranges. - -int symmetricCaseConversionRanges[] = { -//lower, upper, range length, range pitch -//++Autogenerated -- start of section automatically generated -//**\(\*\n\) -97,65,26,1, -224,192,23,1, -248,216,7,1, -257,256,24,2, -314,313,8,2, -331,330,23,2, -462,461,8,2, -479,478,9,2, -505,504,20,2, -547,546,9,2, -583,582,5,2, -945,913,17,1, -963,931,9,1, -985,984,12,2, -1072,1040,32,1, -1104,1024,16,1, -1121,1120,17,2, -1163,1162,27,2, -1218,1217,7,2, -1233,1232,44,2, -1377,1329,38,1, -7681,7680,75,2, -7841,7840,48,2, -7936,7944,8,1, -7952,7960,6,1, -7968,7976,8,1, -7984,7992,8,1, -8000,8008,6,1, -8032,8040,8,1, -8560,8544,16,1, -9424,9398,26,1, -11312,11264,47,1, -11393,11392,50,2, -11520,4256,38,1, -42561,42560,23,2, -42625,42624,12,2, -42787,42786,7,2, -42803,42802,31,2, -42879,42878,5,2, -42913,42912,5,2, -65345,65313,26,1, -66600,66560,40,1, - -//--Autogenerated -- end of section automatically generated -}; - -// Code points that are symmetric but don't fit into a range of similar characters -// are listed here. - -int symmetricCaseConversions[] = { -//lower, upper -//++Autogenerated -- start of section automatically generated -//**1 \(\*\n\) -255,376, -307,306, -309,308, -311,310, -378,377, -380,379, -382,381, -384,579, -387,386, -389,388, -392,391, -396,395, -402,401, -405,502, -409,408, -410,573, -414,544, -417,416, -419,418, -421,420, -424,423, -429,428, -432,431, -436,435, -438,437, -441,440, -445,444, -447,503, -454,452, -457,455, -460,458, -477,398, -499,497, -501,500, -572,571, -575,11390, -576,11391, -578,577, -592,11375, -593,11373, -594,11376, -595,385, -596,390, -598,393, -599,394, -601,399, -603,400, -608,403, -611,404, -613,42893, -614,42922, -616,407, -617,406, -619,11362, -623,412, -625,11374, -626,413, -629,415, -637,11364, -640,422, -643,425, -648,430, -649,580, -650,433, -651,434, -652,581, -658,439, -881,880, -883,882, -887,886, -891,1021, -892,1022, -893,1023, -940,902, -941,904, -942,905, -943,906, -972,908, -973,910, -974,911, -983,975, -1010,1017, -1016,1015, -1019,1018, -1231,1216, -7545,42877, -7549,11363, -8017,8025, -8019,8027, -8021,8029, -8023,8031, -8048,8122, -8049,8123, -8050,8136, -8051,8137, -8052,8138, -8053,8139, -8054,8154, -8055,8155, -8056,8184, -8057,8185, -8058,8170, -8059,8171, -8060,8186, -8061,8187, -8112,8120, -8113,8121, -8144,8152, -8145,8153, -8160,8168, -8161,8169, -8165,8172, -8526,8498, -8580,8579, -11361,11360, -11365,570, -11366,574, -11368,11367, -11370,11369, -11372,11371, -11379,11378, -11382,11381, -11500,11499, -11502,11501, -11507,11506, -11559,4295, -11565,4301, -42874,42873, -42876,42875, -42892,42891, -42897,42896, -42899,42898, - -//--Autogenerated -- end of section automatically generated -}; - -// Characters that have complex case conversions are listed here. -// This includes cases where more than one character is needed for a conversion, -// folding is different to lowering, or (as appropriate) upper(lower(x)) != x or -// lower(upper(x)) != x. - -const char *complexCaseConversions = -// Original | Folded | Upper | Lower | -//++Autogenerated -- start of section automatically generated -//**2 \(\*\n\) -"\xc2\xb5|\xce\xbc|\xce\x9c||" -"\xc3\x9f|ss|SS||" -"\xc4\xb0|i\xcc\x87||i\xcc\x87|" -"\xc4\xb1||I||" -"\xc5\x89|\xca\xbcn|\xca\xbcN||" -"\xc5\xbf|s|S||" -"\xc7\x85|\xc7\x86|\xc7\x84|\xc7\x86|" -"\xc7\x88|\xc7\x89|\xc7\x87|\xc7\x89|" -"\xc7\x8b|\xc7\x8c|\xc7\x8a|\xc7\x8c|" -"\xc7\xb0|j\xcc\x8c|J\xcc\x8c||" -"\xc7\xb2|\xc7\xb3|\xc7\xb1|\xc7\xb3|" -"\xcd\x85|\xce\xb9|\xce\x99||" -"\xce\x90|\xce\xb9\xcc\x88\xcc\x81|\xce\x99\xcc\x88\xcc\x81||" -"\xce\xb0|\xcf\x85\xcc\x88\xcc\x81|\xce\xa5\xcc\x88\xcc\x81||" -"\xcf\x82|\xcf\x83|\xce\xa3||" -"\xcf\x90|\xce\xb2|\xce\x92||" -"\xcf\x91|\xce\xb8|\xce\x98||" -"\xcf\x95|\xcf\x86|\xce\xa6||" -"\xcf\x96|\xcf\x80|\xce\xa0||" -"\xcf\xb0|\xce\xba|\xce\x9a||" -"\xcf\xb1|\xcf\x81|\xce\xa1||" -"\xcf\xb4|\xce\xb8||\xce\xb8|" -"\xcf\xb5|\xce\xb5|\xce\x95||" -"\xd6\x87|\xd5\xa5\xd6\x82|\xd4\xb5\xd5\x92||" -"\xe1\xba\x96|h\xcc\xb1|H\xcc\xb1||" -"\xe1\xba\x97|t\xcc\x88|T\xcc\x88||" -"\xe1\xba\x98|w\xcc\x8a|W\xcc\x8a||" -"\xe1\xba\x99|y\xcc\x8a|Y\xcc\x8a||" -"\xe1\xba\x9a|a\xca\xbe|A\xca\xbe||" -"\xe1\xba\x9b|\xe1\xb9\xa1|\xe1\xb9\xa0||" -"\xe1\xba\x9e|ss||\xc3\x9f|" -"\xe1\xbd\x90|\xcf\x85\xcc\x93|\xce\xa5\xcc\x93||" -"\xe1\xbd\x92|\xcf\x85\xcc\x93\xcc\x80|\xce\xa5\xcc\x93\xcc\x80||" -"\xe1\xbd\x94|\xcf\x85\xcc\x93\xcc\x81|\xce\xa5\xcc\x93\xcc\x81||" -"\xe1\xbd\x96|\xcf\x85\xcc\x93\xcd\x82|\xce\xa5\xcc\x93\xcd\x82||" -"\xe1\xbe\x80|\xe1\xbc\x80\xce\xb9|\xe1\xbc\x88\xce\x99||" -"\xe1\xbe\x81|\xe1\xbc\x81\xce\xb9|\xe1\xbc\x89\xce\x99||" -"\xe1\xbe\x82|\xe1\xbc\x82\xce\xb9|\xe1\xbc\x8a\xce\x99||" -"\xe1\xbe\x83|\xe1\xbc\x83\xce\xb9|\xe1\xbc\x8b\xce\x99||" -"\xe1\xbe\x84|\xe1\xbc\x84\xce\xb9|\xe1\xbc\x8c\xce\x99||" -"\xe1\xbe\x85|\xe1\xbc\x85\xce\xb9|\xe1\xbc\x8d\xce\x99||" -"\xe1\xbe\x86|\xe1\xbc\x86\xce\xb9|\xe1\xbc\x8e\xce\x99||" -"\xe1\xbe\x87|\xe1\xbc\x87\xce\xb9|\xe1\xbc\x8f\xce\x99||" -"\xe1\xbe\x88|\xe1\xbc\x80\xce\xb9|\xe1\xbc\x88\xce\x99|\xe1\xbe\x80|" -"\xe1\xbe\x89|\xe1\xbc\x81\xce\xb9|\xe1\xbc\x89\xce\x99|\xe1\xbe\x81|" -"\xe1\xbe\x8a|\xe1\xbc\x82\xce\xb9|\xe1\xbc\x8a\xce\x99|\xe1\xbe\x82|" -"\xe1\xbe\x8b|\xe1\xbc\x83\xce\xb9|\xe1\xbc\x8b\xce\x99|\xe1\xbe\x83|" -"\xe1\xbe\x8c|\xe1\xbc\x84\xce\xb9|\xe1\xbc\x8c\xce\x99|\xe1\xbe\x84|" -"\xe1\xbe\x8d|\xe1\xbc\x85\xce\xb9|\xe1\xbc\x8d\xce\x99|\xe1\xbe\x85|" -"\xe1\xbe\x8e|\xe1\xbc\x86\xce\xb9|\xe1\xbc\x8e\xce\x99|\xe1\xbe\x86|" -"\xe1\xbe\x8f|\xe1\xbc\x87\xce\xb9|\xe1\xbc\x8f\xce\x99|\xe1\xbe\x87|" -"\xe1\xbe\x90|\xe1\xbc\xa0\xce\xb9|\xe1\xbc\xa8\xce\x99||" -"\xe1\xbe\x91|\xe1\xbc\xa1\xce\xb9|\xe1\xbc\xa9\xce\x99||" -"\xe1\xbe\x92|\xe1\xbc\xa2\xce\xb9|\xe1\xbc\xaa\xce\x99||" -"\xe1\xbe\x93|\xe1\xbc\xa3\xce\xb9|\xe1\xbc\xab\xce\x99||" -"\xe1\xbe\x94|\xe1\xbc\xa4\xce\xb9|\xe1\xbc\xac\xce\x99||" -"\xe1\xbe\x95|\xe1\xbc\xa5\xce\xb9|\xe1\xbc\xad\xce\x99||" -"\xe1\xbe\x96|\xe1\xbc\xa6\xce\xb9|\xe1\xbc\xae\xce\x99||" -"\xe1\xbe\x97|\xe1\xbc\xa7\xce\xb9|\xe1\xbc\xaf\xce\x99||" -"\xe1\xbe\x98|\xe1\xbc\xa0\xce\xb9|\xe1\xbc\xa8\xce\x99|\xe1\xbe\x90|" -"\xe1\xbe\x99|\xe1\xbc\xa1\xce\xb9|\xe1\xbc\xa9\xce\x99|\xe1\xbe\x91|" -"\xe1\xbe\x9a|\xe1\xbc\xa2\xce\xb9|\xe1\xbc\xaa\xce\x99|\xe1\xbe\x92|" -"\xe1\xbe\x9b|\xe1\xbc\xa3\xce\xb9|\xe1\xbc\xab\xce\x99|\xe1\xbe\x93|" -"\xe1\xbe\x9c|\xe1\xbc\xa4\xce\xb9|\xe1\xbc\xac\xce\x99|\xe1\xbe\x94|" -"\xe1\xbe\x9d|\xe1\xbc\xa5\xce\xb9|\xe1\xbc\xad\xce\x99|\xe1\xbe\x95|" -"\xe1\xbe\x9e|\xe1\xbc\xa6\xce\xb9|\xe1\xbc\xae\xce\x99|\xe1\xbe\x96|" -"\xe1\xbe\x9f|\xe1\xbc\xa7\xce\xb9|\xe1\xbc\xaf\xce\x99|\xe1\xbe\x97|" -"\xe1\xbe\xa0|\xe1\xbd\xa0\xce\xb9|\xe1\xbd\xa8\xce\x99||" -"\xe1\xbe\xa1|\xe1\xbd\xa1\xce\xb9|\xe1\xbd\xa9\xce\x99||" -"\xe1\xbe\xa2|\xe1\xbd\xa2\xce\xb9|\xe1\xbd\xaa\xce\x99||" -"\xe1\xbe\xa3|\xe1\xbd\xa3\xce\xb9|\xe1\xbd\xab\xce\x99||" -"\xe1\xbe\xa4|\xe1\xbd\xa4\xce\xb9|\xe1\xbd\xac\xce\x99||" -"\xe1\xbe\xa5|\xe1\xbd\xa5\xce\xb9|\xe1\xbd\xad\xce\x99||" -"\xe1\xbe\xa6|\xe1\xbd\xa6\xce\xb9|\xe1\xbd\xae\xce\x99||" -"\xe1\xbe\xa7|\xe1\xbd\xa7\xce\xb9|\xe1\xbd\xaf\xce\x99||" -"\xe1\xbe\xa8|\xe1\xbd\xa0\xce\xb9|\xe1\xbd\xa8\xce\x99|\xe1\xbe\xa0|" -"\xe1\xbe\xa9|\xe1\xbd\xa1\xce\xb9|\xe1\xbd\xa9\xce\x99|\xe1\xbe\xa1|" -"\xe1\xbe\xaa|\xe1\xbd\xa2\xce\xb9|\xe1\xbd\xaa\xce\x99|\xe1\xbe\xa2|" -"\xe1\xbe\xab|\xe1\xbd\xa3\xce\xb9|\xe1\xbd\xab\xce\x99|\xe1\xbe\xa3|" -"\xe1\xbe\xac|\xe1\xbd\xa4\xce\xb9|\xe1\xbd\xac\xce\x99|\xe1\xbe\xa4|" -"\xe1\xbe\xad|\xe1\xbd\xa5\xce\xb9|\xe1\xbd\xad\xce\x99|\xe1\xbe\xa5|" -"\xe1\xbe\xae|\xe1\xbd\xa6\xce\xb9|\xe1\xbd\xae\xce\x99|\xe1\xbe\xa6|" -"\xe1\xbe\xaf|\xe1\xbd\xa7\xce\xb9|\xe1\xbd\xaf\xce\x99|\xe1\xbe\xa7|" -"\xe1\xbe\xb2|\xe1\xbd\xb0\xce\xb9|\xe1\xbe\xba\xce\x99||" -"\xe1\xbe\xb3|\xce\xb1\xce\xb9|\xce\x91\xce\x99||" -"\xe1\xbe\xb4|\xce\xac\xce\xb9|\xce\x86\xce\x99||" -"\xe1\xbe\xb6|\xce\xb1\xcd\x82|\xce\x91\xcd\x82||" -"\xe1\xbe\xb7|\xce\xb1\xcd\x82\xce\xb9|\xce\x91\xcd\x82\xce\x99||" -"\xe1\xbe\xbc|\xce\xb1\xce\xb9|\xce\x91\xce\x99|\xe1\xbe\xb3|" -"\xe1\xbe\xbe|\xce\xb9|\xce\x99||" -"\xe1\xbf\x82|\xe1\xbd\xb4\xce\xb9|\xe1\xbf\x8a\xce\x99||" -"\xe1\xbf\x83|\xce\xb7\xce\xb9|\xce\x97\xce\x99||" -"\xe1\xbf\x84|\xce\xae\xce\xb9|\xce\x89\xce\x99||" -"\xe1\xbf\x86|\xce\xb7\xcd\x82|\xce\x97\xcd\x82||" -"\xe1\xbf\x87|\xce\xb7\xcd\x82\xce\xb9|\xce\x97\xcd\x82\xce\x99||" -"\xe1\xbf\x8c|\xce\xb7\xce\xb9|\xce\x97\xce\x99|\xe1\xbf\x83|" -"\xe1\xbf\x92|\xce\xb9\xcc\x88\xcc\x80|\xce\x99\xcc\x88\xcc\x80||" -"\xe1\xbf\x93|\xce\xb9\xcc\x88\xcc\x81|\xce\x99\xcc\x88\xcc\x81||" -"\xe1\xbf\x96|\xce\xb9\xcd\x82|\xce\x99\xcd\x82||" -"\xe1\xbf\x97|\xce\xb9\xcc\x88\xcd\x82|\xce\x99\xcc\x88\xcd\x82||" -"\xe1\xbf\xa2|\xcf\x85\xcc\x88\xcc\x80|\xce\xa5\xcc\x88\xcc\x80||" -"\xe1\xbf\xa3|\xcf\x85\xcc\x88\xcc\x81|\xce\xa5\xcc\x88\xcc\x81||" -"\xe1\xbf\xa4|\xcf\x81\xcc\x93|\xce\xa1\xcc\x93||" -"\xe1\xbf\xa6|\xcf\x85\xcd\x82|\xce\xa5\xcd\x82||" -"\xe1\xbf\xa7|\xcf\x85\xcc\x88\xcd\x82|\xce\xa5\xcc\x88\xcd\x82||" -"\xe1\xbf\xb2|\xe1\xbd\xbc\xce\xb9|\xe1\xbf\xba\xce\x99||" -"\xe1\xbf\xb3|\xcf\x89\xce\xb9|\xce\xa9\xce\x99||" -"\xe1\xbf\xb4|\xcf\x8e\xce\xb9|\xce\x8f\xce\x99||" -"\xe1\xbf\xb6|\xcf\x89\xcd\x82|\xce\xa9\xcd\x82||" -"\xe1\xbf\xb7|\xcf\x89\xcd\x82\xce\xb9|\xce\xa9\xcd\x82\xce\x99||" -"\xe1\xbf\xbc|\xcf\x89\xce\xb9|\xce\xa9\xce\x99|\xe1\xbf\xb3|" -"\xe2\x84\xa6|\xcf\x89||\xcf\x89|" -"\xe2\x84\xaa|k||k|" -"\xe2\x84\xab|\xc3\xa5||\xc3\xa5|" -"\xef\xac\x80|ff|FF||" -"\xef\xac\x81|fi|FI||" -"\xef\xac\x82|fl|FL||" -"\xef\xac\x83|ffi|FFI||" -"\xef\xac\x84|ffl|FFL||" -"\xef\xac\x85|st|ST||" -"\xef\xac\x86|st|ST||" -"\xef\xac\x93|\xd5\xb4\xd5\xb6|\xd5\x84\xd5\x86||" -"\xef\xac\x94|\xd5\xb4\xd5\xa5|\xd5\x84\xd4\xb5||" -"\xef\xac\x95|\xd5\xb4\xd5\xab|\xd5\x84\xd4\xbb||" -"\xef\xac\x96|\xd5\xbe\xd5\xb6|\xd5\x8e\xd5\x86||" -"\xef\xac\x97|\xd5\xb4\xd5\xad|\xd5\x84\xd4\xbd||" - -//--Autogenerated -- end of section automatically generated -; - -class CaseConverter : public ICaseConverter { - // Maximum length of a case conversion result is 6 bytes in UTF-8 - enum { maxConversionLength=6 }; - struct ConversionString { - char conversion[maxConversionLength+1]; - ConversionString() { - conversion[0] = '\0'; - } - }; - // Conversions are initially store in a vector of structs but then decomposed into - // parallel arrays as that is about 10% faster to search. - struct CharacterConversion { - int character; - ConversionString conversion; - CharacterConversion(int character_=0, const char *conversion_="") : character(character_) { - StringCopy(conversion.conversion, conversion_); - } - bool operator<(const CharacterConversion &other) const { - return character < other.character; - } - }; - typedef std::vector CharacterToConversion; - CharacterToConversion characterToConversion; - // The parallel arrays - std::vector characters; - std::vector conversions; - -public: - CaseConverter() { - } - bool Initialised() const { - return characters.size() > 0; - } - void Add(int character, const char *conversion) { - characterToConversion.push_back(CharacterConversion(character, conversion)); - } - const char *Find(int character) { - const std::vector::iterator it = std::lower_bound(characters.begin(), characters.end(), character); - if (it == characters.end()) - return 0; - else if (*it == character) - return conversions[it - characters.begin()].conversion; - else - return 0; - } - size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed) { - size_t lenConverted = 0; - size_t mixedPos = 0; - unsigned char bytes[UTF8MaxBytes + 1]; - while (mixedPos < lenMixed) { - const unsigned char leadByte = static_cast(mixed[mixedPos]); - const char *caseConverted = 0; - size_t lenMixedChar = 1; - if (UTF8IsAscii(leadByte)) { - caseConverted = Find(leadByte); - } else { - bytes[0] = leadByte; - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - for (int b=1; b= sizeConverted) - return 0; - } - } else { - // Character has no conversion so copy the input to output - for (size_t i=0; i= sizeConverted) - return 0; - } - } - mixedPos += lenMixedChar; - } - return lenConverted; - } - void FinishedAdding() { - std::sort(characterToConversion.begin(), characterToConversion.end()); - characters.reserve(characterToConversion.size()); - conversions.reserve(characterToConversion.size()); - for (CharacterToConversion::iterator it = characterToConversion.begin(); it != characterToConversion.end(); ++it) { - characters.push_back(it->character); - conversions.push_back(it->conversion); - } - // Empty the original calculated data completely - CharacterToConversion().swap(characterToConversion); - } -}; - -CaseConverter caseConvFold; -CaseConverter caseConvUp; -CaseConverter caseConvLow; - -void UTF8FromUTF32Character(int uch, char *putf) { - size_t k = 0; - if (uch < 0x80) { - putf[k++] = static_cast(uch); - } else if (uch < 0x800) { - putf[k++] = static_cast(0xC0 | (uch >> 6)); - putf[k++] = static_cast(0x80 | (uch & 0x3f)); - } else if (uch < 0x10000) { - putf[k++] = static_cast(0xE0 | (uch >> 12)); - putf[k++] = static_cast(0x80 | ((uch >> 6) & 0x3f)); - putf[k++] = static_cast(0x80 | (uch & 0x3f)); - } else { - putf[k++] = static_cast(0xF0 | (uch >> 18)); - putf[k++] = static_cast(0x80 | ((uch >> 12) & 0x3f)); - putf[k++] = static_cast(0x80 | ((uch >> 6) & 0x3f)); - putf[k++] = static_cast(0x80 | (uch & 0x3f)); - } - putf[k] = 0; -} - -void AddSymmetric(enum CaseConversion conversion, int lower,int upper) { - char lowerUTF8[UTF8MaxBytes+1]; - UTF8FromUTF32Character(lower, lowerUTF8); - char upperUTF8[UTF8MaxBytes+1]; - UTF8FromUTF32Character(upper, upperUTF8); - - switch (conversion) { - case CaseConversionFold: - caseConvFold.Add(upper, lowerUTF8); - break; - case CaseConversionUpper: - caseConvUp.Add(lower, upperUTF8); - break; - case CaseConversionLower: - caseConvLow.Add(upper, lowerUTF8); - break; - } -} - -void SetupConversions(enum CaseConversion conversion) { - // First initialize for the symmetric ranges - for (size_t i=0; i(originUTF8)); - - if (conversion == CaseConversionFold && foldedUTF8[0]) { - caseConvFold.Add(character, foldedUTF8); - } - - if (conversion == CaseConversionUpper && upperUTF8[0]) { - caseConvUp.Add(character, upperUTF8); - } - - if (conversion == CaseConversionLower && lowerUTF8[0]) { - caseConvLow.Add(character, lowerUTF8); - } - } - - switch (conversion) { - case CaseConversionFold: - caseConvFold.FinishedAdding(); - break; - case CaseConversionUpper: - caseConvUp.FinishedAdding(); - break; - case CaseConversionLower: - caseConvLow.FinishedAdding(); - break; - } -} - -CaseConverter *ConverterForConversion(enum CaseConversion conversion) { - switch (conversion) { - case CaseConversionFold: - return &caseConvFold; - case CaseConversionUpper: - return &caseConvUp; - case CaseConversionLower: - return &caseConvLow; - } - return 0; -} - -} - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -ICaseConverter *ConverterFor(enum CaseConversion conversion) { - CaseConverter *pCaseConv = ConverterForConversion(conversion); - if (!pCaseConv->Initialised()) - SetupConversions(conversion); - return pCaseConv; -} - -const char *CaseConvert(int character, enum CaseConversion conversion) { - CaseConverter *pCaseConv = ConverterForConversion(conversion); - if (!pCaseConv->Initialised()) - SetupConversions(conversion); - return pCaseConv->Find(character); -} - -size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion) { - CaseConverter *pCaseConv = ConverterForConversion(conversion); - if (!pCaseConv->Initialised()) - SetupConversions(conversion); - return pCaseConv->CaseConvertString(converted, sizeConverted, mixed, lenMixed); -} - -std::string CaseConvertString(const std::string &s, enum CaseConversion conversion) { - std::string retMapped(s.length() * maxExpansionCaseConversion, 0); - size_t lenMapped = CaseConvertString(&retMapped[0], retMapped.length(), s.c_str(), s.length(), - conversion); - retMapped.resize(lenMapped); - return retMapped; -} - -#ifdef SCI_NAMESPACE -} -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/CaseConvert.h b/qrenderdoc/3rdparty/scintilla/src/CaseConvert.h deleted file mode 100644 index 7a0100300..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CaseConvert.h +++ /dev/null @@ -1,50 +0,0 @@ -// Scintilla source code edit control -// Encoding: UTF-8 -/** @file CaseConvert.h - ** Performs Unicode case conversions. - ** Does not handle locale-sensitive case conversion. - **/ -// Copyright 2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CASECONVERT_H -#define CASECONVERT_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -enum CaseConversion { - CaseConversionFold, - CaseConversionUpper, - CaseConversionLower -}; - -class ICaseConverter { -public: - virtual size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed) = 0; -}; - -ICaseConverter *ConverterFor(enum CaseConversion conversion); - -// Returns a UTF-8 string. Empty when no conversion -const char *CaseConvert(int character, enum CaseConversion conversion); - -// When performing CaseConvertString, the converted value may be up to 3 times longer than the input. -// Ligatures are often decomposed into multiple characters and long cases include: -// Î "\xce\x90" folds to Î¹ÌˆÌ "\xce\xb9\xcc\x88\xcc\x81" -const int maxExpansionCaseConversion=3; - -// Converts a mixed case string using a particular conversion. -// Result may be a different length to input and the length is the return value. -// If there is not enough space then 0 is returned. -size_t CaseConvertString(char *converted, size_t sizeConverted, const char *mixed, size_t lenMixed, enum CaseConversion conversion); - -// Converts a mixed case string using a particular conversion. -std::string CaseConvertString(const std::string &s, enum CaseConversion conversion); - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/CaseFolder.cxx b/qrenderdoc/3rdparty/scintilla/src/CaseFolder.cxx deleted file mode 100644 index 4e095df1a..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CaseFolder.cxx +++ /dev/null @@ -1,69 +0,0 @@ -// Scintilla source code edit control -/** @file CaseFolder.cxx - ** Classes for case folding. - **/ -// Copyright 1998-2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include - -#include "CaseFolder.h" -#include "CaseConvert.h" -#include "UniConversion.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -CaseFolder::~CaseFolder() { -} - -CaseFolderTable::CaseFolderTable() { - for (size_t iChar=0; iChar(iChar); - } -} - -CaseFolderTable::~CaseFolderTable() { -} - -size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { - if (lenMixed > sizeFolded) { - return 0; - } else { - for (size_t i=0; i(mixed[i])]; - } - return lenMixed; - } -} - -void CaseFolderTable::SetTranslation(char ch, char chTranslation) { - mapping[static_cast(ch)] = chTranslation; -} - -void CaseFolderTable::StandardASCII() { - for (size_t iChar=0; iChar= 'A' && iChar <= 'Z') { - mapping[iChar] = static_cast(iChar - 'A' + 'a'); - } else { - mapping[iChar] = static_cast(iChar); - } - } -} - -CaseFolderUnicode::CaseFolderUnicode() { - StandardASCII(); - converter = ConverterFor(CaseConversionFold); -} - -size_t CaseFolderUnicode::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) { - if ((lenMixed == 1) && (sizeFolded > 0)) { - folded[0] = mapping[static_cast(mixed[0])]; - return 1; - } else { - return converter->CaseConvertString(folded, sizeFolded, mixed, lenMixed); - } -} diff --git a/qrenderdoc/3rdparty/scintilla/src/CaseFolder.h b/qrenderdoc/3rdparty/scintilla/src/CaseFolder.h deleted file mode 100644 index 2d754d4f3..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CaseFolder.h +++ /dev/null @@ -1,45 +0,0 @@ -// Scintilla source code edit control -/** @file CaseFolder.h - ** Classes for case folding. - **/ -// Copyright 1998-2013 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CASEFOLDER_H -#define CASEFOLDER_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class CaseFolder { -public: - virtual ~CaseFolder(); - virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0; -}; - -class CaseFolderTable : public CaseFolder { -protected: - char mapping[256]; -public: - CaseFolderTable(); - virtual ~CaseFolderTable(); - virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed); - void SetTranslation(char ch, char chTranslation); - void StandardASCII(); -}; - -class ICaseConverter; - -class CaseFolderUnicode : public CaseFolderTable { - ICaseConverter *converter; -public: - CaseFolderUnicode(); - virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Catalogue.cxx b/qrenderdoc/3rdparty/scintilla/src/Catalogue.cxx deleted file mode 100644 index be8b595ba..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Catalogue.cxx +++ /dev/null @@ -1,95 +0,0 @@ -// Scintilla source code edit control -/** @file Catalogue.cxx - ** Colourise for particular languages. - **/ -// Copyright 1998-2002 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "LexerModule.h" -#include "Catalogue.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static std::vector lexerCatalogue; -static int nextLanguage = SCLEX_AUTOMATIC+1; - -const LexerModule *Catalogue::Find(int language) { - Scintilla_LinkLexers(); - for (std::vector::iterator it=lexerCatalogue.begin(); - it != lexerCatalogue.end(); ++it) { - if ((*it)->GetLanguage() == language) { - return *it; - } - } - return 0; -} - -const LexerModule *Catalogue::Find(const char *languageName) { - Scintilla_LinkLexers(); - if (languageName) { - for (std::vector::iterator it=lexerCatalogue.begin(); - it != lexerCatalogue.end(); ++it) { - if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) { - return *it; - } - } - } - return 0; -} - -void Catalogue::AddLexerModule(LexerModule *plm) { - if (plm->GetLanguage() == SCLEX_AUTOMATIC) { - plm->language = nextLanguage; - nextLanguage++; - } - lexerCatalogue.push_back(plm); -} - -// To add or remove a lexer, add or remove its file and run LexGen.py. - -// Force a reference to all of the Scintilla lexers so that the linker will -// not remove the code of the lexers. -int Scintilla_LinkLexers() { - - static int initialised = 0; - if (initialised) - return 0; - initialised = 1; - -// Shorten the code that declares a lexer and ensures it is linked in by calling a method. -#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer); - -//++Autogenerated -- run scripts/LexGen.py to regenerate -//**\(\tLINK_LEXER(\*);\n\) - LINK_LEXER(lmCPP); - LINK_LEXER(lmCPPNoCase); - LINK_LEXER(lmDiff); - LINK_LEXER(lmErrorList); - LINK_LEXER(lmHTML); - LINK_LEXER(lmJSON); - LINK_LEXER(lmNull); - LINK_LEXER(lmPHPSCRIPT); - LINK_LEXER(lmPython); - LINK_LEXER(lmRust); - LINK_LEXER(lmXML); - -//--Autogenerated -- end of automatically generated section - - return 1; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/Catalogue.h b/qrenderdoc/3rdparty/scintilla/src/Catalogue.h deleted file mode 100644 index 7fea37da8..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Catalogue.h +++ /dev/null @@ -1,26 +0,0 @@ -// Scintilla source code edit control -/** @file Catalogue.h - ** Lexer infrastructure. - **/ -// Copyright 1998-2010 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CATALOGUE_H -#define CATALOGUE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class Catalogue { -public: - static const LexerModule *Find(int language); - static const LexerModule *Find(const char *languageName); - static void AddLexerModule(LexerModule *plm); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/CellBuffer.cxx b/qrenderdoc/3rdparty/scintilla/src/CellBuffer.cxx deleted file mode 100644 index 6ad990a63..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CellBuffer.cxx +++ /dev/null @@ -1,842 +0,0 @@ -// Scintilla source code edit control -/** @file CellBuffer.cxx - ** Manages a buffer of cells. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include - -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "CellBuffer.h" -#include "UniConversion.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -LineVector::LineVector() : starts(256), perLine(0) { - Init(); -} - -LineVector::~LineVector() { - starts.DeleteAll(); -} - -void LineVector::Init() { - starts.DeleteAll(); - if (perLine) { - perLine->Init(); - } -} - -void LineVector::SetPerLine(PerLine *pl) { - perLine = pl; -} - -void LineVector::InsertText(int line, int delta) { - starts.InsertText(line, delta); -} - -void LineVector::InsertLine(int line, int position, bool lineStart) { - starts.InsertPartition(line, position); - if (perLine) { - if ((line > 0) && lineStart) - line--; - perLine->InsertLine(line); - } -} - -void LineVector::SetLineStart(int line, int position) { - starts.SetPartitionStartPosition(line, position); -} - -void LineVector::RemoveLine(int line) { - starts.RemovePartition(line); - if (perLine) { - perLine->RemoveLine(line); - } -} - -int LineVector::LineFromPosition(int pos) const { - return starts.PartitionFromPosition(pos); -} - -Action::Action() { - at = startAction; - position = 0; - data = 0; - lenData = 0; - mayCoalesce = false; -} - -Action::~Action() { - Destroy(); -} - -void Action::Create(actionType at_, int position_, const char *data_, int lenData_, bool mayCoalesce_) { - delete []data; - data = NULL; - position = position_; - at = at_; - if (lenData_) { - data = new char[lenData_]; - memcpy(data, data_, lenData_); - } - lenData = lenData_; - mayCoalesce = mayCoalesce_; -} - -void Action::Destroy() { - delete []data; - data = 0; -} - -void Action::Grab(Action *source) { - delete []data; - - position = source->position; - at = source->at; - data = source->data; - lenData = source->lenData; - mayCoalesce = source->mayCoalesce; - - // Ownership of source data transferred to this - source->position = 0; - source->at = startAction; - source->data = 0; - source->lenData = 0; - source->mayCoalesce = true; -} - -// The undo history stores a sequence of user operations that represent the user's view of the -// commands executed on the text. -// Each user operation contains a sequence of text insertion and text deletion actions. -// All the user operations are stored in a list of individual actions with 'start' actions used -// as delimiters between user operations. -// Initially there is one start action in the history. -// As each action is performed, it is recorded in the history. The action may either become -// part of the current user operation or may start a new user operation. If it is to be part of the -// current operation, then it overwrites the current last action. If it is to be part of a new -// operation, it is appended after the current last action. -// After writing the new action, a new start action is appended at the end of the history. -// The decision of whether to start a new user operation is based upon two factors. If a -// compound operation has been explicitly started by calling BeginUndoAction and no matching -// EndUndoAction (these calls nest) has been called, then the action is coalesced into the current -// operation. If there is no outstanding BeginUndoAction call then a new operation is started -// unless it looks as if the new action is caused by the user typing or deleting a stream of text. -// Sequences that look like typing or deletion are coalesced into a single user operation. - -UndoHistory::UndoHistory() { - - lenActions = 100; - actions = new Action[lenActions]; - maxAction = 0; - currentAction = 0; - undoSequenceDepth = 0; - savePoint = 0; - tentativePoint = -1; - - actions[currentAction].Create(startAction); -} - -UndoHistory::~UndoHistory() { - delete []actions; - actions = 0; -} - -void UndoHistory::EnsureUndoRoom() { - // Have to test that there is room for 2 more actions in the array - // as two actions may be created by the calling function - if (currentAction >= (lenActions - 2)) { - // Run out of undo nodes so extend the array - int lenActionsNew = lenActions * 2; - Action *actionsNew = new Action[lenActionsNew]; - for (int act = 0; act <= currentAction; act++) - actionsNew[act].Grab(&actions[act]); - delete []actions; - lenActions = lenActionsNew; - actions = actionsNew; - } -} - -const char *UndoHistory::AppendAction(actionType at, int position, const char *data, int lengthData, - bool &startSequence, bool mayCoalesce) { - EnsureUndoRoom(); - //Platform::DebugPrintf("%% %d action %d %d %d\n", at, position, lengthData, currentAction); - //Platform::DebugPrintf("^ %d action %d %d\n", actions[currentAction - 1].at, - // actions[currentAction - 1].position, actions[currentAction - 1].lenData); - if (currentAction < savePoint) { - savePoint = -1; - } - int oldCurrentAction = currentAction; - if (currentAction >= 1) { - if (0 == undoSequenceDepth) { - // Top level actions may not always be coalesced - int targetAct = -1; - const Action *actPrevious = &(actions[currentAction + targetAct]); - // Container actions may forward the coalesce state of Scintilla Actions. - while ((actPrevious->at == containerAction) && actPrevious->mayCoalesce) { - targetAct--; - actPrevious = &(actions[currentAction + targetAct]); - } - // See if current action can be coalesced into previous action - // Will work if both are inserts or deletes and position is same -#if defined(_MSC_VER) && defined(_PREFAST_) - // Visual Studio 2013 Code Analysis wrongly believes actions can be NULL at its next reference - __analysis_assume(actions); -#endif - if ((currentAction == savePoint) || (currentAction == tentativePoint)) { - currentAction++; - } else if (!actions[currentAction].mayCoalesce) { - // Not allowed to coalesce if this set - currentAction++; - } else if (!mayCoalesce || !actPrevious->mayCoalesce) { - currentAction++; - } else if (at == containerAction || actions[currentAction].at == containerAction) { - ; // A coalescible containerAction - } else if ((at != actPrevious->at) && (actPrevious->at != startAction)) { - currentAction++; - } else if ((at == insertAction) && - (position != (actPrevious->position + actPrevious->lenData))) { - // Insertions must be immediately after to coalesce - currentAction++; - } else if (at == removeAction) { - if ((lengthData == 1) || (lengthData == 2)) { - if ((position + lengthData) == actPrevious->position) { - ; // Backspace -> OK - } else if (position == actPrevious->position) { - ; // Delete -> OK - } else { - // Removals must be at same position to coalesce - currentAction++; - } - } else { - // Removals must be of one character to coalesce - currentAction++; - } - } else { - // Action coalesced. - } - - } else { - // Actions not at top level are always coalesced unless this is after return to top level - if (!actions[currentAction].mayCoalesce) - currentAction++; - } - } else { - currentAction++; - } - startSequence = oldCurrentAction != currentAction; - int actionWithData = currentAction; - actions[currentAction].Create(at, position, data, lengthData, mayCoalesce); - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - return actions[actionWithData].data; -} - -void UndoHistory::BeginUndoAction() { - EnsureUndoRoom(); - if (undoSequenceDepth == 0) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - actions[currentAction].mayCoalesce = false; - } - undoSequenceDepth++; -} - -void UndoHistory::EndUndoAction() { - PLATFORM_ASSERT(undoSequenceDepth > 0); - EnsureUndoRoom(); - undoSequenceDepth--; - if (0 == undoSequenceDepth) { - if (actions[currentAction].at != startAction) { - currentAction++; - actions[currentAction].Create(startAction); - maxAction = currentAction; - } - actions[currentAction].mayCoalesce = false; - } -} - -void UndoHistory::DropUndoSequence() { - undoSequenceDepth = 0; -} - -void UndoHistory::DeleteUndoHistory() { - for (int i = 1; i < maxAction; i++) - actions[i].Destroy(); - maxAction = 0; - currentAction = 0; - actions[currentAction].Create(startAction); - savePoint = 0; - tentativePoint = -1; -} - -void UndoHistory::SetSavePoint() { - savePoint = currentAction; -} - -bool UndoHistory::IsSavePoint() const { - return savePoint == currentAction; -} - -void UndoHistory::TentativeStart() { - tentativePoint = currentAction; -} - -void UndoHistory::TentativeCommit() { - tentativePoint = -1; - // Truncate undo history - maxAction = currentAction; -} - -int UndoHistory::TentativeSteps() { - // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) - currentAction--; - if (tentativePoint >= 0) - return currentAction - tentativePoint; - else - return -1; -} - -bool UndoHistory::CanUndo() const { - return (currentAction > 0) && (maxAction > 0); -} - -int UndoHistory::StartUndo() { - // Drop any trailing startAction - if (actions[currentAction].at == startAction && currentAction > 0) - currentAction--; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act > 0) { - act--; - } - return currentAction - act; -} - -const Action &UndoHistory::GetUndoStep() const { - return actions[currentAction]; -} - -void UndoHistory::CompletedUndoStep() { - currentAction--; -} - -bool UndoHistory::CanRedo() const { - return maxAction > currentAction; -} - -int UndoHistory::StartRedo() { - // Drop any leading startAction - if (actions[currentAction].at == startAction && currentAction < maxAction) - currentAction++; - - // Count the steps in this action - int act = currentAction; - while (actions[act].at != startAction && act < maxAction) { - act++; - } - return act - currentAction; -} - -const Action &UndoHistory::GetRedoStep() const { - return actions[currentAction]; -} - -void UndoHistory::CompletedRedoStep() { - currentAction++; -} - -CellBuffer::CellBuffer() { - readOnly = false; - utf8LineEnds = 0; - collectingUndo = true; -} - -CellBuffer::~CellBuffer() { -} - -char CellBuffer::CharAt(int position) const { - return substance.ValueAt(position); -} - -void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const { - if (lengthRetrieve <= 0) - return; - if (position < 0) - return; - if ((position + lengthRetrieve) > substance.Length()) { - Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", position, - lengthRetrieve, substance.Length()); - return; - } - substance.GetRange(buffer, position, lengthRetrieve); -} - -char CellBuffer::StyleAt(int position) const { - return style.ValueAt(position); -} - -void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { - if (lengthRetrieve < 0) - return; - if (position < 0) - return; - if ((position + lengthRetrieve) > style.Length()) { - Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position, - lengthRetrieve, style.Length()); - return; - } - style.GetRange(reinterpret_cast(buffer), position, lengthRetrieve); -} - -const char *CellBuffer::BufferPointer() { - return substance.BufferPointer(); -} - -const char *CellBuffer::RangePointer(int position, int rangeLength) { - return substance.RangePointer(position, rangeLength); -} - -int CellBuffer::GapPosition() const { - return substance.GapPosition(); -} - -// The char* returned is to an allocation owned by the undo history -const char *CellBuffer::InsertString(int position, const char *s, int insertLength, bool &startSequence) { - // InsertString and DeleteChars are the bottleneck though which all changes occur - const char *data = s; - if (!readOnly) { - if (collectingUndo) { - // Save into the undo/redo stack, but only the characters - not the formatting - // This takes up about half load time - data = uh.AppendAction(insertAction, position, s, insertLength, startSequence); - } - - BasicInsertString(position, s, insertLength); - } - return data; -} - -bool CellBuffer::SetStyleAt(int position, char styleValue) { - char curVal = style.ValueAt(position); - if (curVal != styleValue) { - style.SetValueAt(position, styleValue); - return true; - } else { - return false; - } -} - -bool CellBuffer::SetStyleFor(int position, int lengthStyle, char styleValue) { - bool changed = false; - PLATFORM_ASSERT(lengthStyle == 0 || - (lengthStyle > 0 && lengthStyle + position <= style.Length())); - while (lengthStyle--) { - char curVal = style.ValueAt(position); - if (curVal != styleValue) { - style.SetValueAt(position, styleValue); - changed = true; - } - position++; - } - return changed; -} - -// The char* returned is to an allocation owned by the undo history -const char *CellBuffer::DeleteChars(int position, int deleteLength, bool &startSequence) { - // InsertString and DeleteChars are the bottleneck though which all changes occur - PLATFORM_ASSERT(deleteLength > 0); - const char *data = 0; - if (!readOnly) { - if (collectingUndo) { - // Save into the undo/redo stack, but only the characters - not the formatting - // The gap would be moved to position anyway for the deletion so this doesn't cost extra - data = substance.RangePointer(position, deleteLength); - data = uh.AppendAction(removeAction, position, data, deleteLength, startSequence); - } - - BasicDeleteChars(position, deleteLength); - } - return data; -} - -int CellBuffer::Length() const { - return substance.Length(); -} - -void CellBuffer::Allocate(int newSize) { - substance.ReAllocate(newSize); - style.ReAllocate(newSize); -} - -void CellBuffer::SetLineEndTypes(int utf8LineEnds_) { - if (utf8LineEnds != utf8LineEnds_) { - utf8LineEnds = utf8LineEnds_; - ResetLineEnds(); - } -} - -bool CellBuffer::ContainsLineEnd(const char *s, int length) const { - unsigned char chBeforePrev = 0; - unsigned char chPrev = 0; - for (int i = 0; i < length; i++) { - const unsigned char ch = s[i]; - if ((ch == '\r') || (ch == '\n')) { - return true; - } else if (utf8LineEnds) { - unsigned char back3[3] = { chBeforePrev, chPrev, ch }; - if (UTF8IsSeparator(back3) || UTF8IsNEL(back3 + 1)) { - return true; - } - } - chBeforePrev = chPrev; - chPrev = ch; - } - return false; -} - -void CellBuffer::SetPerLine(PerLine *pl) { - lv.SetPerLine(pl); -} - -int CellBuffer::Lines() const { - return lv.Lines(); -} - -int CellBuffer::LineStart(int line) const { - if (line < 0) - return 0; - else if (line >= Lines()) - return Length(); - else - return lv.LineStart(line); -} - -bool CellBuffer::IsReadOnly() const { - return readOnly; -} - -void CellBuffer::SetReadOnly(bool set) { - readOnly = set; -} - -void CellBuffer::SetSavePoint() { - uh.SetSavePoint(); -} - -bool CellBuffer::IsSavePoint() const { - return uh.IsSavePoint(); -} - -void CellBuffer::TentativeStart() { - uh.TentativeStart(); -} - -void CellBuffer::TentativeCommit() { - uh.TentativeCommit(); -} - -int CellBuffer::TentativeSteps() { - return uh.TentativeSteps(); -} - -bool CellBuffer::TentativeActive() const { - return uh.TentativeActive(); -} - -// Without undo - -void CellBuffer::InsertLine(int line, int position, bool lineStart) { - lv.InsertLine(line, position, lineStart); -} - -void CellBuffer::RemoveLine(int line) { - lv.RemoveLine(line); -} - -bool CellBuffer::UTF8LineEndOverlaps(int position) const { - unsigned char bytes[] = { - static_cast(substance.ValueAt(position-2)), - static_cast(substance.ValueAt(position-1)), - static_cast(substance.ValueAt(position)), - static_cast(substance.ValueAt(position+1)), - }; - return UTF8IsSeparator(bytes) || UTF8IsSeparator(bytes+1) || UTF8IsNEL(bytes+1); -} - -void CellBuffer::ResetLineEnds() { - // Reinitialize line data -- too much work to preserve - lv.Init(); - - int position = 0; - int length = Length(); - int lineInsert = 1; - bool atLineStart = true; - lv.InsertText(lineInsert-1, length); - unsigned char chBeforePrev = 0; - unsigned char chPrev = 0; - for (int i = 0; i < length; i++) { - unsigned char ch = substance.ValueAt(position + i); - if (ch == '\r') { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - } else if (ch == '\n') { - if (chPrev == '\r') { - // Patch up what was end of line - lv.SetLineStart(lineInsert - 1, (position + i) + 1); - } else { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - } - } else if (utf8LineEnds) { - unsigned char back3[3] = {chBeforePrev, chPrev, ch}; - if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - } - } - chBeforePrev = chPrev; - chPrev = ch; - } -} - -void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) { - if (insertLength == 0) - return; - PLATFORM_ASSERT(insertLength > 0); - - unsigned char chAfter = substance.ValueAt(position); - bool breakingUTF8LineEnd = false; - if (utf8LineEnds && UTF8IsTrailByte(chAfter)) { - breakingUTF8LineEnd = UTF8LineEndOverlaps(position); - } - - substance.InsertFromArray(position, s, 0, insertLength); - style.InsertValue(position, insertLength, 0); - - int lineInsert = lv.LineFromPosition(position) + 1; - bool atLineStart = lv.LineStart(lineInsert-1) == position; - // Point all the lines after the insertion point further along in the buffer - lv.InsertText(lineInsert-1, insertLength); - unsigned char chBeforePrev = substance.ValueAt(position - 2); - unsigned char chPrev = substance.ValueAt(position - 1); - if (chPrev == '\r' && chAfter == '\n') { - // Splitting up a crlf pair at position - InsertLine(lineInsert, position, false); - lineInsert++; - } - if (breakingUTF8LineEnd) { - RemoveLine(lineInsert); - } - unsigned char ch = ' '; - for (int i = 0; i < insertLength; i++) { - ch = s[i]; - if (ch == '\r') { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - } else if (ch == '\n') { - if (chPrev == '\r') { - // Patch up what was end of line - lv.SetLineStart(lineInsert - 1, (position + i) + 1); - } else { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - } - } else if (utf8LineEnds) { - unsigned char back3[3] = {chBeforePrev, chPrev, ch}; - if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) { - InsertLine(lineInsert, (position + i) + 1, atLineStart); - lineInsert++; - } - } - chBeforePrev = chPrev; - chPrev = ch; - } - // Joining two lines where last insertion is cr and following substance starts with lf - if (chAfter == '\n') { - if (ch == '\r') { - // End of line already in buffer so drop the newly created one - RemoveLine(lineInsert - 1); - } - } else if (utf8LineEnds && !UTF8IsAscii(chAfter)) { - // May have end of UTF-8 line end in buffer and start in insertion - for (int j = 0; j < UTF8SeparatorLength-1; j++) { - unsigned char chAt = substance.ValueAt(position + insertLength + j); - unsigned char back3[3] = {chBeforePrev, chPrev, chAt}; - if (UTF8IsSeparator(back3)) { - InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart); - lineInsert++; - } - if ((j == 0) && UTF8IsNEL(back3+1)) { - InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart); - lineInsert++; - } - chBeforePrev = chPrev; - chPrev = chAt; - } - } -} - -void CellBuffer::BasicDeleteChars(int position, int deleteLength) { - if (deleteLength == 0) - return; - - if ((position == 0) && (deleteLength == substance.Length())) { - // If whole buffer is being deleted, faster to reinitialise lines data - // than to delete each line. - lv.Init(); - } else { - // Have to fix up line positions before doing deletion as looking at text in buffer - // to work out which lines have been removed - - int lineRemove = lv.LineFromPosition(position) + 1; - lv.InsertText(lineRemove-1, - (deleteLength)); - unsigned char chPrev = substance.ValueAt(position - 1); - unsigned char chBefore = chPrev; - unsigned char chNext = substance.ValueAt(position); - bool ignoreNL = false; - if (chPrev == '\r' && chNext == '\n') { - // Move back one - lv.SetLineStart(lineRemove, position); - lineRemove++; - ignoreNL = true; // First \n is not real deletion - } - if (utf8LineEnds && UTF8IsTrailByte(chNext)) { - if (UTF8LineEndOverlaps(position)) { - RemoveLine(lineRemove); - } - } - - unsigned char ch = chNext; - for (int i = 0; i < deleteLength; i++) { - chNext = substance.ValueAt(position + i + 1); - if (ch == '\r') { - if (chNext != '\n') { - RemoveLine(lineRemove); - } - } else if (ch == '\n') { - if (ignoreNL) { - ignoreNL = false; // Further \n are real deletions - } else { - RemoveLine(lineRemove); - } - } else if (utf8LineEnds) { - if (!UTF8IsAscii(ch)) { - unsigned char next3[3] = {ch, chNext, - static_cast(substance.ValueAt(position + i + 2))}; - if (UTF8IsSeparator(next3) || UTF8IsNEL(next3)) { - RemoveLine(lineRemove); - } - } - } - - ch = chNext; - } - // May have to fix up end if last deletion causes cr to be next to lf - // or removes one of a crlf pair - char chAfter = substance.ValueAt(position + deleteLength); - if (chBefore == '\r' && chAfter == '\n') { - // Using lineRemove-1 as cr ended line before start of deletion - RemoveLine(lineRemove - 1); - lv.SetLineStart(lineRemove - 1, position + 1); - } - } - substance.DeleteRange(position, deleteLength); - style.DeleteRange(position, deleteLength); -} - -bool CellBuffer::SetUndoCollection(bool collectUndo) { - collectingUndo = collectUndo; - uh.DropUndoSequence(); - return collectingUndo; -} - -bool CellBuffer::IsCollectingUndo() const { - return collectingUndo; -} - -void CellBuffer::BeginUndoAction() { - uh.BeginUndoAction(); -} - -void CellBuffer::EndUndoAction() { - uh.EndUndoAction(); -} - -void CellBuffer::AddUndoAction(int token, bool mayCoalesce) { - bool startSequence; - uh.AppendAction(containerAction, token, 0, 0, startSequence, mayCoalesce); -} - -void CellBuffer::DeleteUndoHistory() { - uh.DeleteUndoHistory(); -} - -bool CellBuffer::CanUndo() const { - return uh.CanUndo(); -} - -int CellBuffer::StartUndo() { - return uh.StartUndo(); -} - -const Action &CellBuffer::GetUndoStep() const { - return uh.GetUndoStep(); -} - -void CellBuffer::PerformUndoStep() { - const Action &actionStep = uh.GetUndoStep(); - if (actionStep.at == insertAction) { - if (substance.Length() < actionStep.lenData) { - throw std::runtime_error( - "CellBuffer::PerformUndoStep: deletion must be less than document length."); - } - BasicDeleteChars(actionStep.position, actionStep.lenData); - } else if (actionStep.at == removeAction) { - BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData); - } - uh.CompletedUndoStep(); -} - -bool CellBuffer::CanRedo() const { - return uh.CanRedo(); -} - -int CellBuffer::StartRedo() { - return uh.StartRedo(); -} - -const Action &CellBuffer::GetRedoStep() const { - return uh.GetRedoStep(); -} - -void CellBuffer::PerformRedoStep() { - const Action &actionStep = uh.GetRedoStep(); - if (actionStep.at == insertAction) { - BasicInsertString(actionStep.position, actionStep.data, actionStep.lenData); - } else if (actionStep.at == removeAction) { - BasicDeleteChars(actionStep.position, actionStep.lenData); - } - uh.CompletedRedoStep(); -} - diff --git a/qrenderdoc/3rdparty/scintilla/src/CellBuffer.h b/qrenderdoc/3rdparty/scintilla/src/CellBuffer.h deleted file mode 100644 index c1e973cff..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CellBuffer.h +++ /dev/null @@ -1,216 +0,0 @@ -// Scintilla source code edit control -/** @file CellBuffer.h - ** Manages the text of the document. - **/ -// Copyright 1998-2004 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CELLBUFFER_H -#define CELLBUFFER_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// Interface to per-line data that wants to see each line insertion and deletion -class PerLine { -public: - virtual ~PerLine() {} - virtual void Init()=0; - virtual void InsertLine(int line)=0; - virtual void RemoveLine(int line)=0; -}; - -/** - * The line vector contains information about each of the lines in a cell buffer. - */ -class LineVector { - - Partitioning starts; - PerLine *perLine; - -public: - - LineVector(); - ~LineVector(); - void Init(); - void SetPerLine(PerLine *pl); - - void InsertText(int line, int delta); - void InsertLine(int line, int position, bool lineStart); - void SetLineStart(int line, int position); - void RemoveLine(int line); - int Lines() const { - return starts.Partitions(); - } - int LineFromPosition(int pos) const; - int LineStart(int line) const { - return starts.PositionFromPartition(line); - } -}; - -enum actionType { insertAction, removeAction, startAction, containerAction }; - -/** - * Actions are used to store all the information required to perform one undo/redo step. - */ -class Action { -public: - actionType at; - int position; - char *data; - int lenData; - bool mayCoalesce; - - Action(); - ~Action(); - void Create(actionType at_, int position_=0, const char *data_=0, int lenData_=0, bool mayCoalesce_=true); - void Destroy(); - void Grab(Action *source); -}; - -/** - * - */ -class UndoHistory { - Action *actions; - int lenActions; - int maxAction; - int currentAction; - int undoSequenceDepth; - int savePoint; - int tentativePoint; - - void EnsureUndoRoom(); - - // Private so UndoHistory objects can not be copied - UndoHistory(const UndoHistory &); - -public: - UndoHistory(); - ~UndoHistory(); - - const char *AppendAction(actionType at, int position, const char *data, int length, bool &startSequence, bool mayCoalesce=true); - - void BeginUndoAction(); - void EndUndoAction(); - void DropUndoSequence(); - void DeleteUndoHistory(); - - /// The save point is a marker in the undo stack where the container has stated that - /// the buffer was saved. Undo and redo can move over the save point. - void SetSavePoint(); - bool IsSavePoint() const; - - // Tentative actions are used for input composition so that it can be undone cleanly - void TentativeStart(); - void TentativeCommit(); - bool TentativeActive() const { return tentativePoint >= 0; } - int TentativeSteps(); - - /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is - /// called that many times. Similarly for redo. - bool CanUndo() const; - int StartUndo(); - const Action &GetUndoStep() const; - void CompletedUndoStep(); - bool CanRedo() const; - int StartRedo(); - const Action &GetRedoStep() const; - void CompletedRedoStep(); -}; - -/** - * Holder for an expandable array of characters that supports undo and line markers. - * Based on article "Data Structures in a Bit-Mapped Text Editor" - * by Wilfred J. Hansen, Byte January 1987, page 183. - */ -class CellBuffer { -private: - SplitVector substance; - SplitVector style; - bool readOnly; - int utf8LineEnds; - - bool collectingUndo; - UndoHistory uh; - - LineVector lv; - - bool UTF8LineEndOverlaps(int position) const; - void ResetLineEnds(); - /// Actions without undo - void BasicInsertString(int position, const char *s, int insertLength); - void BasicDeleteChars(int position, int deleteLength); - -public: - - CellBuffer(); - ~CellBuffer(); - - /// Retrieving positions outside the range of the buffer works and returns 0 - char CharAt(int position) const; - void GetCharRange(char *buffer, int position, int lengthRetrieve) const; - char StyleAt(int position) const; - void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const; - const char *BufferPointer(); - const char *RangePointer(int position, int rangeLength); - int GapPosition() const; - - int Length() const; - void Allocate(int newSize); - int GetLineEndTypes() const { return utf8LineEnds; } - void SetLineEndTypes(int utf8LineEnds_); - bool ContainsLineEnd(const char *s, int length) const; - void SetPerLine(PerLine *pl); - int Lines() const; - int LineStart(int line) const; - int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); } - void InsertLine(int line, int position, bool lineStart); - void RemoveLine(int line); - const char *InsertString(int position, const char *s, int insertLength, bool &startSequence); - - /// Setting styles for positions outside the range of the buffer is safe and has no effect. - /// @return true if the style of a character is changed. - bool SetStyleAt(int position, char styleValue); - bool SetStyleFor(int position, int length, char styleValue); - - const char *DeleteChars(int position, int deleteLength, bool &startSequence); - - bool IsReadOnly() const; - void SetReadOnly(bool set); - - /// The save point is a marker in the undo stack where the container has stated that - /// the buffer was saved. Undo and redo can move over the save point. - void SetSavePoint(); - bool IsSavePoint() const; - - void TentativeStart(); - void TentativeCommit(); - bool TentativeActive() const; - int TentativeSteps(); - - bool SetUndoCollection(bool collectUndo); - bool IsCollectingUndo() const; - void BeginUndoAction(); - void EndUndoAction(); - void AddUndoAction(int token, bool mayCoalesce); - void DeleteUndoHistory(); - - /// To perform an undo, StartUndo is called to retrieve the number of steps, then UndoStep is - /// called that many times. Similarly for redo. - bool CanUndo() const; - int StartUndo(); - const Action &GetUndoStep() const; - void PerformUndoStep(); - bool CanRedo() const; - int StartRedo(); - const Action &GetRedoStep() const; - void PerformRedoStep(); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/CharClassify.cxx b/qrenderdoc/3rdparty/scintilla/src/CharClassify.cxx deleted file mode 100644 index 8678e6d64..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CharClassify.cxx +++ /dev/null @@ -1,61 +0,0 @@ -// Scintilla source code edit control -/** @file CharClassify.cxx - ** Character classifications used by Document and RESearch. - **/ -// Copyright 2006 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include - -#include - -#include "CharClassify.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -CharClassify::CharClassify() { - SetDefaultCharClasses(true); -} - -void CharClassify::SetDefaultCharClasses(bool includeWordClass) { - // Initialize all char classes to default values - for (int ch = 0; ch < 256; ch++) { - if (ch == '\r' || ch == '\n') - charClass[ch] = ccNewLine; - else if (ch < 0x20 || ch == ' ') - charClass[ch] = ccSpace; - else if (includeWordClass && (ch >= 0x80 || isalnum(ch) || ch == '_')) - charClass[ch] = ccWord; - else - charClass[ch] = ccPunctuation; - } -} - -void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) { - // Apply the newCharClass to the specifed chars - if (chars) { - while (*chars) { - charClass[*chars] = static_cast(newCharClass); - chars++; - } - } -} - -int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) const { - // Get characters belonging to the given char class; return the number - // of characters (if the buffer is NULL, don't write to it). - int count = 0; - for (int ch = maxChar - 1; ch >= 0; --ch) { - if (charClass[ch] == characterClass) { - ++count; - if (buffer) { - *buffer = static_cast(ch); - buffer++; - } - } - } - return count; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/CharClassify.h b/qrenderdoc/3rdparty/scintilla/src/CharClassify.h deleted file mode 100644 index 63e8e8be2..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/CharClassify.h +++ /dev/null @@ -1,35 +0,0 @@ -// Scintilla source code edit control -/** @file CharClassify.h - ** Character classifications used by Document and RESearch. - **/ -// Copyright 2006-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CHARCLASSIFY_H -#define CHARCLASSIFY_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class CharClassify { -public: - CharClassify(); - - enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation }; - void SetDefaultCharClasses(bool includeWordClass); - void SetCharClasses(const unsigned char *chars, cc newCharClass); - int GetCharsOfClass(cc charClass, unsigned char *buffer) const; - cc GetClass(unsigned char ch) const { return static_cast(charClass[ch]);} - bool IsWord(unsigned char ch) const { return static_cast(charClass[ch]) == ccWord;} - -private: - enum { maxChar=256 }; - unsigned char charClass[maxChar]; // not type cc to save space -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/ContractionState.cxx b/qrenderdoc/3rdparty/scintilla/src/ContractionState.cxx deleted file mode 100644 index 41627c173..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ContractionState.cxx +++ /dev/null @@ -1,316 +0,0 @@ -// Scintilla source code edit control -/** @file ContractionState.cxx - ** Manages visibility of lines for folding and wrapping. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include - -#include -#include - -#include "Platform.h" - -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "SparseVector.h" -#include "ContractionState.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -ContractionState::ContractionState() : visible(0), expanded(0), heights(0), foldDisplayTexts(0), displayLines(0), linesInDocument(1) { - //InsertLine(0); -} - -ContractionState::~ContractionState() { - Clear(); -} - -void ContractionState::EnsureData() { - if (OneToOne()) { - visible = new RunStyles(); - expanded = new RunStyles(); - heights = new RunStyles(); - foldDisplayTexts = new SparseVector(); - displayLines = new Partitioning(4); - InsertLines(0, linesInDocument); - } -} - -void ContractionState::Clear() { - delete visible; - visible = 0; - delete expanded; - expanded = 0; - delete heights; - heights = 0; - delete foldDisplayTexts; - foldDisplayTexts = 0; - delete displayLines; - displayLines = 0; - linesInDocument = 1; -} - -int ContractionState::LinesInDoc() const { - if (OneToOne()) { - return linesInDocument; - } else { - return displayLines->Partitions() - 1; - } -} - -int ContractionState::LinesDisplayed() const { - if (OneToOne()) { - return linesInDocument; - } else { - return displayLines->PositionFromPartition(LinesInDoc()); - } -} - -int ContractionState::DisplayFromDoc(int lineDoc) const { - if (OneToOne()) { - return (lineDoc <= linesInDocument) ? lineDoc : linesInDocument; - } else { - if (lineDoc > displayLines->Partitions()) - lineDoc = displayLines->Partitions(); - return displayLines->PositionFromPartition(lineDoc); - } -} - -int ContractionState::DisplayLastFromDoc(int lineDoc) const { - return DisplayFromDoc(lineDoc) + GetHeight(lineDoc) - 1; -} - -int ContractionState::DocFromDisplay(int lineDisplay) const { - if (OneToOne()) { - return lineDisplay; - } else { - if (lineDisplay <= 0) { - return 0; - } - if (lineDisplay > LinesDisplayed()) { - return displayLines->PartitionFromPosition(LinesDisplayed()); - } - int lineDoc = displayLines->PartitionFromPosition(lineDisplay); - PLATFORM_ASSERT(GetVisible(lineDoc)); - return lineDoc; - } -} - -void ContractionState::InsertLine(int lineDoc) { - if (OneToOne()) { - linesInDocument++; - } else { - visible->InsertSpace(lineDoc, 1); - visible->SetValueAt(lineDoc, 1); - expanded->InsertSpace(lineDoc, 1); - expanded->SetValueAt(lineDoc, 1); - heights->InsertSpace(lineDoc, 1); - heights->SetValueAt(lineDoc, 1); - foldDisplayTexts->InsertSpace(lineDoc, 1); - foldDisplayTexts->SetValueAt(lineDoc, NULL); - int lineDisplay = DisplayFromDoc(lineDoc); - displayLines->InsertPartition(lineDoc, lineDisplay); - displayLines->InsertText(lineDoc, 1); - } -} - -void ContractionState::InsertLines(int lineDoc, int lineCount) { - for (int l = 0; l < lineCount; l++) { - InsertLine(lineDoc + l); - } - Check(); -} - -void ContractionState::DeleteLine(int lineDoc) { - if (OneToOne()) { - linesInDocument--; - } else { - if (GetVisible(lineDoc)) { - displayLines->InsertText(lineDoc, -heights->ValueAt(lineDoc)); - } - displayLines->RemovePartition(lineDoc); - visible->DeleteRange(lineDoc, 1); - expanded->DeleteRange(lineDoc, 1); - heights->DeleteRange(lineDoc, 1); - foldDisplayTexts->DeletePosition(lineDoc); - } -} - -void ContractionState::DeleteLines(int lineDoc, int lineCount) { - for (int l = 0; l < lineCount; l++) { - DeleteLine(lineDoc); - } - Check(); -} - -bool ContractionState::GetVisible(int lineDoc) const { - if (OneToOne()) { - return true; - } else { - if (lineDoc >= visible->Length()) - return true; - return visible->ValueAt(lineDoc) == 1; - } -} - -bool ContractionState::SetVisible(int lineDocStart, int lineDocEnd, bool isVisible) { - if (OneToOne() && isVisible) { - return false; - } else { - EnsureData(); - int delta = 0; - Check(); - if ((lineDocStart <= lineDocEnd) && (lineDocStart >= 0) && (lineDocEnd < LinesInDoc())) { - for (int line = lineDocStart; line <= lineDocEnd; line++) { - if (GetVisible(line) != isVisible) { - int difference = isVisible ? heights->ValueAt(line) : -heights->ValueAt(line); - visible->SetValueAt(line, isVisible ? 1 : 0); - displayLines->InsertText(line, difference); - delta += difference; - } - } - } else { - return false; - } - Check(); - return delta != 0; - } -} - -bool ContractionState::HiddenLines() const { - if (OneToOne()) { - return false; - } else { - return !visible->AllSameAs(1); - } -} - -const char *ContractionState::GetFoldDisplayText(int lineDoc) const { - Check(); - return foldDisplayTexts->ValueAt(lineDoc); -} - -bool ContractionState::SetFoldDisplayText(int lineDoc, const char *text) { - EnsureData(); - const char *foldText = foldDisplayTexts->ValueAt(lineDoc); - if (!foldText || 0 != strcmp(text, foldText)) { - foldDisplayTexts->SetValueAt(lineDoc, text); - Check(); - return true; - } else { - Check(); - return false; - } -} - -bool ContractionState::GetExpanded(int lineDoc) const { - if (OneToOne()) { - return true; - } else { - Check(); - return expanded->ValueAt(lineDoc) == 1; - } -} - -bool ContractionState::SetExpanded(int lineDoc, bool isExpanded) { - if (OneToOne() && isExpanded) { - return false; - } else { - EnsureData(); - if (isExpanded != (expanded->ValueAt(lineDoc) == 1)) { - expanded->SetValueAt(lineDoc, isExpanded ? 1 : 0); - Check(); - return true; - } else { - Check(); - return false; - } - } -} - -bool ContractionState::GetFoldDisplayTextShown(int lineDoc) const { - return !GetExpanded(lineDoc) && GetFoldDisplayText(lineDoc); -} - -int ContractionState::ContractedNext(int lineDocStart) const { - if (OneToOne()) { - return -1; - } else { - Check(); - if (!expanded->ValueAt(lineDocStart)) { - return lineDocStart; - } else { - int lineDocNextChange = expanded->EndRun(lineDocStart); - if (lineDocNextChange < LinesInDoc()) - return lineDocNextChange; - else - return -1; - } - } -} - -int ContractionState::GetHeight(int lineDoc) const { - if (OneToOne()) { - return 1; - } else { - return heights->ValueAt(lineDoc); - } -} - -// Set the number of display lines needed for this line. -// Return true if this is a change. -bool ContractionState::SetHeight(int lineDoc, int height) { - if (OneToOne() && (height == 1)) { - return false; - } else if (lineDoc < LinesInDoc()) { - EnsureData(); - if (GetHeight(lineDoc) != height) { - if (GetVisible(lineDoc)) { - displayLines->InsertText(lineDoc, height - GetHeight(lineDoc)); - } - heights->SetValueAt(lineDoc, height); - Check(); - return true; - } else { - Check(); - return false; - } - } else { - return false; - } -} - -void ContractionState::ShowAll() { - int lines = LinesInDoc(); - Clear(); - linesInDocument = lines; -} - -// Debugging checks - -void ContractionState::Check() const { -#ifdef CHECK_CORRECTNESS - for (int vline = 0; vline < LinesDisplayed(); vline++) { - const int lineDoc = DocFromDisplay(vline); - PLATFORM_ASSERT(GetVisible(lineDoc)); - } - for (int lineDoc = 0; lineDoc < LinesInDoc(); lineDoc++) { - const int displayThis = DisplayFromDoc(lineDoc); - const int displayNext = DisplayFromDoc(lineDoc + 1); - const int height = displayNext - displayThis; - PLATFORM_ASSERT(height >= 0); - if (GetVisible(lineDoc)) { - PLATFORM_ASSERT(GetHeight(lineDoc) == height); - } else { - PLATFORM_ASSERT(0 == height); - } - } -#endif -} diff --git a/qrenderdoc/3rdparty/scintilla/src/ContractionState.h b/qrenderdoc/3rdparty/scintilla/src/ContractionState.h deleted file mode 100644 index 622696939..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ContractionState.h +++ /dev/null @@ -1,77 +0,0 @@ -// Scintilla source code edit control -/** @file ContractionState.h - ** Manages visibility of lines for folding and wrapping. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef CONTRACTIONSTATE_H -#define CONTRACTIONSTATE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -template -class SparseVector; - -/** - */ -class ContractionState { - // These contain 1 element for every document line. - RunStyles *visible; - RunStyles *expanded; - RunStyles *heights; - SparseVector *foldDisplayTexts; - Partitioning *displayLines; - int linesInDocument; - - void EnsureData(); - - bool OneToOne() const { - // True when each document line is exactly one display line so need for - // complex data structures. - return visible == 0; - } - -public: - ContractionState(); - virtual ~ContractionState(); - - void Clear(); - - int LinesInDoc() const; - int LinesDisplayed() const; - int DisplayFromDoc(int lineDoc) const; - int DisplayLastFromDoc(int lineDoc) const; - int DocFromDisplay(int lineDisplay) const; - - void InsertLine(int lineDoc); - void InsertLines(int lineDoc, int lineCount); - void DeleteLine(int lineDoc); - void DeleteLines(int lineDoc, int lineCount); - - bool GetVisible(int lineDoc) const; - bool SetVisible(int lineDocStart, int lineDocEnd, bool isVisible); - bool HiddenLines() const; - - const char *GetFoldDisplayText(int lineDoc) const; - bool SetFoldDisplayText(int lineDoc, const char *text); - - bool GetExpanded(int lineDoc) const; - bool SetExpanded(int lineDoc, bool isExpanded); - bool GetFoldDisplayTextShown(int lineDoc) const; - int ContractedNext(int lineDocStart) const; - - int GetHeight(int lineDoc) const; - bool SetHeight(int lineDoc, int height); - - void ShowAll(); - void Check() const; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Decoration.cxx b/qrenderdoc/3rdparty/scintilla/src/Decoration.cxx deleted file mode 100644 index 389db5029..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Decoration.cxx +++ /dev/null @@ -1,198 +0,0 @@ -/** @file Decoration.cxx - ** Visual elements added over text. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include - -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "Decoration.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -Decoration::Decoration(int indicator_) : next(0), indicator(indicator_) { -} - -Decoration::~Decoration() { -} - -bool Decoration::Empty() const { - return (rs.Runs() == 1) && (rs.AllSameAs(0)); -} - -DecorationList::DecorationList() : currentIndicator(0), currentValue(1), current(0), - lengthDocument(0), root(0), clickNotified(false) { -} - -DecorationList::~DecorationList() { - Decoration *deco = root; - while (deco) { - Decoration *decoNext = deco->next; - delete deco; - deco = decoNext; - } - root = 0; - current = 0; -} - -Decoration *DecorationList::DecorationFromIndicator(int indicator) { - for (Decoration *deco=root; deco; deco = deco->next) { - if (deco->indicator == indicator) { - return deco; - } - } - return 0; -} - -Decoration *DecorationList::Create(int indicator, int length) { - currentIndicator = indicator; - Decoration *decoNew = new Decoration(indicator); - decoNew->rs.InsertSpace(0, length); - - Decoration *decoPrev = 0; - Decoration *deco = root; - - while (deco && (deco->indicator < indicator)) { - decoPrev = deco; - deco = deco->next; - } - if (decoPrev == 0) { - decoNew->next = root; - root = decoNew; - } else { - decoNew->next = deco; - decoPrev->next = decoNew; - } - return decoNew; -} - -void DecorationList::Delete(int indicator) { - Decoration *decoToDelete = 0; - if (root) { - if (root->indicator == indicator) { - decoToDelete = root; - root = root->next; - } else { - Decoration *deco=root; - while (deco->next && !decoToDelete) { - if (deco->next && deco->next->indicator == indicator) { - decoToDelete = deco->next; - deco->next = decoToDelete->next; - } else { - deco = deco->next; - } - } - } - } - if (decoToDelete) { - delete decoToDelete; - current = 0; - } -} - -void DecorationList::SetCurrentIndicator(int indicator) { - currentIndicator = indicator; - current = DecorationFromIndicator(indicator); - currentValue = 1; -} - -void DecorationList::SetCurrentValue(int value) { - currentValue = value ? value : 1; -} - -bool DecorationList::FillRange(int &position, int value, int &fillLength) { - if (!current) { - current = DecorationFromIndicator(currentIndicator); - if (!current) { - current = Create(currentIndicator, lengthDocument); - } - } - bool changed = current->rs.FillRange(position, value, fillLength); - if (current->Empty()) { - Delete(currentIndicator); - } - return changed; -} - -void DecorationList::InsertSpace(int position, int insertLength) { - const bool atEnd = position == lengthDocument; - lengthDocument += insertLength; - for (Decoration *deco=root; deco; deco = deco->next) { - deco->rs.InsertSpace(position, insertLength); - if (atEnd) { - deco->rs.FillRange(position, 0, insertLength); - } - } -} - -void DecorationList::DeleteRange(int position, int deleteLength) { - lengthDocument -= deleteLength; - Decoration *deco; - for (deco=root; deco; deco = deco->next) { - deco->rs.DeleteRange(position, deleteLength); - } - DeleteAnyEmpty(); -} - -void DecorationList::DeleteAnyEmpty() { - Decoration *deco = root; - while (deco) { - if ((lengthDocument == 0) || deco->Empty()) { - Delete(deco->indicator); - deco = root; - } else { - deco = deco->next; - } - } -} - -int DecorationList::AllOnFor(int position) const { - int mask = 0; - for (Decoration *deco=root; deco; deco = deco->next) { - if (deco->rs.ValueAt(position)) { - if (deco->indicator < INDIC_IME) { - mask |= 1 << deco->indicator; - } - } - } - return mask; -} - -int DecorationList::ValueAt(int indicator, int position) { - Decoration *deco = DecorationFromIndicator(indicator); - if (deco) { - return deco->rs.ValueAt(position); - } - return 0; -} - -int DecorationList::Start(int indicator, int position) { - Decoration *deco = DecorationFromIndicator(indicator); - if (deco) { - return deco->rs.StartRun(position); - } - return 0; -} - -int DecorationList::End(int indicator, int position) { - Decoration *deco = DecorationFromIndicator(indicator); - if (deco) { - return deco->rs.EndRun(position); - } - return 0; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/Decoration.h b/qrenderdoc/3rdparty/scintilla/src/Decoration.h deleted file mode 100644 index a0c434af8..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Decoration.h +++ /dev/null @@ -1,64 +0,0 @@ -/** @file Decoration.h - ** Visual elements added over text. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef DECORATION_H -#define DECORATION_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class Decoration { -public: - Decoration *next; - RunStyles rs; - int indicator; - - explicit Decoration(int indicator_); - ~Decoration(); - - bool Empty() const; -}; - -class DecorationList { - int currentIndicator; - int currentValue; - Decoration *current; - int lengthDocument; - Decoration *DecorationFromIndicator(int indicator); - Decoration *Create(int indicator, int length); - void Delete(int indicator); - void DeleteAnyEmpty(); -public: - Decoration *root; - bool clickNotified; - - DecorationList(); - ~DecorationList(); - - void SetCurrentIndicator(int indicator); - int GetCurrentIndicator() const { return currentIndicator; } - - void SetCurrentValue(int value); - int GetCurrentValue() const { return currentValue; } - - // Returns true if some values may have changed - bool FillRange(int &position, int value, int &fillLength); - - void InsertSpace(int position, int insertLength); - void DeleteRange(int position, int deleteLength); - - int AllOnFor(int position) const; - int ValueAt(int indicator, int position); - int Start(int indicator, int position); - int End(int indicator, int position); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Document.cxx b/qrenderdoc/3rdparty/scintilla/src/Document.cxx deleted file mode 100644 index c105bdda3..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Document.cxx +++ /dev/null @@ -1,3081 +0,0 @@ -// Scintilla source code edit control -/** @file Document.cxx - ** Text document that handles notifications, DBCS, styling, words and end of line. - **/ -// Copyright 1998-2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define NOEXCEPT - -#ifndef NO_CXX11_REGEX -#include -#if defined(__GLIBCXX__) -// If using the GNU implementation of then have 'noexcept' so can use -// when defining regex iterators to keep Clang analyze happy. -#undef NOEXCEPT -#define NOEXCEPT noexcept -#endif -#endif - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "CharacterSet.h" -#include "CharacterCategory.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "CellBuffer.h" -#include "PerLine.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "RESearch.h" -#include "UniConversion.h" -#include "UnicodeFromUTF8.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -void LexInterface::Colourise(int start, int end) { - if (pdoc && instance && !performingStyle) { - // Protect against reentrance, which may occur, for example, when - // fold points are discovered while performing styling and the folding - // code looks for child lines which may trigger styling. - performingStyle = true; - - int lengthDoc = pdoc->Length(); - if (end == -1) - end = lengthDoc; - int len = end - start; - - PLATFORM_ASSERT(len >= 0); - PLATFORM_ASSERT(start + len <= lengthDoc); - - int styleStart = 0; - if (start > 0) - styleStart = pdoc->StyleAt(start - 1); - - if (len > 0) { - instance->Lex(start, len, styleStart, pdoc); - instance->Fold(start, len, styleStart, pdoc); - } - - performingStyle = false; - } -} - -int LexInterface::LineEndTypesSupported() { - if (instance) { - int interfaceVersion = instance->Version(); - if (interfaceVersion >= lvSubStyles) { - ILexerWithSubStyles *ssinstance = static_cast(instance); - return ssinstance->LineEndTypesSupported(); - } - } - return 0; -} - -Document::Document() { - refCount = 0; - pcf = NULL; -#ifdef _WIN32 - eolMode = SC_EOL_CRLF; -#else - eolMode = SC_EOL_LF; -#endif - dbcsCodePage = 0; - lineEndBitSet = SC_LINE_END_TYPE_DEFAULT; - endStyled = 0; - styleClock = 0; - enteredModification = 0; - enteredStyling = 0; - enteredReadOnlyCount = 0; - insertionSet = false; - tabInChars = 8; - indentInChars = 0; - actualIndentInChars = 8; - useTabs = true; - tabIndents = true; - backspaceUnindents = false; - durationStyleOneLine = 0.00001; - - matchesValid = false; - regex = 0; - - UTF8BytesOfLeadInitialise(); - - perLineData[ldMarkers] = new LineMarkers(); - perLineData[ldLevels] = new LineLevels(); - perLineData[ldState] = new LineState(); - perLineData[ldMargin] = new LineAnnotation(); - perLineData[ldAnnotation] = new LineAnnotation(); - - cb.SetPerLine(this); - - pli = 0; -} - -Document::~Document() { - for (std::vector::iterator it = watchers.begin(); it != watchers.end(); ++it) { - it->watcher->NotifyDeleted(this, it->userData); - } - for (int j=0; jInit(); - } -} - -int Document::LineEndTypesSupported() const { - if ((SC_CP_UTF8 == dbcsCodePage) && pli) - return pli->LineEndTypesSupported(); - else - return 0; -} - -bool Document::SetDBCSCodePage(int dbcsCodePage_) { - if (dbcsCodePage != dbcsCodePage_) { - dbcsCodePage = dbcsCodePage_; - SetCaseFolder(NULL); - cb.SetLineEndTypes(lineEndBitSet & LineEndTypesSupported()); - return true; - } else { - return false; - } -} - -bool Document::SetLineEndTypesAllowed(int lineEndBitSet_) { - if (lineEndBitSet != lineEndBitSet_) { - lineEndBitSet = lineEndBitSet_; - int lineEndBitSetActive = lineEndBitSet & LineEndTypesSupported(); - if (lineEndBitSetActive != cb.GetLineEndTypes()) { - ModifiedAt(0); - cb.SetLineEndTypes(lineEndBitSetActive); - return true; - } else { - return false; - } - } else { - return false; - } -} - -void Document::InsertLine(int line) { - for (int j=0; jInsertLine(line); - } -} - -void Document::RemoveLine(int line) { - for (int j=0; jRemoveLine(line); - } -} - -// Increase reference count and return its previous value. -int Document::AddRef() { - return refCount++; -} - -// Decrease reference count and return its previous value. -// Delete the document if reference count reaches zero. -int SCI_METHOD Document::Release() { - int curRefCount = --refCount; - if (curRefCount == 0) - delete this; - return curRefCount; -} - -void Document::SetSavePoint() { - cb.SetSavePoint(); - NotifySavePoint(true); -} - -void Document::TentativeUndo() { - if (!TentativeActive()) - return; - CheckReadOnly(); - if (enteredModification == 0) { - enteredModification++; - if (!cb.IsReadOnly()) { - bool startSavePoint = cb.IsSavePoint(); - bool multiLine = false; - int steps = cb.TentativeSteps(); - //Platform::DebugPrintf("Steps=%d\n", steps); - for (int step = 0; step < steps; step++) { - const int prevLinesTotal = LinesTotal(); - const Action &action = cb.GetUndoStep(); - if (action.at == removeAction) { - NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); - } else if (action.at == containerAction) { - DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO); - dm.token = action.position; - NotifyModified(dm); - } else { - NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); - } - cb.PerformUndoStep(); - if (action.at != containerAction) { - ModifiedAt(action.position); - } - - int modFlags = SC_PERFORMED_UNDO; - // With undo, an insertion action becomes a deletion notification - if (action.at == removeAction) { - modFlags |= SC_MOD_INSERTTEXT; - } else if (action.at == insertAction) { - modFlags |= SC_MOD_DELETETEXT; - } - if (steps > 1) - modFlags |= SC_MULTISTEPUNDOREDO; - const int linesAdded = LinesTotal() - prevLinesTotal; - if (linesAdded != 0) - multiLine = true; - if (step == steps - 1) { - modFlags |= SC_LASTSTEPINUNDOREDO; - if (multiLine) - modFlags |= SC_MULTILINEUNDOREDO; - } - NotifyModified(DocModification(modFlags, action.position, action.lenData, - linesAdded, action.data)); - } - - bool endSavePoint = cb.IsSavePoint(); - if (startSavePoint != endSavePoint) - NotifySavePoint(endSavePoint); - - cb.TentativeCommit(); - } - enteredModification--; - } -} - -int Document::GetMark(int line) { - return static_cast(perLineData[ldMarkers])->MarkValue(line); -} - -int Document::MarkerNext(int lineStart, int mask) const { - return static_cast(perLineData[ldMarkers])->MarkerNext(lineStart, mask); -} - -int Document::AddMark(int line, int markerNum) { - if (line >= 0 && line <= LinesTotal()) { - int prev = static_cast(perLineData[ldMarkers])-> - AddMark(line, markerNum, LinesTotal()); - DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); - NotifyModified(mh); - return prev; - } else { - return 0; - } -} - -void Document::AddMarkSet(int line, int valueSet) { - if (line < 0 || line > LinesTotal()) { - return; - } - unsigned int m = valueSet; - for (int i = 0; m; i++, m >>= 1) - if (m & 1) - static_cast(perLineData[ldMarkers])-> - AddMark(line, i, LinesTotal()); - DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); - NotifyModified(mh); -} - -void Document::DeleteMark(int line, int markerNum) { - static_cast(perLineData[ldMarkers])->DeleteMark(line, markerNum, false); - DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line); - NotifyModified(mh); -} - -void Document::DeleteMarkFromHandle(int markerHandle) { - static_cast(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle); - DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); - mh.line = -1; - NotifyModified(mh); -} - -void Document::DeleteAllMarks(int markerNum) { - bool someChanges = false; - for (int line = 0; line < LinesTotal(); line++) { - if (static_cast(perLineData[ldMarkers])->DeleteMark(line, markerNum, true)) - someChanges = true; - } - if (someChanges) { - DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0); - mh.line = -1; - NotifyModified(mh); - } -} - -int Document::LineFromHandle(int markerHandle) { - return static_cast(perLineData[ldMarkers])->LineFromHandle(markerHandle); -} - -Sci_Position SCI_METHOD Document::LineStart(Sci_Position line) const { - return cb.LineStart(line); -} - -bool Document::IsLineStartPosition(int position) const { - return LineStart(LineFromPosition(position)) == position; -} - -Sci_Position SCI_METHOD Document::LineEnd(Sci_Position line) const { - if (line >= LinesTotal() - 1) { - return LineStart(line + 1); - } else { - int position = LineStart(line + 1); - if (SC_CP_UTF8 == dbcsCodePage) { - unsigned char bytes[] = { - static_cast(cb.CharAt(position-3)), - static_cast(cb.CharAt(position-2)), - static_cast(cb.CharAt(position-1)), - }; - if (UTF8IsSeparator(bytes)) { - return position - UTF8SeparatorLength; - } - if (UTF8IsNEL(bytes+1)) { - return position - UTF8NELLength; - } - } - position--; // Back over CR or LF - // When line terminator is CR+LF, may need to go back one more - if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) { - position--; - } - return position; - } -} - -void SCI_METHOD Document::SetErrorStatus(int status) { - // Tell the watchers an error has occurred. - for (std::vector::iterator it = watchers.begin(); it != watchers.end(); ++it) { - it->watcher->NotifyErrorOccurred(this, it->userData, status); - } -} - -Sci_Position SCI_METHOD Document::LineFromPosition(Sci_Position pos) const { - return cb.LineFromPosition(pos); -} - -int Document::LineEndPosition(int position) const { - return LineEnd(LineFromPosition(position)); -} - -bool Document::IsLineEndPosition(int position) const { - return LineEnd(LineFromPosition(position)) == position; -} - -bool Document::IsPositionInLineEnd(int position) const { - return position >= LineEnd(LineFromPosition(position)); -} - -int Document::VCHomePosition(int position) const { - int line = LineFromPosition(position); - int startPosition = LineStart(line); - int endLine = LineEnd(line); - int startText = startPosition; - while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t')) - startText++; - if (position == startText) - return startPosition; - else - return startText; -} - -int SCI_METHOD Document::SetLevel(Sci_Position line, int level) { - int prev = static_cast(perLineData[ldLevels])->SetLevel(line, level, LinesTotal()); - if (prev != level) { - DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER, - LineStart(line), 0, 0, 0, line); - mh.foldLevelNow = level; - mh.foldLevelPrev = prev; - NotifyModified(mh); - } - return prev; -} - -int SCI_METHOD Document::GetLevel(Sci_Position line) const { - return static_cast(perLineData[ldLevels])->GetLevel(line); -} - -void Document::ClearLevels() { - static_cast(perLineData[ldLevels])->ClearLevels(); -} - -static bool IsSubordinate(int levelStart, int levelTry) { - if (levelTry & SC_FOLDLEVELWHITEFLAG) - return true; - else - return LevelNumber(levelStart) < LevelNumber(levelTry); -} - -int Document::GetLastChild(int lineParent, int level, int lastLine) { - if (level == -1) - level = LevelNumber(GetLevel(lineParent)); - int maxLine = LinesTotal(); - int lookLastLine = (lastLine != -1) ? Platform::Minimum(LinesTotal() - 1, lastLine) : -1; - int lineMaxSubord = lineParent; - while (lineMaxSubord < maxLine - 1) { - EnsureStyledTo(LineStart(lineMaxSubord + 2)); - if (!IsSubordinate(level, GetLevel(lineMaxSubord + 1))) - break; - if ((lookLastLine != -1) && (lineMaxSubord >= lookLastLine) && !(GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG)) - break; - lineMaxSubord++; - } - if (lineMaxSubord > lineParent) { - if (level > LevelNumber(GetLevel(lineMaxSubord + 1))) { - // Have chewed up some whitespace that belongs to a parent so seek back - if (GetLevel(lineMaxSubord) & SC_FOLDLEVELWHITEFLAG) { - lineMaxSubord--; - } - } - } - return lineMaxSubord; -} - -int Document::GetFoldParent(int line) const { - int level = LevelNumber(GetLevel(line)); - int lineLook = line - 1; - while ((lineLook > 0) && ( - (!(GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG)) || - (LevelNumber(GetLevel(lineLook)) >= level)) - ) { - lineLook--; - } - if ((GetLevel(lineLook) & SC_FOLDLEVELHEADERFLAG) && - (LevelNumber(GetLevel(lineLook)) < level)) { - return lineLook; - } else { - return -1; - } -} - -void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int lastLine) { - int level = GetLevel(line); - int lookLastLine = Platform::Maximum(line, lastLine) + 1; - - int lookLine = line; - int lookLineLevel = level; - int lookLineLevelNum = LevelNumber(lookLineLevel); - while ((lookLine > 0) && ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || - ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum >= LevelNumber(GetLevel(lookLine + 1)))))) { - lookLineLevel = GetLevel(--lookLine); - lookLineLevelNum = LevelNumber(lookLineLevel); - } - - int beginFoldBlock = (lookLineLevel & SC_FOLDLEVELHEADERFLAG) ? lookLine : GetFoldParent(lookLine); - if (beginFoldBlock == -1) { - highlightDelimiter.Clear(); - return; - } - - int endFoldBlock = GetLastChild(beginFoldBlock, -1, lookLastLine); - int firstChangeableLineBefore = -1; - if (endFoldBlock < line) { - lookLine = beginFoldBlock - 1; - lookLineLevel = GetLevel(lookLine); - lookLineLevelNum = LevelNumber(lookLineLevel); - while ((lookLine >= 0) && (lookLineLevelNum >= SC_FOLDLEVELBASE)) { - if (lookLineLevel & SC_FOLDLEVELHEADERFLAG) { - if (GetLastChild(lookLine, -1, lookLastLine) == line) { - beginFoldBlock = lookLine; - endFoldBlock = line; - firstChangeableLineBefore = line - 1; - } - } - if ((lookLine > 0) && (lookLineLevelNum == SC_FOLDLEVELBASE) && (LevelNumber(GetLevel(lookLine - 1)) > lookLineLevelNum)) - break; - lookLineLevel = GetLevel(--lookLine); - lookLineLevelNum = LevelNumber(lookLineLevel); - } - } - if (firstChangeableLineBefore == -1) { - for (lookLine = line - 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = LevelNumber(lookLineLevel); - lookLine >= beginFoldBlock; - lookLineLevel = GetLevel(--lookLine), lookLineLevelNum = LevelNumber(lookLineLevel)) { - if ((lookLineLevel & SC_FOLDLEVELWHITEFLAG) || (lookLineLevelNum > LevelNumber(level))) { - firstChangeableLineBefore = lookLine; - break; - } - } - } - if (firstChangeableLineBefore == -1) - firstChangeableLineBefore = beginFoldBlock - 1; - - int firstChangeableLineAfter = -1; - for (lookLine = line + 1, lookLineLevel = GetLevel(lookLine), lookLineLevelNum = LevelNumber(lookLineLevel); - lookLine <= endFoldBlock; - lookLineLevel = GetLevel(++lookLine), lookLineLevelNum = LevelNumber(lookLineLevel)) { - if ((lookLineLevel & SC_FOLDLEVELHEADERFLAG) && (lookLineLevelNum < LevelNumber(GetLevel(lookLine + 1)))) { - firstChangeableLineAfter = lookLine; - break; - } - } - if (firstChangeableLineAfter == -1) - firstChangeableLineAfter = endFoldBlock + 1; - - highlightDelimiter.beginFoldBlock = beginFoldBlock; - highlightDelimiter.endFoldBlock = endFoldBlock; - highlightDelimiter.firstChangeableLineBefore = firstChangeableLineBefore; - highlightDelimiter.firstChangeableLineAfter = firstChangeableLineAfter; -} - -int Document::ClampPositionIntoDocument(int pos) const { - return Platform::Clamp(pos, 0, Length()); -} - -bool Document::IsCrLf(int pos) const { - if (pos < 0) - return false; - if (pos >= (Length() - 1)) - return false; - return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n'); -} - -int Document::LenChar(int pos) { - if (pos < 0) { - return 1; - } else if (IsCrLf(pos)) { - return 2; - } else if (SC_CP_UTF8 == dbcsCodePage) { - const unsigned char leadByte = static_cast(cb.CharAt(pos)); - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - int lengthDoc = Length(); - if ((pos + widthCharBytes) > lengthDoc) - return lengthDoc - pos; - else - return widthCharBytes; - } else if (dbcsCodePage) { - return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1; - } else { - return 1; - } -} - -bool Document::InGoodUTF8(int pos, int &start, int &end) const { - int trail = pos; - while ((trail>0) && (pos-trail < UTF8MaxBytes) && UTF8IsTrailByte(static_cast(cb.CharAt(trail-1)))) - trail--; - start = (trail > 0) ? trail-1 : trail; - - const unsigned char leadByte = static_cast(cb.CharAt(start)); - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - if (widthCharBytes == 1) { - return false; - } else { - int trailBytes = widthCharBytes - 1; - int len = pos - start; - if (len > trailBytes) - // pos too far from lead - return false; - char charBytes[UTF8MaxBytes] = {static_cast(leadByte),0,0,0}; - for (int b=1; b(start+b)); - int utf8status = UTF8Classify(reinterpret_cast(charBytes), widthCharBytes); - if (utf8status & UTF8MaskInvalid) - return false; - end = start + widthCharBytes; - return true; - } -} - -// Normalise a position so that it is not halfway through a two byte character. -// This can occur in two situations - -// When lines are terminated with \r\n pairs which should be treated as one character. -// When displaying DBCS text such as Japanese. -// If moving, move the position in the indicated direction. -int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) const { - //Platform::DebugPrintf("NoCRLF %d %d\n", pos, moveDir); - // If out of range, just return minimum/maximum value. - if (pos <= 0) - return 0; - if (pos >= Length()) - return Length(); - - // PLATFORM_ASSERT(pos > 0 && pos < Length()); - if (checkLineEnd && IsCrLf(pos - 1)) { - if (moveDir > 0) - return pos + 1; - else - return pos - 1; - } - - if (dbcsCodePage) { - if (SC_CP_UTF8 == dbcsCodePage) { - unsigned char ch = static_cast(cb.CharAt(pos)); - // If ch is not a trail byte then pos is valid intercharacter position - if (UTF8IsTrailByte(ch)) { - int startUTF = pos; - int endUTF = pos; - if (InGoodUTF8(pos, startUTF, endUTF)) { - // ch is a trail byte within a UTF-8 character - if (moveDir > 0) - pos = endUTF; - else - pos = startUTF; - } - // Else invalid UTF-8 so return position of isolated trail byte - } - } else { - // Anchor DBCS calculations at start of line because start of line can - // not be a DBCS trail byte. - int posStartLine = LineStart(LineFromPosition(pos)); - if (pos == posStartLine) - return pos; - - // Step back until a non-lead-byte is found. - int posCheck = pos; - while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1))) - posCheck--; - - // Check from known start of character. - while (posCheck < pos) { - int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1; - if (posCheck + mbsize == pos) { - return pos; - } else if (posCheck + mbsize > pos) { - if (moveDir > 0) { - return posCheck + mbsize; - } else { - return posCheck; - } - } - posCheck += mbsize; - } - } - } - - return pos; -} - -// NextPosition moves between valid positions - it can not handle a position in the middle of a -// multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar. -// A \r\n pair is treated as two characters. -int Document::NextPosition(int pos, int moveDir) const { - // If out of range, just return minimum/maximum value. - int increment = (moveDir > 0) ? 1 : -1; - if (pos + increment <= 0) - return 0; - if (pos + increment >= Length()) - return Length(); - - if (dbcsCodePage) { - if (SC_CP_UTF8 == dbcsCodePage) { - if (increment == 1) { - // Simple forward movement case so can avoid some checks - const unsigned char leadByte = static_cast(cb.CharAt(pos)); - if (UTF8IsAscii(leadByte)) { - // Single byte character or invalid - pos++; - } else { - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - char charBytes[UTF8MaxBytes] = {static_cast(leadByte),0,0,0}; - for (int b=1; b(pos+b)); - int utf8status = UTF8Classify(reinterpret_cast(charBytes), widthCharBytes); - if (utf8status & UTF8MaskInvalid) - pos++; - else - pos += utf8status & UTF8MaskWidth; - } - } else { - // Examine byte before position - pos--; - unsigned char ch = static_cast(cb.CharAt(pos)); - // If ch is not a trail byte then pos is valid intercharacter position - if (UTF8IsTrailByte(ch)) { - // If ch is a trail byte in a valid UTF-8 character then return start of character - int startUTF = pos; - int endUTF = pos; - if (InGoodUTF8(pos, startUTF, endUTF)) { - pos = startUTF; - } - // Else invalid UTF-8 so return position of isolated trail byte - } - } - } else { - if (moveDir > 0) { - int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1; - pos += mbsize; - if (pos > Length()) - pos = Length(); - } else { - // Anchor DBCS calculations at start of line because start of line can - // not be a DBCS trail byte. - int posStartLine = LineStart(LineFromPosition(pos)); - // See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx - // http://msdn.microsoft.com/en-us/library/cc194790.aspx - if ((pos - 1) <= posStartLine) { - return pos - 1; - } else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) { - // Must actually be trail byte - return pos - 2; - } else { - // Otherwise, step back until a non-lead-byte is found. - int posTemp = pos - 1; - while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp))) - ; - // Now posTemp+1 must point to the beginning of a character, - // so figure out whether we went back an even or an odd - // number of bytes and go back 1 or 2 bytes, respectively. - return (pos - 1 - ((pos - posTemp) & 1)); - } - } - } - } else { - pos += increment; - } - - return pos; -} - -bool Document::NextCharacter(int &pos, int moveDir) const { - // Returns true if pos changed - int posNext = NextPosition(pos, moveDir); - if (posNext == pos) { - return false; - } else { - pos = posNext; - return true; - } -} - -Document::CharacterExtracted Document::CharacterAfter(int position) const { - if (position >= Length()) { - return CharacterExtracted(unicodeReplacementChar, 0); - } - const unsigned char leadByte = static_cast(cb.CharAt(position)); - if (!dbcsCodePage || UTF8IsAscii(leadByte)) { - // Common case: ASCII character - return CharacterExtracted(leadByte, 1); - } - if (SC_CP_UTF8 == dbcsCodePage) { - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; - for (int b = 1; b(cb.CharAt(position + b)); - int utf8status = UTF8Classify(charBytes, widthCharBytes); - if (utf8status & UTF8MaskInvalid) { - // Treat as invalid and use up just one byte - return CharacterExtracted(unicodeReplacementChar, 1); - } else { - return CharacterExtracted(UnicodeFromUTF8(charBytes), utf8status & UTF8MaskWidth); - } - } else { - if (IsDBCSLeadByte(leadByte) && ((position + 1) < Length())) { - return CharacterExtracted::DBCS(leadByte, static_cast(cb.CharAt(position + 1))); - } else { - return CharacterExtracted(leadByte, 1); - } - } -} - -Document::CharacterExtracted Document::CharacterBefore(int position) const { - if (position <= 0) { - return CharacterExtracted(unicodeReplacementChar, 0); - } - const unsigned char previousByte = static_cast(cb.CharAt(position - 1)); - if (0 == dbcsCodePage) { - return CharacterExtracted(previousByte, 1); - } - if (SC_CP_UTF8 == dbcsCodePage) { - if (UTF8IsAscii(previousByte)) { - return CharacterExtracted(previousByte, 1); - } - position--; - // If previousByte is not a trail byte then its invalid - if (UTF8IsTrailByte(previousByte)) { - // If previousByte is a trail byte in a valid UTF-8 character then find start of character - int startUTF = position; - int endUTF = position; - if (InGoodUTF8(position, startUTF, endUTF)) { - const int widthCharBytes = endUTF - startUTF; - unsigned char charBytes[UTF8MaxBytes] = { 0, 0, 0, 0 }; - for (int b = 0; b(cb.CharAt(startUTF + b)); - int utf8status = UTF8Classify(charBytes, widthCharBytes); - if (utf8status & UTF8MaskInvalid) { - // Treat as invalid and use up just one byte - return CharacterExtracted(unicodeReplacementChar, 1); - } else { - return CharacterExtracted(UnicodeFromUTF8(charBytes), utf8status & UTF8MaskWidth); - } - } - // Else invalid UTF-8 so return position of isolated trail byte - } - return CharacterExtracted(unicodeReplacementChar, 1); - } else { - // Moving backwards in DBCS is complex so use NextPosition - const int posStartCharacter = NextPosition(position, -1); - return CharacterAfter(posStartCharacter); - } -} - -// Return -1 on out-of-bounds -Sci_Position SCI_METHOD Document::GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const { - int pos = positionStart; - if (dbcsCodePage) { - const int increment = (characterOffset > 0) ? 1 : -1; - while (characterOffset != 0) { - const int posNext = NextPosition(pos, increment); - if (posNext == pos) - return INVALID_POSITION; - pos = posNext; - characterOffset -= increment; - } - } else { - pos = positionStart + characterOffset; - if ((pos < 0) || (pos > Length())) - return INVALID_POSITION; - } - return pos; -} - -int Document::GetRelativePositionUTF16(int positionStart, int characterOffset) const { - int pos = positionStart; - if (dbcsCodePage) { - const int increment = (characterOffset > 0) ? 1 : -1; - while (characterOffset != 0) { - const int posNext = NextPosition(pos, increment); - if (posNext == pos) - return INVALID_POSITION; - if (abs(pos-posNext) > 3) // 4 byte character = 2*UTF16. - characterOffset -= increment; - pos = posNext; - characterOffset -= increment; - } - } else { - pos = positionStart + characterOffset; - if ((pos < 0) || (pos > Length())) - return INVALID_POSITION; - } - return pos; -} - -int SCI_METHOD Document::GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const { - int character; - int bytesInCharacter = 1; - if (dbcsCodePage) { - const unsigned char leadByte = static_cast(cb.CharAt(position)); - if (SC_CP_UTF8 == dbcsCodePage) { - if (UTF8IsAscii(leadByte)) { - // Single byte character or invalid - character = leadByte; - } else { - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - unsigned char charBytes[UTF8MaxBytes] = {leadByte,0,0,0}; - for (int b=1; b(cb.CharAt(position+b)); - int utf8status = UTF8Classify(charBytes, widthCharBytes); - if (utf8status & UTF8MaskInvalid) { - // Report as singleton surrogate values which are invalid Unicode - character = 0xDC80 + leadByte; - } else { - bytesInCharacter = utf8status & UTF8MaskWidth; - character = UnicodeFromUTF8(charBytes); - } - } - } else { - if (IsDBCSLeadByte(leadByte)) { - bytesInCharacter = 2; - character = (leadByte << 8) | static_cast(cb.CharAt(position+1)); - } else { - character = leadByte; - } - } - } else { - character = cb.CharAt(position); - } - if (pWidth) { - *pWidth = bytesInCharacter; - } - return character; -} - -int SCI_METHOD Document::CodePage() const { - return dbcsCodePage; -} - -bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const { - // Byte ranges found in Wikipedia articles with relevant search strings in each case - unsigned char uch = static_cast(ch); - switch (dbcsCodePage) { - case 932: - // Shift_jis - return ((uch >= 0x81) && (uch <= 0x9F)) || - ((uch >= 0xE0) && (uch <= 0xFC)); - // Lead bytes F0 to FC may be a Microsoft addition. - case 936: - // GBK - return (uch >= 0x81) && (uch <= 0xFE); - case 949: - // Korean Wansung KS C-5601-1987 - return (uch >= 0x81) && (uch <= 0xFE); - case 950: - // Big5 - return (uch >= 0x81) && (uch <= 0xFE); - case 1361: - // Korean Johab KS C-5601-1992 - return - ((uch >= 0x84) && (uch <= 0xD3)) || - ((uch >= 0xD8) && (uch <= 0xDE)) || - ((uch >= 0xE0) && (uch <= 0xF9)); - } - return false; -} - -static inline bool IsSpaceOrTab(int ch) { - return ch == ' ' || ch == '\t'; -} - -// Need to break text into segments near lengthSegment but taking into -// account the encoding to not break inside a UTF-8 or DBCS character -// and also trying to avoid breaking inside a pair of combining characters. -// The segment length must always be long enough (more than 4 bytes) -// so that there will be at least one whole character to make a segment. -// For UTF-8, text must consist only of valid whole characters. -// In preference order from best to worst: -// 1) Break after space -// 2) Break before punctuation -// 3) Break after whole character - -int Document::SafeSegment(const char *text, int length, int lengthSegment) const { - if (length <= lengthSegment) - return length; - int lastSpaceBreak = -1; - int lastPunctuationBreak = -1; - int lastEncodingAllowedBreak = 0; - for (int j=0; j < lengthSegment;) { - unsigned char ch = static_cast(text[j]); - if (j > 0) { - if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) { - lastSpaceBreak = j; - } - if (ch < 'A') { - lastPunctuationBreak = j; - } - } - lastEncodingAllowedBreak = j; - - if (dbcsCodePage == SC_CP_UTF8) { - j += UTF8BytesOfLead[ch]; - } else if (dbcsCodePage) { - j += IsDBCSLeadByte(ch) ? 2 : 1; - } else { - j++; - } - } - if (lastSpaceBreak >= 0) { - return lastSpaceBreak; - } else if (lastPunctuationBreak >= 0) { - return lastPunctuationBreak; - } - return lastEncodingAllowedBreak; -} - -EncodingFamily Document::CodePageFamily() const { - if (SC_CP_UTF8 == dbcsCodePage) - return efUnicode; - else if (dbcsCodePage) - return efDBCS; - else - return efEightBit; -} - -void Document::ModifiedAt(int pos) { - if (endStyled > pos) - endStyled = pos; -} - -void Document::CheckReadOnly() { - if (cb.IsReadOnly() && enteredReadOnlyCount == 0) { - enteredReadOnlyCount++; - NotifyModifyAttempt(); - enteredReadOnlyCount--; - } -} - -// Document only modified by gateways DeleteChars, InsertString, Undo, Redo, and SetStyleAt. -// SetStyleAt does not change the persistent state of a document - -bool Document::DeleteChars(int pos, int len) { - if (pos < 0) - return false; - if (len <= 0) - return false; - if ((pos + len) > Length()) - return false; - CheckReadOnly(); - if (enteredModification != 0) { - return false; - } else { - enteredModification++; - if (!cb.IsReadOnly()) { - NotifyModified( - DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_USER, - pos, len, - 0, 0)); - int prevLinesTotal = LinesTotal(); - bool startSavePoint = cb.IsSavePoint(); - bool startSequence = false; - const char *text = cb.DeleteChars(pos, len, startSequence); - if (startSavePoint && cb.IsCollectingUndo()) - NotifySavePoint(!startSavePoint); - if ((pos < Length()) || (pos == 0)) - ModifiedAt(pos); - else - ModifiedAt(pos-1); - NotifyModified( - DocModification( - SC_MOD_DELETETEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), - pos, len, - LinesTotal() - prevLinesTotal, text)); - } - enteredModification--; - } - return !cb.IsReadOnly(); -} - -/** - * Insert a string with a length. - */ -int Document::InsertString(int position, const char *s, int insertLength) { - if (insertLength <= 0) { - return 0; - } - CheckReadOnly(); // Application may change read only state here - if (cb.IsReadOnly()) { - return 0; - } - if (enteredModification != 0) { - return 0; - } - enteredModification++; - insertionSet = false; - insertion.clear(); - NotifyModified( - DocModification( - SC_MOD_INSERTCHECK, - position, insertLength, - 0, s)); - if (insertionSet) { - s = insertion.c_str(); - insertLength = static_cast(insertion.length()); - } - NotifyModified( - DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_USER, - position, insertLength, - 0, s)); - int prevLinesTotal = LinesTotal(); - bool startSavePoint = cb.IsSavePoint(); - bool startSequence = false; - const char *text = cb.InsertString(position, s, insertLength, startSequence); - if (startSavePoint && cb.IsCollectingUndo()) - NotifySavePoint(!startSavePoint); - ModifiedAt(position); - NotifyModified( - DocModification( - SC_MOD_INSERTTEXT | SC_PERFORMED_USER | (startSequence?SC_STARTACTION:0), - position, insertLength, - LinesTotal() - prevLinesTotal, text)); - if (insertionSet) { // Free memory as could be large - std::string().swap(insertion); - } - enteredModification--; - return insertLength; -} - -void Document::ChangeInsertion(const char *s, int length) { - insertionSet = true; - insertion.assign(s, length); -} - -int SCI_METHOD Document::AddData(char *data, Sci_Position length) { - try { - int position = Length(); - InsertString(position, data, length); - } catch (std::bad_alloc &) { - return SC_STATUS_BADALLOC; - } catch (...) { - return SC_STATUS_FAILURE; - } - return 0; -} - -void * SCI_METHOD Document::ConvertToDocument() { - return this; -} - -int Document::Undo() { - int newPos = -1; - CheckReadOnly(); - if ((enteredModification == 0) && (cb.IsCollectingUndo())) { - enteredModification++; - if (!cb.IsReadOnly()) { - bool startSavePoint = cb.IsSavePoint(); - bool multiLine = false; - int steps = cb.StartUndo(); - //Platform::DebugPrintf("Steps=%d\n", steps); - int coalescedRemovePos = -1; - int coalescedRemoveLen = 0; - int prevRemoveActionPos = -1; - int prevRemoveActionLen = 0; - for (int step = 0; step < steps; step++) { - const int prevLinesTotal = LinesTotal(); - const Action &action = cb.GetUndoStep(); - if (action.at == removeAction) { - NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_UNDO, action)); - } else if (action.at == containerAction) { - DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO); - dm.token = action.position; - NotifyModified(dm); - if (!action.mayCoalesce) { - coalescedRemovePos = -1; - coalescedRemoveLen = 0; - prevRemoveActionPos = -1; - prevRemoveActionLen = 0; - } - } else { - NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_UNDO, action)); - } - cb.PerformUndoStep(); - if (action.at != containerAction) { - ModifiedAt(action.position); - newPos = action.position; - } - - int modFlags = SC_PERFORMED_UNDO; - // With undo, an insertion action becomes a deletion notification - if (action.at == removeAction) { - newPos += action.lenData; - modFlags |= SC_MOD_INSERTTEXT; - if ((coalescedRemoveLen > 0) && - (action.position == prevRemoveActionPos || action.position == (prevRemoveActionPos + prevRemoveActionLen))) { - coalescedRemoveLen += action.lenData; - newPos = coalescedRemovePos + coalescedRemoveLen; - } else { - coalescedRemovePos = action.position; - coalescedRemoveLen = action.lenData; - } - prevRemoveActionPos = action.position; - prevRemoveActionLen = action.lenData; - } else if (action.at == insertAction) { - modFlags |= SC_MOD_DELETETEXT; - coalescedRemovePos = -1; - coalescedRemoveLen = 0; - prevRemoveActionPos = -1; - prevRemoveActionLen = 0; - } - if (steps > 1) - modFlags |= SC_MULTISTEPUNDOREDO; - const int linesAdded = LinesTotal() - prevLinesTotal; - if (linesAdded != 0) - multiLine = true; - if (step == steps - 1) { - modFlags |= SC_LASTSTEPINUNDOREDO; - if (multiLine) - modFlags |= SC_MULTILINEUNDOREDO; - } - NotifyModified(DocModification(modFlags, action.position, action.lenData, - linesAdded, action.data)); - } - - bool endSavePoint = cb.IsSavePoint(); - if (startSavePoint != endSavePoint) - NotifySavePoint(endSavePoint); - } - enteredModification--; - } - return newPos; -} - -int Document::Redo() { - int newPos = -1; - CheckReadOnly(); - if ((enteredModification == 0) && (cb.IsCollectingUndo())) { - enteredModification++; - if (!cb.IsReadOnly()) { - bool startSavePoint = cb.IsSavePoint(); - bool multiLine = false; - int steps = cb.StartRedo(); - for (int step = 0; step < steps; step++) { - const int prevLinesTotal = LinesTotal(); - const Action &action = cb.GetRedoStep(); - if (action.at == insertAction) { - NotifyModified(DocModification( - SC_MOD_BEFOREINSERT | SC_PERFORMED_REDO, action)); - } else if (action.at == containerAction) { - DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_REDO); - dm.token = action.position; - NotifyModified(dm); - } else { - NotifyModified(DocModification( - SC_MOD_BEFOREDELETE | SC_PERFORMED_REDO, action)); - } - cb.PerformRedoStep(); - if (action.at != containerAction) { - ModifiedAt(action.position); - newPos = action.position; - } - - int modFlags = SC_PERFORMED_REDO; - if (action.at == insertAction) { - newPos += action.lenData; - modFlags |= SC_MOD_INSERTTEXT; - } else if (action.at == removeAction) { - modFlags |= SC_MOD_DELETETEXT; - } - if (steps > 1) - modFlags |= SC_MULTISTEPUNDOREDO; - const int linesAdded = LinesTotal() - prevLinesTotal; - if (linesAdded != 0) - multiLine = true; - if (step == steps - 1) { - modFlags |= SC_LASTSTEPINUNDOREDO; - if (multiLine) - modFlags |= SC_MULTILINEUNDOREDO; - } - NotifyModified( - DocModification(modFlags, action.position, action.lenData, - linesAdded, action.data)); - } - - bool endSavePoint = cb.IsSavePoint(); - if (startSavePoint != endSavePoint) - NotifySavePoint(endSavePoint); - } - enteredModification--; - } - return newPos; -} - -void Document::DelChar(int pos) { - DeleteChars(pos, LenChar(pos)); -} - -void Document::DelCharBack(int pos) { - if (pos <= 0) { - return; - } else if (IsCrLf(pos - 2)) { - DeleteChars(pos - 2, 2); - } else if (dbcsCodePage) { - int startChar = NextPosition(pos, -1); - DeleteChars(startChar, pos - startChar); - } else { - DeleteChars(pos - 1, 1); - } -} - -static int NextTab(int pos, int tabSize) { - return ((pos / tabSize) + 1) * tabSize; -} - -static std::string CreateIndentation(int indent, int tabSize, bool insertSpaces) { - std::string indentation; - if (!insertSpaces) { - while (indent >= tabSize) { - indentation += '\t'; - indent -= tabSize; - } - } - while (indent > 0) { - indentation += ' '; - indent--; - } - return indentation; -} - -int SCI_METHOD Document::GetLineIndentation(Sci_Position line) { - int indent = 0; - if ((line >= 0) && (line < LinesTotal())) { - int lineStart = LineStart(line); - int length = Length(); - for (int i = lineStart; i < length; i++) { - char ch = cb.CharAt(i); - if (ch == ' ') - indent++; - else if (ch == '\t') - indent = NextTab(indent, tabInChars); - else - return indent; - } - } - return indent; -} - -int Document::SetLineIndentation(int line, int indent) { - int indentOfLine = GetLineIndentation(line); - if (indent < 0) - indent = 0; - if (indent != indentOfLine) { - std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs); - int thisLineStart = LineStart(line); - int indentPos = GetLineIndentPosition(line); - UndoGroup ug(this); - DeleteChars(thisLineStart, indentPos - thisLineStart); - return thisLineStart + InsertString(thisLineStart, linebuf.c_str(), - static_cast(linebuf.length())); - } else { - return GetLineIndentPosition(line); - } -} - -int Document::GetLineIndentPosition(int line) const { - if (line < 0) - return 0; - int pos = LineStart(line); - int length = Length(); - while ((pos < length) && IsSpaceOrTab(cb.CharAt(pos))) { - pos++; - } - return pos; -} - -int Document::GetColumn(int pos) { - int column = 0; - int line = LineFromPosition(pos); - if ((line >= 0) && (line < LinesTotal())) { - for (int i = LineStart(line); i < pos;) { - char ch = cb.CharAt(i); - if (ch == '\t') { - column = NextTab(column, tabInChars); - i++; - } else if (ch == '\r') { - return column; - } else if (ch == '\n') { - return column; - } else if (i >= Length()) { - return column; - } else { - column++; - i = NextPosition(i, 1); - } - } - } - return column; -} - -int Document::CountCharacters(int startPos, int endPos) const { - startPos = MovePositionOutsideChar(startPos, 1, false); - endPos = MovePositionOutsideChar(endPos, -1, false); - int count = 0; - int i = startPos; - while (i < endPos) { - count++; - i = NextPosition(i, 1); - } - return count; -} - -int Document::CountUTF16(int startPos, int endPos) const { - startPos = MovePositionOutsideChar(startPos, 1, false); - endPos = MovePositionOutsideChar(endPos, -1, false); - int count = 0; - int i = startPos; - while (i < endPos) { - count++; - const int next = NextPosition(i, 1); - if ((next - i) > 3) - count++; - i = next; - } - return count; -} - -int Document::FindColumn(int line, int column) { - int position = LineStart(line); - if ((line >= 0) && (line < LinesTotal())) { - int columnCurrent = 0; - while ((columnCurrent < column) && (position < Length())) { - char ch = cb.CharAt(position); - if (ch == '\t') { - columnCurrent = NextTab(columnCurrent, tabInChars); - if (columnCurrent > column) - return position; - position++; - } else if (ch == '\r') { - return position; - } else if (ch == '\n') { - return position; - } else { - columnCurrent++; - position = NextPosition(position, 1); - } - } - } - return position; -} - -void Document::Indent(bool forwards, int lineBottom, int lineTop) { - // Dedent - suck white space off the front of the line to dedent by equivalent of a tab - for (int line = lineBottom; line >= lineTop; line--) { - int indentOfLine = GetLineIndentation(line); - if (forwards) { - if (LineStart(line) < LineEnd(line)) { - SetLineIndentation(line, indentOfLine + IndentSize()); - } - } else { - SetLineIndentation(line, indentOfLine - IndentSize()); - } - } -} - -// Convert line endings for a piece of text to a particular mode. -// Stop at len or when a NUL is found. -std::string Document::TransformLineEnds(const char *s, size_t len, int eolModeWanted) { - std::string dest; - for (size_t i = 0; (i < len) && (s[i]); i++) { - if (s[i] == '\n' || s[i] == '\r') { - if (eolModeWanted == SC_EOL_CR) { - dest.push_back('\r'); - } else if (eolModeWanted == SC_EOL_LF) { - dest.push_back('\n'); - } else { // eolModeWanted == SC_EOL_CRLF - dest.push_back('\r'); - dest.push_back('\n'); - } - if ((s[i] == '\r') && (i+1 < len) && (s[i+1] == '\n')) { - i++; - } - } else { - dest.push_back(s[i]); - } - } - return dest; -} - -void Document::ConvertLineEnds(int eolModeSet) { - UndoGroup ug(this); - - for (int pos = 0; pos < Length(); pos++) { - if (cb.CharAt(pos) == '\r') { - if (cb.CharAt(pos + 1) == '\n') { - // CRLF - if (eolModeSet == SC_EOL_CR) { - DeleteChars(pos + 1, 1); // Delete the LF - } else if (eolModeSet == SC_EOL_LF) { - DeleteChars(pos, 1); // Delete the CR - } else { - pos++; - } - } else { - // CR - if (eolModeSet == SC_EOL_CRLF) { - pos += InsertString(pos + 1, "\n", 1); // Insert LF - } else if (eolModeSet == SC_EOL_LF) { - pos += InsertString(pos, "\n", 1); // Insert LF - DeleteChars(pos, 1); // Delete CR - pos--; - } - } - } else if (cb.CharAt(pos) == '\n') { - // LF - if (eolModeSet == SC_EOL_CRLF) { - pos += InsertString(pos, "\r", 1); // Insert CR - } else if (eolModeSet == SC_EOL_CR) { - pos += InsertString(pos, "\r", 1); // Insert CR - DeleteChars(pos, 1); // Delete LF - pos--; - } - } - } - -} - -bool Document::IsWhiteLine(int line) const { - int currentChar = LineStart(line); - int endLine = LineEnd(line); - while (currentChar < endLine) { - if (cb.CharAt(currentChar) != ' ' && cb.CharAt(currentChar) != '\t') { - return false; - } - ++currentChar; - } - return true; -} - -int Document::ParaUp(int pos) const { - int line = LineFromPosition(pos); - line--; - while (line >= 0 && IsWhiteLine(line)) { // skip empty lines - line--; - } - while (line >= 0 && !IsWhiteLine(line)) { // skip non-empty lines - line--; - } - line++; - return LineStart(line); -} - -int Document::ParaDown(int pos) const { - int line = LineFromPosition(pos); - while (line < LinesTotal() && !IsWhiteLine(line)) { // skip non-empty lines - line++; - } - while (line < LinesTotal() && IsWhiteLine(line)) { // skip empty lines - line++; - } - if (line < LinesTotal()) - return LineStart(line); - else // end of a document - return LineEnd(line-1); -} - -bool Document::IsASCIIWordByte(unsigned char ch) const { - if (IsASCII(ch)) { - return charClass.GetClass(ch) == CharClassify::ccWord; - } else { - return false; - } -} - -CharClassify::cc Document::WordCharacterClass(unsigned int ch) const { - if (dbcsCodePage && (!UTF8IsAscii(ch))) { - if (SC_CP_UTF8 == dbcsCodePage) { - // Use hard coded Unicode class - const CharacterCategory cc = CategoriseCharacter(ch); - switch (cc) { - - // Separator, Line/Paragraph - case ccZl: - case ccZp: - return CharClassify::ccNewLine; - - // Separator, Space - case ccZs: - // Other - case ccCc: - case ccCf: - case ccCs: - case ccCo: - case ccCn: - return CharClassify::ccSpace; - - // Letter - case ccLu: - case ccLl: - case ccLt: - case ccLm: - case ccLo: - // Number - case ccNd: - case ccNl: - case ccNo: - // Mark - includes combining diacritics - case ccMn: - case ccMc: - case ccMe: - return CharClassify::ccWord; - - // Punctuation - case ccPc: - case ccPd: - case ccPs: - case ccPe: - case ccPi: - case ccPf: - case ccPo: - // Symbol - case ccSm: - case ccSc: - case ccSk: - case ccSo: - return CharClassify::ccPunctuation; - - } - } else { - // Asian DBCS - return CharClassify::ccWord; - } - } - return charClass.GetClass(static_cast(ch)); -} - -/** - * Used by commmands that want to select whole words. - * Finds the start of word at pos when delta < 0 or the end of the word when delta >= 0. - */ -int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) const { - CharClassify::cc ccStart = CharClassify::ccWord; - if (delta < 0) { - if (!onlyWordCharacters) { - const CharacterExtracted ce = CharacterBefore(pos); - ccStart = WordCharacterClass(ce.character); - } - while (pos > 0) { - const CharacterExtracted ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != ccStart) - break; - pos -= ce.widthBytes; - } - } else { - if (!onlyWordCharacters && pos < Length()) { - const CharacterExtracted ce = CharacterAfter(pos); - ccStart = WordCharacterClass(ce.character); - } - while (pos < Length()) { - const CharacterExtracted ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != ccStart) - break; - pos += ce.widthBytes; - } - } - return MovePositionOutsideChar(pos, delta, true); -} - -/** - * Find the start of the next word in either a forward (delta >= 0) or backwards direction - * (delta < 0). - * This is looking for a transition between character classes although there is also some - * additional movement to transit white space. - * Used by cursor movement by word commands. - */ -int Document::NextWordStart(int pos, int delta) const { - if (delta < 0) { - while (pos > 0) { - const CharacterExtracted ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) - break; - pos -= ce.widthBytes; - } - if (pos > 0) { - CharacterExtracted ce = CharacterBefore(pos); - const CharClassify::cc ccStart = WordCharacterClass(ce.character); - while (pos > 0) { - ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != ccStart) - break; - pos -= ce.widthBytes; - } - } - } else { - CharacterExtracted ce = CharacterAfter(pos); - const CharClassify::cc ccStart = WordCharacterClass(ce.character); - while (pos < Length()) { - ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != ccStart) - break; - pos += ce.widthBytes; - } - while (pos < Length()) { - ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) - break; - pos += ce.widthBytes; - } - } - return pos; -} - -/** - * Find the end of the next word in either a forward (delta >= 0) or backwards direction - * (delta < 0). - * This is looking for a transition between character classes although there is also some - * additional movement to transit white space. - * Used by cursor movement by word commands. - */ -int Document::NextWordEnd(int pos, int delta) const { - if (delta < 0) { - if (pos > 0) { - CharacterExtracted ce = CharacterBefore(pos); - CharClassify::cc ccStart = WordCharacterClass(ce.character); - if (ccStart != CharClassify::ccSpace) { - while (pos > 0) { - ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != ccStart) - break; - pos -= ce.widthBytes; - } - } - while (pos > 0) { - ce = CharacterBefore(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) - break; - pos -= ce.widthBytes; - } - } - } else { - while (pos < Length()) { - CharacterExtracted ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != CharClassify::ccSpace) - break; - pos += ce.widthBytes; - } - if (pos < Length()) { - CharacterExtracted ce = CharacterAfter(pos); - CharClassify::cc ccStart = WordCharacterClass(ce.character); - while (pos < Length()) { - ce = CharacterAfter(pos); - if (WordCharacterClass(ce.character) != ccStart) - break; - pos += ce.widthBytes; - } - } - } - return pos; -} - -/** - * Check that the character at the given position is a word or punctuation character and that - * the previous character is of a different character class. - */ -bool Document::IsWordStartAt(int pos) const { - if (pos >= Length()) - return false; - if (pos > 0) { - const CharacterExtracted cePos = CharacterAfter(pos); - const CharClassify::cc ccPos = WordCharacterClass(cePos.character); - const CharacterExtracted cePrev = CharacterBefore(pos); - const CharClassify::cc ccPrev = WordCharacterClass(cePrev.character); - return (ccPos == CharClassify::ccWord || ccPos == CharClassify::ccPunctuation) && - (ccPos != ccPrev); - } - return true; -} - -/** - * Check that the character at the given position is a word or punctuation character and that - * the next character is of a different character class. - */ -bool Document::IsWordEndAt(int pos) const { - if (pos <= 0) - return false; - if (pos < Length()) { - const CharacterExtracted cePos = CharacterAfter(pos); - const CharClassify::cc ccPos = WordCharacterClass(cePos.character); - const CharacterExtracted cePrev = CharacterBefore(pos); - const CharClassify::cc ccPrev = WordCharacterClass(cePrev.character); - return (ccPrev == CharClassify::ccWord || ccPrev == CharClassify::ccPunctuation) && - (ccPrev != ccPos); - } - return true; -} - -/** - * Check that the given range is has transitions between character classes at both - * ends and where the characters on the inside are word or punctuation characters. - */ -bool Document::IsWordAt(int start, int end) const { - return (start < end) && IsWordStartAt(start) && IsWordEndAt(end); -} - -bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length) const { - return (!word && !wordStart) || - (word && IsWordAt(pos, pos + length)) || - (wordStart && IsWordStartAt(pos)); -} - -bool Document::HasCaseFolder(void) const { - return pcf != 0; -} - -void Document::SetCaseFolder(CaseFolder *pcf_) { - delete pcf; - pcf = pcf_; -} - -Document::CharacterExtracted Document::ExtractCharacter(int position) const { - const unsigned char leadByte = static_cast(cb.CharAt(position)); - if (UTF8IsAscii(leadByte)) { - // Common case: ASCII character - return CharacterExtracted(leadByte, 1); - } - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - unsigned char charBytes[UTF8MaxBytes] = { leadByte, 0, 0, 0 }; - for (int b=1; b(cb.CharAt(position + b)); - int utf8status = UTF8Classify(charBytes, widthCharBytes); - if (utf8status & UTF8MaskInvalid) { - // Treat as invalid and use up just one byte - return CharacterExtracted(unicodeReplacementChar, 1); - } else { - return CharacterExtracted(UnicodeFromUTF8(charBytes), utf8status & UTF8MaskWidth); - } -} - -/** - * Find text in document, supporting both forward and backward - * searches (just pass minPos > maxPos to do a backward search) - * Has not been tested with backwards DBCS searches yet. - */ -long Document::FindText(int minPos, int maxPos, const char *search, - int flags, int *length) { - if (*length <= 0) - return minPos; - const bool caseSensitive = (flags & SCFIND_MATCHCASE) != 0; - const bool word = (flags & SCFIND_WHOLEWORD) != 0; - const bool wordStart = (flags & SCFIND_WORDSTART) != 0; - const bool regExp = (flags & SCFIND_REGEXP) != 0; - if (regExp) { - if (!regex) - regex = CreateRegexSearch(&charClass); - return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length); - } else { - - const bool forward = minPos <= maxPos; - const int increment = forward ? 1 : -1; - - // Range endpoints should not be inside DBCS characters, but just in case, move them. - const int startPos = MovePositionOutsideChar(minPos, increment, false); - const int endPos = MovePositionOutsideChar(maxPos, increment, false); - - // Compute actual search ranges needed - const int lengthFind = *length; - - //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind); - const int limitPos = Platform::Maximum(startPos, endPos); - int pos = startPos; - if (!forward) { - // Back all of a character - pos = NextPosition(pos, increment); - } - if (caseSensitive) { - const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; - const char charStartSearch = search[0]; - while (forward ? (pos < endSearch) : (pos >= endSearch)) { - if (CharAt(pos) == charStartSearch) { - bool found = (pos + lengthFind) <= limitPos; - for (int indexSearch = 1; (indexSearch < lengthFind) && found; indexSearch++) { - found = CharAt(pos + indexSearch) == search[indexSearch]; - } - if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { - return pos; - } - } - if (!NextCharacter(pos, increment)) - break; - } - } else if (SC_CP_UTF8 == dbcsCodePage) { - const size_t maxFoldingExpansion = 4; - std::vector searchThing(lengthFind * UTF8MaxBytes * maxFoldingExpansion + 1); - const int lenSearch = static_cast( - pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind)); - char bytes[UTF8MaxBytes + 1]; - char folded[UTF8MaxBytes * maxFoldingExpansion + 1]; - while (forward ? (pos < endPos) : (pos >= endPos)) { - int widthFirstCharacter = 0; - int posIndexDocument = pos; - int indexSearch = 0; - bool characterMatches = true; - for (;;) { - const unsigned char leadByte = static_cast(cb.CharAt(posIndexDocument)); - bytes[0] = leadByte; - int widthChar = 1; - if (!UTF8IsAscii(leadByte)) { - const int widthCharBytes = UTF8BytesOfLead[leadByte]; - for (int b=1; b(bytes), widthCharBytes) & UTF8MaskWidth; - } - if (!widthFirstCharacter) - widthFirstCharacter = widthChar; - if ((posIndexDocument + widthChar) > limitPos) - break; - const int lenFlat = static_cast(pcf->Fold(folded, sizeof(folded), bytes, widthChar)); - folded[lenFlat] = 0; - // Does folded match the buffer - characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); - if (!characterMatches) - break; - posIndexDocument += widthChar; - indexSearch += lenFlat; - if (indexSearch >= lenSearch) - break; - } - if (characterMatches && (indexSearch == static_cast(lenSearch))) { - if (MatchesWordOptions(word, wordStart, pos, posIndexDocument - pos)) { - *length = posIndexDocument - pos; - return pos; - } - } - if (forward) { - pos += widthFirstCharacter; - } else { - if (!NextCharacter(pos, increment)) - break; - } - } - } else if (dbcsCodePage) { - const size_t maxBytesCharacter = 2; - const size_t maxFoldingExpansion = 4; - std::vector searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1); - const int lenSearch = static_cast( - pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind)); - while (forward ? (pos < endPos) : (pos >= endPos)) { - int indexDocument = 0; - int indexSearch = 0; - bool characterMatches = true; - while (characterMatches && - ((pos + indexDocument) < limitPos) && - (indexSearch < lenSearch)) { - char bytes[maxBytesCharacter + 1]; - bytes[0] = cb.CharAt(pos + indexDocument); - const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1; - if (widthChar == 2) - bytes[1] = cb.CharAt(pos + indexDocument + 1); - if ((pos + indexDocument + widthChar) > limitPos) - break; - char folded[maxBytesCharacter * maxFoldingExpansion + 1]; - const int lenFlat = static_cast(pcf->Fold(folded, sizeof(folded), bytes, widthChar)); - folded[lenFlat] = 0; - // Does folded match the buffer - characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat); - indexDocument += widthChar; - indexSearch += lenFlat; - } - if (characterMatches && (indexSearch == static_cast(lenSearch))) { - if (MatchesWordOptions(word, wordStart, pos, indexDocument)) { - *length = indexDocument; - return pos; - } - } - if (!NextCharacter(pos, increment)) - break; - } - } else { - const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos; - std::vector searchThing(lengthFind + 1); - pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind); - while (forward ? (pos < endSearch) : (pos >= endSearch)) { - bool found = (pos + lengthFind) <= limitPos; - for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) { - char ch = CharAt(pos + indexSearch); - char folded[2]; - pcf->Fold(folded, sizeof(folded), &ch, 1); - found = folded[0] == searchThing[indexSearch]; - } - if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) { - return pos; - } - if (!NextCharacter(pos, increment)) - break; - } - } - } - //Platform::DebugPrintf("Not found\n"); - return -1; -} - -const char *Document::SubstituteByPosition(const char *text, int *length) { - if (regex) - return regex->SubstituteByPosition(this, text, length); - else - return 0; -} - -int Document::LinesTotal() const { - return cb.Lines(); -} - -void Document::SetDefaultCharClasses(bool includeWordClass) { - charClass.SetDefaultCharClasses(includeWordClass); -} - -void Document::SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass) { - charClass.SetCharClasses(chars, newCharClass); -} - -int Document::GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) const { - return charClass.GetCharsOfClass(characterClass, buffer); -} - -void SCI_METHOD Document::StartStyling(Sci_Position position, char) { - endStyled = position; -} - -bool SCI_METHOD Document::SetStyleFor(Sci_Position length, char style) { - if (enteredStyling != 0) { - return false; - } else { - enteredStyling++; - int prevEndStyled = endStyled; - if (cb.SetStyleFor(endStyled, length, style)) { - DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, - prevEndStyled, length); - NotifyModified(mh); - } - endStyled += length; - enteredStyling--; - return true; - } -} - -bool SCI_METHOD Document::SetStyles(Sci_Position length, const char *styles) { - if (enteredStyling != 0) { - return false; - } else { - enteredStyling++; - bool didChange = false; - int startMod = 0; - int endMod = 0; - for (int iPos = 0; iPos < length; iPos++, endStyled++) { - PLATFORM_ASSERT(endStyled < Length()); - if (cb.SetStyleAt(endStyled, styles[iPos])) { - if (!didChange) { - startMod = endStyled; - } - didChange = true; - endMod = endStyled; - } - } - if (didChange) { - DocModification mh(SC_MOD_CHANGESTYLE | SC_PERFORMED_USER, - startMod, endMod - startMod + 1); - NotifyModified(mh); - } - enteredStyling--; - return true; - } -} - -void Document::EnsureStyledTo(int pos) { - if ((enteredStyling == 0) && (pos > GetEndStyled())) { - IncrementStyleClock(); - if (pli && !pli->UseContainerLexing()) { - int lineEndStyled = LineFromPosition(GetEndStyled()); - int endStyledTo = LineStart(lineEndStyled); - pli->Colourise(endStyledTo, pos); - } else { - // Ask the watchers to style, and stop as soon as one responds. - for (std::vector::iterator it = watchers.begin(); - (pos > GetEndStyled()) && (it != watchers.end()); ++it) { - it->watcher->NotifyStyleNeeded(this, it->userData, pos); - } - } - } -} - -void Document::StyleToAdjustingLineDuration(int pos) { - // Place bounds on the duration used to avoid glitches spiking it - // and so causing slow styling or non-responsive scrolling - const double minDurationOneLine = 0.000001; - const double maxDurationOneLine = 0.0001; - - // Alpha value for exponential smoothing. - // Most recent value contributes 25% to smoothed value. - const double alpha = 0.25; - - const Sci_Position lineFirst = LineFromPosition(GetEndStyled()); - ElapsedTime etStyling; - EnsureStyledTo(pos); - const double durationStyling = etStyling.Duration(); - const Sci_Position lineLast = LineFromPosition(GetEndStyled()); - if (lineLast >= lineFirst + 8) { - // Only adjust for styling multiple lines to avoid instability - const double durationOneLine = durationStyling / (lineLast - lineFirst); - durationStyleOneLine = alpha * durationOneLine + (1.0 - alpha) * durationStyleOneLine; - if (durationStyleOneLine < minDurationOneLine) { - durationStyleOneLine = minDurationOneLine; - } else if (durationStyleOneLine > maxDurationOneLine) { - durationStyleOneLine = maxDurationOneLine; - } - } -} - -void Document::LexerChanged() { - // Tell the watchers the lexer has changed. - for (std::vector::iterator it = watchers.begin(); it != watchers.end(); ++it) { - it->watcher->NotifyLexerChanged(this, it->userData); - } -} - -int SCI_METHOD Document::SetLineState(Sci_Position line, int state) { - int statePrevious = static_cast(perLineData[ldState])->SetLineState(line, state); - if (state != statePrevious) { - DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, 0, line); - NotifyModified(mh); - } - return statePrevious; -} - -int SCI_METHOD Document::GetLineState(Sci_Position line) const { - return static_cast(perLineData[ldState])->GetLineState(line); -} - -int Document::GetMaxLineState() { - return static_cast(perLineData[ldState])->GetMaxLineState(); -} - -void SCI_METHOD Document::ChangeLexerState(Sci_Position start, Sci_Position end) { - DocModification mh(SC_MOD_LEXERSTATE, start, end-start, 0, 0, 0); - NotifyModified(mh); -} - -StyledText Document::MarginStyledText(int line) const { - LineAnnotation *pla = static_cast(perLineData[ldMargin]); - return StyledText(pla->Length(line), pla->Text(line), - pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); -} - -void Document::MarginSetText(int line, const char *text) { - static_cast(perLineData[ldMargin])->SetText(line, text); - DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line); - NotifyModified(mh); -} - -void Document::MarginSetStyle(int line, int style) { - static_cast(perLineData[ldMargin])->SetStyle(line, style); - NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line)); -} - -void Document::MarginSetStyles(int line, const unsigned char *styles) { - static_cast(perLineData[ldMargin])->SetStyles(line, styles); - NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line)); -} - -void Document::MarginClearAll() { - int maxEditorLine = LinesTotal(); - for (int l=0; l(perLineData[ldMargin])->ClearAll(); -} - -StyledText Document::AnnotationStyledText(int line) const { - LineAnnotation *pla = static_cast(perLineData[ldAnnotation]); - return StyledText(pla->Length(line), pla->Text(line), - pla->MultipleStyles(line), pla->Style(line), pla->Styles(line)); -} - -void Document::AnnotationSetText(int line, const char *text) { - if (line >= 0 && line < LinesTotal()) { - const int linesBefore = AnnotationLines(line); - static_cast(perLineData[ldAnnotation])->SetText(line, text); - const int linesAfter = AnnotationLines(line); - DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line); - mh.annotationLinesAdded = linesAfter - linesBefore; - NotifyModified(mh); - } -} - -void Document::AnnotationSetStyle(int line, int style) { - static_cast(perLineData[ldAnnotation])->SetStyle(line, style); - DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line); - NotifyModified(mh); -} - -void Document::AnnotationSetStyles(int line, const unsigned char *styles) { - if (line >= 0 && line < LinesTotal()) { - static_cast(perLineData[ldAnnotation])->SetStyles(line, styles); - } -} - -int Document::AnnotationLines(int line) const { - return static_cast(perLineData[ldAnnotation])->Lines(line); -} - -void Document::AnnotationClearAll() { - int maxEditorLine = LinesTotal(); - for (int l=0; l(perLineData[ldAnnotation])->ClearAll(); -} - -void Document::IncrementStyleClock() { - styleClock = (styleClock + 1) % 0x100000; -} - -void SCI_METHOD Document::DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength) { - if (decorations.FillRange(position, value, fillLength)) { - DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER, - position, fillLength); - NotifyModified(mh); - } -} - -bool Document::AddWatcher(DocWatcher *watcher, void *userData) { - WatcherWithUserData wwud(watcher, userData); - std::vector::iterator it = - std::find(watchers.begin(), watchers.end(), wwud); - if (it != watchers.end()) - return false; - watchers.push_back(wwud); - return true; -} - -bool Document::RemoveWatcher(DocWatcher *watcher, void *userData) { - std::vector::iterator it = - std::find(watchers.begin(), watchers.end(), WatcherWithUserData(watcher, userData)); - if (it != watchers.end()) { - watchers.erase(it); - return true; - } - return false; -} - -void Document::NotifyModifyAttempt() { - for (std::vector::iterator it = watchers.begin(); it != watchers.end(); ++it) { - it->watcher->NotifyModifyAttempt(this, it->userData); - } -} - -void Document::NotifySavePoint(bool atSavePoint) { - for (std::vector::iterator it = watchers.begin(); it != watchers.end(); ++it) { - it->watcher->NotifySavePoint(this, it->userData, atSavePoint); - } -} - -void Document::NotifyModified(DocModification mh) { - if (mh.modificationType & SC_MOD_INSERTTEXT) { - decorations.InsertSpace(mh.position, mh.length); - } else if (mh.modificationType & SC_MOD_DELETETEXT) { - decorations.DeleteRange(mh.position, mh.length); - } - for (std::vector::iterator it = watchers.begin(); it != watchers.end(); ++it) { - it->watcher->NotifyModified(this, mh, it->userData); - } -} - -// Used for word part navigation. -static bool IsASCIIPunctuationCharacter(unsigned int ch) { - switch (ch) { - case '!': - case '"': - case '#': - case '$': - case '%': - case '&': - case '\'': - case '(': - case ')': - case '*': - case '+': - case ',': - case '-': - case '.': - case '/': - case ':': - case ';': - case '<': - case '=': - case '>': - case '?': - case '@': - case '[': - case '\\': - case ']': - case '^': - case '_': - case '`': - case '{': - case '|': - case '}': - case '~': - return true; - default: - return false; - } -} - -bool Document::IsWordPartSeparator(unsigned int ch) const { - return (WordCharacterClass(ch) == CharClassify::ccWord) && IsASCIIPunctuationCharacter(ch); -} - -int Document::WordPartLeft(int pos) const { - if (pos > 0) { - pos -= CharacterBefore(pos).widthBytes; - CharacterExtracted ceStart = CharacterAfter(pos); - if (IsWordPartSeparator(ceStart.character)) { - while (pos > 0 && IsWordPartSeparator(CharacterAfter(pos).character)) { - pos -= CharacterBefore(pos).widthBytes; - } - } - if (pos > 0) { - ceStart = CharacterAfter(pos); - pos -= CharacterBefore(pos).widthBytes; - if (IsLowerCase(ceStart.character)) { - while (pos > 0 && IsLowerCase(CharacterAfter(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - if (!IsUpperCase(CharacterAfter(pos).character) && !IsLowerCase(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (IsUpperCase(ceStart.character)) { - while (pos > 0 && IsUpperCase(CharacterAfter(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - if (!IsUpperCase(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (IsADigit(ceStart.character)) { - while (pos > 0 && IsADigit(CharacterAfter(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - if (!IsADigit(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (IsASCIIPunctuationCharacter(ceStart.character)) { - while (pos > 0 && IsASCIIPunctuationCharacter(CharacterAfter(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - if (!IsASCIIPunctuationCharacter(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (isspacechar(ceStart.character)) { - while (pos > 0 && isspacechar(CharacterAfter(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - if (!isspacechar(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (!IsASCII(ceStart.character)) { - while (pos > 0 && !IsASCII(CharacterAfter(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - if (IsASCII(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else { - pos += CharacterAfter(pos).widthBytes; - } - } - } - return pos; -} - -int Document::WordPartRight(int pos) const { - CharacterExtracted ceStart = CharacterAfter(pos); - const int length = Length(); - if (IsWordPartSeparator(ceStart.character)) { - while (pos < length && IsWordPartSeparator(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - ceStart = CharacterAfter(pos); - } - if (!IsASCII(ceStart.character)) { - while (pos < length && !IsASCII(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (IsLowerCase(ceStart.character)) { - while (pos < length && IsLowerCase(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (IsUpperCase(ceStart.character)) { - if (IsLowerCase(CharacterAfter(pos + ceStart.widthBytes).character)) { - pos += CharacterAfter(pos).widthBytes; - while (pos < length && IsLowerCase(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else { - while (pos < length && IsUpperCase(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } - if (IsLowerCase(CharacterAfter(pos).character) && IsUpperCase(CharacterBefore(pos).character)) - pos -= CharacterBefore(pos).widthBytes; - } else if (IsADigit(ceStart.character)) { - while (pos < length && IsADigit(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (IsASCIIPunctuationCharacter(ceStart.character)) { - while (pos < length && IsASCIIPunctuationCharacter(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else if (isspacechar(ceStart.character)) { - while (pos < length && isspacechar(CharacterAfter(pos).character)) - pos += CharacterAfter(pos).widthBytes; - } else { - pos += CharacterAfter(pos).widthBytes; - } - return pos; -} - -static bool IsLineEndChar(char c) { - return (c == '\n' || c == '\r'); -} - -int Document::ExtendStyleRange(int pos, int delta, bool singleLine) { - int sStart = cb.StyleAt(pos); - if (delta < 0) { - while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) - pos--; - pos++; - } else { - while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos)))) - pos++; - } - return pos; -} - -static char BraceOpposite(char ch) { - switch (ch) { - case '(': - return ')'; - case ')': - return '('; - case '[': - return ']'; - case ']': - return '['; - case '{': - return '}'; - case '}': - return '{'; - case '<': - return '>'; - case '>': - return '<'; - default: - return '\0'; - } -} - -// TODO: should be able to extend styled region to find matching brace -int Document::BraceMatch(int position, int /*maxReStyle*/) { - char chBrace = CharAt(position); - char chSeek = BraceOpposite(chBrace); - if (chSeek == '\0') - return - 1; - const int styBrace = StyleIndexAt(position); - int direction = -1; - if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<') - direction = 1; - int depth = 1; - position = NextPosition(position, direction); - while ((position >= 0) && (position < Length())) { - char chAtPos = CharAt(position); - const int styAtPos = StyleIndexAt(position); - if ((position > GetEndStyled()) || (styAtPos == styBrace)) { - if (chAtPos == chBrace) - depth++; - if (chAtPos == chSeek) - depth--; - if (depth == 0) - return position; - } - int positionBeforeMove = position; - position = NextPosition(position, direction); - if (position == positionBeforeMove) - break; - } - return - 1; -} - -/** - * Implementation of RegexSearchBase for the default built-in regular expression engine - */ -class BuiltinRegex : public RegexSearchBase { -public: - explicit BuiltinRegex(CharClassify *charClassTable) : search(charClassTable) {} - - virtual ~BuiltinRegex() { - } - - virtual long FindText(Document *doc, int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, int flags, - int *length); - - virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length); - -private: - RESearch search; - std::string substituted; -}; - -namespace { - -/** -* RESearchRange keeps track of search range. -*/ -class RESearchRange { -public: - const Document *doc; - int increment; - int startPos; - int endPos; - int lineRangeStart; - int lineRangeEnd; - int lineRangeBreak; - RESearchRange(const Document *doc_, int minPos, int maxPos) : doc(doc_) { - increment = (minPos <= maxPos) ? 1 : -1; - - // Range endpoints should not be inside DBCS characters, but just in case, move them. - startPos = doc->MovePositionOutsideChar(minPos, 1, false); - endPos = doc->MovePositionOutsideChar(maxPos, 1, false); - - lineRangeStart = doc->LineFromPosition(startPos); - lineRangeEnd = doc->LineFromPosition(endPos); - if ((increment == 1) && - (startPos >= doc->LineEnd(lineRangeStart)) && - (lineRangeStart < lineRangeEnd)) { - // the start position is at end of line or between line end characters. - lineRangeStart++; - startPos = doc->LineStart(lineRangeStart); - } else if ((increment == -1) && - (startPos <= doc->LineStart(lineRangeStart)) && - (lineRangeStart > lineRangeEnd)) { - // the start position is at beginning of line. - lineRangeStart--; - startPos = doc->LineEnd(lineRangeStart); - } - lineRangeBreak = lineRangeEnd + increment; - } - Range LineRange(int line) const { - Range range(doc->LineStart(line), doc->LineEnd(line)); - if (increment == 1) { - if (line == lineRangeStart) - range.start = startPos; - if (line == lineRangeEnd) - range.end = endPos; - } else { - if (line == lineRangeEnd) - range.start = endPos; - if (line == lineRangeStart) - range.end = startPos; - } - return range; - } -}; - -// Define a way for the Regular Expression code to access the document -class DocumentIndexer : public CharacterIndexer { - Document *pdoc; - int end; -public: - DocumentIndexer(Document *pdoc_, int end_) : - pdoc(pdoc_), end(end_) { - } - - virtual ~DocumentIndexer() { - } - - virtual char CharAt(int index) { - if (index < 0 || index >= end) - return 0; - else - return pdoc->CharAt(index); - } -}; - -#ifndef NO_CXX11_REGEX - -class ByteIterator : public std::iterator { -public: - const Document *doc; - Position position; - ByteIterator(const Document *doc_ = 0, Position position_ = 0) : doc(doc_), position(position_) { - } - ByteIterator(const ByteIterator &other) NOEXCEPT { - doc = other.doc; - position = other.position; - } - ByteIterator &operator=(const ByteIterator &other) { - if (this != &other) { - doc = other.doc; - position = other.position; - } - return *this; - } - char operator*() const { - return doc->CharAt(position); - } - ByteIterator &operator++() { - position++; - return *this; - } - ByteIterator operator++(int) { - ByteIterator retVal(*this); - position++; - return retVal; - } - ByteIterator &operator--() { - position--; - return *this; - } - bool operator==(const ByteIterator &other) const { - return doc == other.doc && position == other.position; - } - bool operator!=(const ByteIterator &other) const { - return doc != other.doc || position != other.position; - } - int Pos() const { - return position; - } - int PosRoundUp() const { - return position; - } -}; - -// On Windows, wchar_t is 16 bits wide and on Unix it is 32 bits wide. -// Would be better to use sizeof(wchar_t) or similar to differentiate -// but easier for now to hard-code platforms. -// C++11 has char16_t and char32_t but neither Clang nor Visual C++ -// appear to allow specializing basic_regex over these. - -#ifdef _WIN32 -#define WCHAR_T_IS_16 1 -#else -#define WCHAR_T_IS_16 0 -#endif - -#if WCHAR_T_IS_16 - -// On Windows, report non-BMP characters as 2 separate surrogates as that -// matches wregex since it is based on wchar_t. -class UTF8Iterator : public std::iterator { - // These 3 fields determine the iterator position and are used for comparisons - const Document *doc; - Position position; - size_t characterIndex; - // Remaining fields are derived from the determining fields so are excluded in comparisons - unsigned int lenBytes; - size_t lenCharacters; - wchar_t buffered[2]; -public: - UTF8Iterator(const Document *doc_ = 0, Position position_ = 0) : - doc(doc_), position(position_), characterIndex(0), lenBytes(0), lenCharacters(0) { - buffered[0] = 0; - buffered[1] = 0; - if (doc) { - ReadCharacter(); - } - } - UTF8Iterator(const UTF8Iterator &other) { - doc = other.doc; - position = other.position; - characterIndex = other.characterIndex; - lenBytes = other.lenBytes; - lenCharacters = other.lenCharacters; - buffered[0] = other.buffered[0]; - buffered[1] = other.buffered[1]; - } - UTF8Iterator &operator=(const UTF8Iterator &other) { - if (this != &other) { - doc = other.doc; - position = other.position; - characterIndex = other.characterIndex; - lenBytes = other.lenBytes; - lenCharacters = other.lenCharacters; - buffered[0] = other.buffered[0]; - buffered[1] = other.buffered[1]; - } - return *this; - } - wchar_t operator*() const { - assert(lenCharacters != 0); - return buffered[characterIndex]; - } - UTF8Iterator &operator++() { - if ((characterIndex + 1) < (lenCharacters)) { - characterIndex++; - } else { - position += lenBytes; - ReadCharacter(); - characterIndex = 0; - } - return *this; - } - UTF8Iterator operator++(int) { - UTF8Iterator retVal(*this); - if ((characterIndex + 1) < (lenCharacters)) { - characterIndex++; - } else { - position += lenBytes; - ReadCharacter(); - characterIndex = 0; - } - return retVal; - } - UTF8Iterator &operator--() { - if (characterIndex) { - characterIndex--; - } else { - position = doc->NextPosition(position, -1); - ReadCharacter(); - characterIndex = lenCharacters - 1; - } - return *this; - } - bool operator==(const UTF8Iterator &other) const { - // Only test the determining fields, not the character widths and values derived from this - return doc == other.doc && - position == other.position && - characterIndex == other.characterIndex; - } - bool operator!=(const UTF8Iterator &other) const { - // Only test the determining fields, not the character widths and values derived from this - return doc != other.doc || - position != other.position || - characterIndex != other.characterIndex; - } - int Pos() const { - return position; - } - int PosRoundUp() const { - if (characterIndex) - return position + lenBytes; // Force to end of character - else - return position; - } -private: - void ReadCharacter() { - Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); - lenBytes = charExtracted.widthBytes; - if (charExtracted.character == unicodeReplacementChar) { - lenCharacters = 1; - buffered[0] = static_cast(charExtracted.character); - } else { - lenCharacters = UTF16FromUTF32Character(charExtracted.character, buffered); - } - } -}; - -#else - -// On Unix, report non-BMP characters as single characters - -class UTF8Iterator : public std::iterator { - const Document *doc; - Position position; -public: - UTF8Iterator(const Document *doc_=0, Position position_=0) : doc(doc_), position(position_) { - } - UTF8Iterator(const UTF8Iterator &other) NOEXCEPT { - doc = other.doc; - position = other.position; - } - UTF8Iterator &operator=(const UTF8Iterator &other) { - if (this != &other) { - doc = other.doc; - position = other.position; - } - return *this; - } - wchar_t operator*() const { - Document::CharacterExtracted charExtracted = doc->ExtractCharacter(position); - return charExtracted.character; - } - UTF8Iterator &operator++() { - position = doc->NextPosition(position, 1); - return *this; - } - UTF8Iterator operator++(int) { - UTF8Iterator retVal(*this); - position = doc->NextPosition(position, 1); - return retVal; - } - UTF8Iterator &operator--() { - position = doc->NextPosition(position, -1); - return *this; - } - bool operator==(const UTF8Iterator &other) const { - return doc == other.doc && position == other.position; - } - bool operator!=(const UTF8Iterator &other) const { - return doc != other.doc || position != other.position; - } - int Pos() const { - return position; - } - int PosRoundUp() const { - return position; - } -}; - -#endif - -std::regex_constants::match_flag_type MatchFlags(const Document *doc, int startPos, int endPos) { - std::regex_constants::match_flag_type flagsMatch = std::regex_constants::match_default; - if (!doc->IsLineStartPosition(startPos)) - flagsMatch |= std::regex_constants::match_not_bol; - if (!doc->IsLineEndPosition(endPos)) - flagsMatch |= std::regex_constants::match_not_eol; - return flagsMatch; -} - -template -bool MatchOnLines(const Document *doc, const Regex ®exp, const RESearchRange &resr, RESearch &search) { - bool matched = false; - std::match_results match; - - // MSVC and libc++ have problems with ^ and $ matching line ends inside a range - // If they didn't then the line by line iteration could be removed for the forwards - // case and replaced with the following 4 lines: - // Iterator uiStart(doc, startPos); - // Iterator uiEnd(doc, endPos); - // flagsMatch = MatchFlags(doc, startPos, endPos); - // matched = std::regex_search(uiStart, uiEnd, match, regexp, flagsMatch); - - // Line by line. - for (int line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) { - const Range lineRange = resr.LineRange(line); - Iterator itStart(doc, lineRange.start); - Iterator itEnd(doc, lineRange.end); - std::regex_constants::match_flag_type flagsMatch = MatchFlags(doc, lineRange.start, lineRange.end); - matched = std::regex_search(itStart, itEnd, match, regexp, flagsMatch); - // Check for the last match on this line. - if (matched) { - if (resr.increment == -1) { - while (matched) { - Iterator itNext(doc, match[0].second.PosRoundUp()); - flagsMatch = MatchFlags(doc, itNext.Pos(), lineRange.end); - std::match_results matchNext; - matched = std::regex_search(itNext, itEnd, matchNext, regexp, flagsMatch); - if (matched) { - if (match[0].first == match[0].second) { - // Empty match means failure so exit - return false; - } - match = matchNext; - } - } - matched = true; - } - break; - } - } - if (matched) { - for (size_t co = 0; co < match.size(); co++) { - search.bopat[co] = match[co].first.Pos(); - search.eopat[co] = match[co].second.PosRoundUp(); - Sci::Position lenMatch = search.eopat[co] - search.bopat[co]; - search.pat[co].resize(lenMatch); - for (Sci::Position iPos = 0; iPos < lenMatch; iPos++) { - search.pat[co][iPos] = doc->CharAt(iPos + search.bopat[co]); - } - } - } - return matched; -} - -long Cxx11RegexFindText(Document *doc, int minPos, int maxPos, const char *s, - bool caseSensitive, int *length, RESearch &search) { - const RESearchRange resr(doc, minPos, maxPos); - try { - //ElapsedTime et; - std::regex::flag_type flagsRe = std::regex::ECMAScript; - // Flags that apper to have no effect: - // | std::regex::collate | std::regex::extended; - if (!caseSensitive) - flagsRe = flagsRe | std::regex::icase; - - // Clear the RESearch so can fill in matches - search.Clear(); - - bool matched = false; - if (SC_CP_UTF8 == doc->dbcsCodePage) { - unsigned int lenS = static_cast(strlen(s)); - std::vector ws(lenS + 1); -#if WCHAR_T_IS_16 - size_t outLen = UTF16FromUTF8(s, lenS, &ws[0], lenS); -#else - size_t outLen = UTF32FromUTF8(s, lenS, reinterpret_cast(&ws[0]), lenS); -#endif - ws[outLen] = 0; - std::wregex regexp; -#if defined(__APPLE__) - // Using a UTF-8 locale doesn't change to Unicode over a byte buffer so '.' - // is one byte not one character. - // However, on OS X this makes wregex act as Unicode - std::locale localeU("en_US.UTF-8"); - regexp.imbue(localeU); -#endif - regexp.assign(&ws[0], flagsRe); - matched = MatchOnLines(doc, regexp, resr, search); - - } else { - std::regex regexp; - regexp.assign(s, flagsRe); - matched = MatchOnLines(doc, regexp, resr, search); - } - - int posMatch = -1; - if (matched) { - posMatch = search.bopat[0]; - *length = search.eopat[0] - search.bopat[0]; - } - // Example - search in doc/ScintillaHistory.html for - // [[:upper:]]eta[[:space:]] - // On MacBook, normally around 1 second but with locale imbued -> 14 seconds. - //double durSearch = et.Duration(true); - //Platform::DebugPrintf("Search:%9.6g \n", durSearch); - return posMatch; - } catch (std::regex_error &) { - // Failed to create regular expression - throw RegexError(); - } catch (...) { - // Failed in some other way - return -1; - } -} - -#endif - -} - -long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s, - bool caseSensitive, bool, bool, int flags, - int *length) { - -#ifndef NO_CXX11_REGEX - if (flags & SCFIND_CXX11REGEX) { - return Cxx11RegexFindText(doc, minPos, maxPos, s, - caseSensitive, length, search); - } -#endif - - const RESearchRange resr(doc, minPos, maxPos); - - const bool posix = (flags & SCFIND_POSIX) != 0; - - const char *errmsg = search.Compile(s, *length, caseSensitive, posix); - if (errmsg) { - return -1; - } - // Find a variable in a property file: \$(\([A-Za-z0-9_.]+\)) - // Replace first '.' with '-' in each property file variable reference: - // Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\)) - // Replace: $(\1-\2) - int pos = -1; - int lenRet = 0; - const char searchEnd = s[*length - 1]; - const char searchEndPrev = (*length > 1) ? s[*length - 2] : '\0'; - for (int line = resr.lineRangeStart; line != resr.lineRangeBreak; line += resr.increment) { - int startOfLine = doc->LineStart(line); - int endOfLine = doc->LineEnd(line); - if (resr.increment == 1) { - if (line == resr.lineRangeStart) { - if ((resr.startPos != startOfLine) && (s[0] == '^')) - continue; // Can't match start of line if start position after start of line - startOfLine = resr.startPos; - } - if (line == resr.lineRangeEnd) { - if ((resr.endPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) - continue; // Can't match end of line if end position before end of line - endOfLine = resr.endPos; - } - } else { - if (line == resr.lineRangeEnd) { - if ((resr.endPos != startOfLine) && (s[0] == '^')) - continue; // Can't match start of line if end position after start of line - startOfLine = resr.endPos; - } - if (line == resr.lineRangeStart) { - if ((resr.startPos != endOfLine) && (searchEnd == '$') && (searchEndPrev != '\\')) - continue; // Can't match end of line if start position before end of line - endOfLine = resr.startPos; - } - } - - DocumentIndexer di(doc, endOfLine); - int success = search.Execute(di, startOfLine, endOfLine); - if (success) { - pos = search.bopat[0]; - // Ensure only whole characters selected - search.eopat[0] = doc->MovePositionOutsideChar(search.eopat[0], 1, false); - lenRet = search.eopat[0] - search.bopat[0]; - // There can be only one start of a line, so no need to look for last match in line - if ((resr.increment == -1) && (s[0] != '^')) { - // Check for the last match on this line. - int repetitions = 1000; // Break out of infinite loop - while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) { - success = search.Execute(di, pos+1, endOfLine); - if (success) { - if (search.eopat[0] <= minPos) { - pos = search.bopat[0]; - lenRet = search.eopat[0] - search.bopat[0]; - } else { - success = 0; - } - } - } - } - break; - } - } - *length = lenRet; - return pos; -} - -const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, int *length) { - substituted.clear(); - DocumentIndexer di(doc, doc->Length()); - search.GrabMatches(di); - for (int j = 0; j < *length; j++) { - if (text[j] == '\\') { - if (text[j + 1] >= '0' && text[j + 1] <= '9') { - unsigned int patNum = text[j + 1] - '0'; - unsigned int len = search.eopat[patNum] - search.bopat[patNum]; - if (!search.pat[patNum].empty()) // Will be null if try for a match that did not occur - substituted.append(search.pat[patNum].c_str(), len); - j++; - } else { - j++; - switch (text[j]) { - case 'a': - substituted.push_back('\a'); - break; - case 'b': - substituted.push_back('\b'); - break; - case 'f': - substituted.push_back('\f'); - break; - case 'n': - substituted.push_back('\n'); - break; - case 'r': - substituted.push_back('\r'); - break; - case 't': - substituted.push_back('\t'); - break; - case 'v': - substituted.push_back('\v'); - break; - case '\\': - substituted.push_back('\\'); - break; - default: - substituted.push_back('\\'); - j--; - } - } - } else { - substituted.push_back(text[j]); - } - } - *length = static_cast(substituted.length()); - return substituted.c_str(); -} - -#ifndef SCI_OWNREGEX - -#ifdef SCI_NAMESPACE - -RegexSearchBase *Scintilla::CreateRegexSearch(CharClassify *charClassTable) { - return new BuiltinRegex(charClassTable); -} - -#else - -RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable) { - return new BuiltinRegex(charClassTable); -} - -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Document.h b/qrenderdoc/3rdparty/scintilla/src/Document.h deleted file mode 100644 index c0a0bb808..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Document.h +++ /dev/null @@ -1,551 +0,0 @@ -// Scintilla source code edit control -/** @file Document.h - ** Text document that handles notifications, DBCS, styling, words and end of line. - **/ -// Copyright 1998-2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef DOCUMENT_H -#define DOCUMENT_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - * A Position is a position within a document between two characters or at the beginning or end. - * Sometimes used as a character index where it identifies the character after the position. - */ -typedef int Position; -const Position invalidPosition = -1; - -enum EncodingFamily { efEightBit, efUnicode, efDBCS }; - -/** - * The range class represents a range of text in a document. - * The two values are not sorted as one end may be more significant than the other - * as is the case for the selection where the end position is the position of the caret. - * If either position is invalidPosition then the range is invalid and most operations will fail. - */ -class Range { -public: - Position start; - Position end; - - explicit Range(Position pos=0) : - start(pos), end(pos) { - } - Range(Position start_, Position end_) : - start(start_), end(end_) { - } - - bool operator==(const Range &other) const { - return (start == other.start) && (end == other.end); - } - - bool Valid() const { - return (start != invalidPosition) && (end != invalidPosition); - } - - Position First() const { - return (start <= end) ? start : end; - } - - Position Last() const { - return (start > end) ? start : end; - } - - // Is the position within the range? - bool Contains(Position pos) const { - if (start < end) { - return (pos >= start && pos <= end); - } else { - return (pos <= start && pos >= end); - } - } - - // Is the character after pos within the range? - bool ContainsCharacter(Position pos) const { - if (start < end) { - return (pos >= start && pos < end); - } else { - return (pos < start && pos >= end); - } - } - - bool Contains(Range other) const { - return Contains(other.start) && Contains(other.end); - } - - bool Overlaps(Range other) const { - return - Contains(other.start) || - Contains(other.end) || - other.Contains(start) || - other.Contains(end); - } -}; - -class DocWatcher; -class DocModification; -class Document; - -/** - * Interface class for regular expression searching - */ -class RegexSearchBase { -public: - virtual ~RegexSearchBase() {} - - virtual long FindText(Document *doc, int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0; - - ///@return String with the substitutions, must remain valid until the next call or destruction - virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length) = 0; -}; - -/// Factory function for RegexSearchBase -extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable); - -struct StyledText { - size_t length; - const char *text; - bool multipleStyles; - size_t style; - const unsigned char *styles; - StyledText(size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) : - length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) { - } - // Return number of bytes from start to before '\n' or end of text. - // Return 1 when start is outside text - size_t LineLength(size_t start) const { - size_t cur = start; - while ((cur < length) && (text[cur] != '\n')) - cur++; - return cur-start; - } - size_t StyleAt(size_t i) const { - return multipleStyles ? styles[i] : style; - } -}; - -class HighlightDelimiter { -public: - HighlightDelimiter() : isEnabled(false) { - Clear(); - } - - void Clear() { - beginFoldBlock = -1; - endFoldBlock = -1; - firstChangeableLineBefore = -1; - firstChangeableLineAfter = -1; - } - - bool NeedsDrawing(int line) const { - return isEnabled && (line <= firstChangeableLineBefore || line >= firstChangeableLineAfter); - } - - bool IsFoldBlockHighlighted(int line) const { - return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock; - } - - bool IsHeadOfFoldBlock(int line) const { - return beginFoldBlock == line && line < endFoldBlock; - } - - bool IsBodyOfFoldBlock(int line) const { - return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock; - } - - bool IsTailOfFoldBlock(int line) const { - return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock; - } - - int beginFoldBlock; // Begin of current fold block - int endFoldBlock; // End of current fold block - int firstChangeableLineBefore; // First line that triggers repaint before starting line that determined current fold block - int firstChangeableLineAfter; // First line that triggers repaint after starting line that determined current fold block - bool isEnabled; -}; - -class Document; - -inline int LevelNumber(int level) { - return level & SC_FOLDLEVELNUMBERMASK; -} - -class LexInterface { -protected: - Document *pdoc; - ILexer *instance; - bool performingStyle; ///< Prevent reentrance -public: - explicit LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) { - } - virtual ~LexInterface() { - } - void Colourise(int start, int end); - int LineEndTypesSupported(); - bool UseContainerLexing() const { - return instance == 0; - } -}; - -struct RegexError : public std::runtime_error { - RegexError() : std::runtime_error("regex failure") {} -}; - -/** - */ -class Document : PerLine, public IDocumentWithLineEnd, public ILoader { - -public: - /** Used to pair watcher pointer with user data. */ - struct WatcherWithUserData { - DocWatcher *watcher; - void *userData; - WatcherWithUserData(DocWatcher *watcher_=0, void *userData_=0) : - watcher(watcher_), userData(userData_) { - } - bool operator==(const WatcherWithUserData &other) const { - return (watcher == other.watcher) && (userData == other.userData); - } - }; - -private: - int refCount; - CellBuffer cb; - CharClassify charClass; - CaseFolder *pcf; - int endStyled; - int styleClock; - int enteredModification; - int enteredStyling; - int enteredReadOnlyCount; - - bool insertionSet; - std::string insertion; - - std::vector watchers; - - // ldSize is not real data - it is for dimensions and loops - enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize }; - PerLine *perLineData[ldSize]; - - bool matchesValid; - RegexSearchBase *regex; - -public: - - struct CharacterExtracted { - unsigned int character; - unsigned int widthBytes; - CharacterExtracted(unsigned int character_, unsigned int widthBytes_) : - character(character_), widthBytes(widthBytes_) { - } - // For DBCS characters turn 2 bytes into an int - static CharacterExtracted DBCS(unsigned char lead, unsigned char trail) { - return CharacterExtracted((lead << 8) | trail, 2); - } - }; - - LexInterface *pli; - - int eolMode; - /// Can also be SC_CP_UTF8 to enable UTF-8 mode - int dbcsCodePage; - int lineEndBitSet; - int tabInChars; - int indentInChars; - int actualIndentInChars; - bool useTabs; - bool tabIndents; - bool backspaceUnindents; - double durationStyleOneLine; - - DecorationList decorations; - - Document(); - virtual ~Document(); - - int AddRef(); - int SCI_METHOD Release(); - - virtual void Init(); - int LineEndTypesSupported() const; - bool SetDBCSCodePage(int dbcsCodePage_); - int GetLineEndTypesAllowed() const { return cb.GetLineEndTypes(); } - bool SetLineEndTypesAllowed(int lineEndBitSet_); - int GetLineEndTypesActive() const { return cb.GetLineEndTypes(); } - virtual void InsertLine(int line); - virtual void RemoveLine(int line); - - int SCI_METHOD Version() const { - return dvLineEnd; - } - - void SCI_METHOD SetErrorStatus(int status); - - Sci_Position SCI_METHOD LineFromPosition(Sci_Position pos) const; - int ClampPositionIntoDocument(int pos) const; - bool ContainsLineEnd(const char *s, int length) const { return cb.ContainsLineEnd(s, length); } - bool IsCrLf(int pos) const; - int LenChar(int pos); - bool InGoodUTF8(int pos, int &start, int &end) const; - int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const; - int NextPosition(int pos, int moveDir) const; - bool NextCharacter(int &pos, int moveDir) const; // Returns true if pos changed - Document::CharacterExtracted CharacterAfter(int position) const; - Document::CharacterExtracted CharacterBefore(int position) const; - Sci_Position SCI_METHOD GetRelativePosition(Sci_Position positionStart, Sci_Position characterOffset) const; - int GetRelativePositionUTF16(int positionStart, int characterOffset) const; - int SCI_METHOD GetCharacterAndWidth(Sci_Position position, Sci_Position *pWidth) const; - int SCI_METHOD CodePage() const; - bool SCI_METHOD IsDBCSLeadByte(char ch) const; - int SafeSegment(const char *text, int length, int lengthSegment) const; - EncodingFamily CodePageFamily() const; - - // Gateways to modifying document - void ModifiedAt(int pos); - void CheckReadOnly(); - bool DeleteChars(int pos, int len); - int InsertString(int position, const char *s, int insertLength); - void ChangeInsertion(const char *s, int length); - int SCI_METHOD AddData(char *data, Sci_Position length); - void * SCI_METHOD ConvertToDocument(); - int Undo(); - int Redo(); - bool CanUndo() const { return cb.CanUndo(); } - bool CanRedo() const { return cb.CanRedo(); } - void DeleteUndoHistory() { cb.DeleteUndoHistory(); } - bool SetUndoCollection(bool collectUndo) { - return cb.SetUndoCollection(collectUndo); - } - bool IsCollectingUndo() const { return cb.IsCollectingUndo(); } - void BeginUndoAction() { cb.BeginUndoAction(); } - void EndUndoAction() { cb.EndUndoAction(); } - void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); } - void SetSavePoint(); - bool IsSavePoint() const { return cb.IsSavePoint(); } - - void TentativeStart() { cb.TentativeStart(); } - void TentativeCommit() { cb.TentativeCommit(); } - void TentativeUndo(); - bool TentativeActive() const { return cb.TentativeActive(); } - - const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); } - const char *RangePointer(int position, int rangeLength) { return cb.RangePointer(position, rangeLength); } - int GapPosition() const { return cb.GapPosition(); } - - int SCI_METHOD GetLineIndentation(Sci_Position line); - int SetLineIndentation(int line, int indent); - int GetLineIndentPosition(int line) const; - int GetColumn(int position); - int CountCharacters(int startPos, int endPos) const; - int CountUTF16(int startPos, int endPos) const; - int FindColumn(int line, int column); - void Indent(bool forwards, int lineBottom, int lineTop); - static std::string TransformLineEnds(const char *s, size_t len, int eolModeWanted); - void ConvertLineEnds(int eolModeSet); - void SetReadOnly(bool set) { cb.SetReadOnly(set); } - bool IsReadOnly() const { return cb.IsReadOnly(); } - - void DelChar(int pos); - void DelCharBack(int pos); - - char CharAt(int position) const { return cb.CharAt(position); } - void SCI_METHOD GetCharRange(char *buffer, Sci_Position position, Sci_Position lengthRetrieve) const { - cb.GetCharRange(buffer, position, lengthRetrieve); - } - char SCI_METHOD StyleAt(Sci_Position position) const { return cb.StyleAt(position); } - int StyleIndexAt(Sci_Position position) const { return static_cast(cb.StyleAt(position)); } - void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const { - cb.GetStyleRange(buffer, position, lengthRetrieve); - } - int GetMark(int line); - int MarkerNext(int lineStart, int mask) const; - int AddMark(int line, int markerNum); - void AddMarkSet(int line, int valueSet); - void DeleteMark(int line, int markerNum); - void DeleteMarkFromHandle(int markerHandle); - void DeleteAllMarks(int markerNum); - int LineFromHandle(int markerHandle); - Sci_Position SCI_METHOD LineStart(Sci_Position line) const; - bool IsLineStartPosition(int position) const; - Sci_Position SCI_METHOD LineEnd(Sci_Position line) const; - int LineEndPosition(int position) const; - bool IsLineEndPosition(int position) const; - bool IsPositionInLineEnd(int position) const; - int VCHomePosition(int position) const; - - int SCI_METHOD SetLevel(Sci_Position line, int level); - int SCI_METHOD GetLevel(Sci_Position line) const; - void ClearLevels(); - int GetLastChild(int lineParent, int level=-1, int lastLine=-1); - int GetFoldParent(int line) const; - void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int lastLine); - - void Indent(bool forwards); - int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false) const; - int NextWordStart(int pos, int delta) const; - int NextWordEnd(int pos, int delta) const; - Sci_Position SCI_METHOD Length() const { return cb.Length(); } - void Allocate(int newSize) { cb.Allocate(newSize); } - - CharacterExtracted ExtractCharacter(int position) const; - - bool IsWordStartAt(int pos) const; - bool IsWordEndAt(int pos) const; - bool IsWordAt(int start, int end) const; - - bool MatchesWordOptions(bool word, bool wordStart, int pos, int length) const; - bool HasCaseFolder(void) const; - void SetCaseFolder(CaseFolder *pcf_); - long FindText(int minPos, int maxPos, const char *search, int flags, int *length); - const char *SubstituteByPosition(const char *text, int *length); - int LinesTotal() const; - - void SetDefaultCharClasses(bool includeWordClass); - void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass); - int GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) const; - void SCI_METHOD StartStyling(Sci_Position position, char mask); - bool SCI_METHOD SetStyleFor(Sci_Position length, char style); - bool SCI_METHOD SetStyles(Sci_Position length, const char *styles); - int GetEndStyled() const { return endStyled; } - void EnsureStyledTo(int pos); - void StyleToAdjustingLineDuration(int pos); - void LexerChanged(); - int GetStyleClock() const { return styleClock; } - void IncrementStyleClock(); - void SCI_METHOD DecorationSetCurrentIndicator(int indicator) { - decorations.SetCurrentIndicator(indicator); - } - void SCI_METHOD DecorationFillRange(Sci_Position position, int value, Sci_Position fillLength); - - int SCI_METHOD SetLineState(Sci_Position line, int state); - int SCI_METHOD GetLineState(Sci_Position line) const; - int GetMaxLineState(); - void SCI_METHOD ChangeLexerState(Sci_Position start, Sci_Position end); - - StyledText MarginStyledText(int line) const; - void MarginSetStyle(int line, int style); - void MarginSetStyles(int line, const unsigned char *styles); - void MarginSetText(int line, const char *text); - void MarginClearAll(); - - StyledText AnnotationStyledText(int line) const; - void AnnotationSetText(int line, const char *text); - void AnnotationSetStyle(int line, int style); - void AnnotationSetStyles(int line, const unsigned char *styles); - int AnnotationLines(int line) const; - void AnnotationClearAll(); - - bool AddWatcher(DocWatcher *watcher, void *userData); - bool RemoveWatcher(DocWatcher *watcher, void *userData); - - bool IsASCIIWordByte(unsigned char ch) const; - CharClassify::cc WordCharacterClass(unsigned int ch) const; - bool IsWordPartSeparator(unsigned int ch) const; - int WordPartLeft(int pos) const; - int WordPartRight(int pos) const; - int ExtendStyleRange(int pos, int delta, bool singleLine = false); - bool IsWhiteLine(int line) const; - int ParaUp(int pos) const; - int ParaDown(int pos) const; - int IndentSize() const { return actualIndentInChars; } - int BraceMatch(int position, int maxReStyle); - -private: - void NotifyModifyAttempt(); - void NotifySavePoint(bool atSavePoint); - void NotifyModified(DocModification mh); -}; - -class UndoGroup { - Document *pdoc; - bool groupNeeded; -public: - UndoGroup(Document *pdoc_, bool groupNeeded_=true) : - pdoc(pdoc_), groupNeeded(groupNeeded_) { - if (groupNeeded) { - pdoc->BeginUndoAction(); - } - } - ~UndoGroup() { - if (groupNeeded) { - pdoc->EndUndoAction(); - } - } - bool Needed() const { - return groupNeeded; - } -}; - - -/** - * To optimise processing of document modifications by DocWatchers, a hint is passed indicating the - * scope of the change. - * If the DocWatcher is a document view then this can be used to optimise screen updating. - */ -class DocModification { -public: - int modificationType; - int position; - int length; - int linesAdded; /**< Negative if lines deleted. */ - const char *text; /**< Only valid for changes to text, not for changes to style. */ - int line; - int foldLevelNow; - int foldLevelPrev; - int annotationLinesAdded; - int token; - - DocModification(int modificationType_, int position_=0, int length_=0, - int linesAdded_=0, const char *text_=0, int line_=0) : - modificationType(modificationType_), - position(position_), - length(length_), - linesAdded(linesAdded_), - text(text_), - line(line_), - foldLevelNow(0), - foldLevelPrev(0), - annotationLinesAdded(0), - token(0) {} - - DocModification(int modificationType_, const Action &act, int linesAdded_=0) : - modificationType(modificationType_), - position(act.position), - length(act.lenData), - linesAdded(linesAdded_), - text(act.data), - line(0), - foldLevelNow(0), - foldLevelPrev(0), - annotationLinesAdded(0), - token(0) {} -}; - -/** - * A class that wants to receive notifications from a Document must be derived from DocWatcher - * and implement the notification methods. It can then be added to the watcher list with AddWatcher. - */ -class DocWatcher { -public: - virtual ~DocWatcher() {} - - virtual void NotifyModifyAttempt(Document *doc, void *userData) = 0; - virtual void NotifySavePoint(Document *doc, void *userData, bool atSavePoint) = 0; - virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0; - virtual void NotifyDeleted(Document *doc, void *userData) = 0; - virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0; - virtual void NotifyLexerChanged(Document *doc, void *userData) = 0; - virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/EditModel.cxx b/qrenderdoc/3rdparty/scintilla/src/EditModel.cxx deleted file mode 100644 index 0f64e07f9..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/EditModel.cxx +++ /dev/null @@ -1,79 +0,0 @@ -// Scintilla source code edit control -/** @file EditModel.cxx - ** Defines the editor state that must be visible to EditorView. - **/ -// Copyright 1998-2014 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "StringCopy.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "UniConversion.h" -#include "Selection.h" -#include "PositionCache.h" -#include "EditModel.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -Caret::Caret() : - active(false), on(false), period(500) {} - -EditModel::EditModel() { - inOverstrike = false; - xOffset = 0; - trackLineWidth = false; - posDrag = SelectionPosition(invalidPosition); - braces[0] = invalidPosition; - braces[1] = invalidPosition; - bracesMatchStyle = STYLE_BRACEBAD; - highlightGuideColumn = 0; - primarySelection = true; - imeInteraction = imeWindowed; - foldFlags = 0; - foldDisplayTextStyle = SC_FOLDDISPLAYTEXT_HIDDEN; - hotspot = Range(invalidPosition); - hoverIndicatorPos = invalidPosition; - wrapWidth = LineLayout::wrapWidthInfinite; - pdoc = new Document(); - pdoc->AddRef(); -} - -EditModel::~EditModel() { - pdoc->Release(); - pdoc = 0; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/EditModel.h b/qrenderdoc/3rdparty/scintilla/src/EditModel.h deleted file mode 100644 index 847fd728d..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/EditModel.h +++ /dev/null @@ -1,71 +0,0 @@ -// Scintilla source code edit control -/** @file EditModel.h - ** Defines the editor state that must be visible to EditorView. - **/ -// Copyright 1998-2014 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef EDITMODEL_H -#define EDITMODEL_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** -*/ -class Caret { -public: - bool active; - bool on; - int period; - - Caret(); -}; - -class EditModel { - // Private so EditModel objects can not be copied - explicit EditModel(const EditModel &); - EditModel &operator=(const EditModel &); - -public: - bool inOverstrike; - int xOffset; ///< Horizontal scrolled amount in pixels - bool trackLineWidth; - - SpecialRepresentations reprs; - Caret caret; - SelectionPosition posDrag; - Position braces[2]; - int bracesMatchStyle; - int highlightGuideColumn; - Selection sel; - bool primarySelection; - - enum IMEInteraction { imeWindowed, imeInline } imeInteraction; - - int foldFlags; - int foldDisplayTextStyle; - ContractionState cs; - // Hotspot support - Range hotspot; - int hoverIndicatorPos; - - // Wrapping support - int wrapWidth; - - Document *pdoc; - - EditModel(); - virtual ~EditModel(); - virtual int TopLineOfMain() const = 0; - virtual Point GetVisibleOriginInMain() const = 0; - virtual int LinesOnScreen() const = 0; - virtual Range GetHotSpotRange() const = 0; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/EditView.cxx b/qrenderdoc/3rdparty/scintilla/src/EditView.cxx deleted file mode 100644 index 5c622568b..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/EditView.cxx +++ /dev/null @@ -1,2311 +0,0 @@ -// Scintilla source code edit control -/** @file EditView.cxx - ** Defines the appearance of the main text area of the editor window. - **/ -// Copyright 1998-2014 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "StringCopy.h" -#include "CharacterSet.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "PerLine.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "UniConversion.h" -#include "Selection.h" -#include "PositionCache.h" -#include "EditModel.h" -#include "MarginView.h" -#include "EditView.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static inline bool IsControlCharacter(int ch) { - // iscntrl returns true for lots of chars > 127 which are displayable - return ch >= 0 && ch < ' '; -} - -PrintParameters::PrintParameters() { - magnification = 0; - colourMode = SC_PRINT_NORMAL; - wrapState = eWrapWord; -} - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st) { - if (st.multipleStyles) { - for (size_t iStyle = 0; iStyle(styles[endSegment + 1]) == style)) - endSegment++; - FontAlias fontText = vs.styles[style + styleOffset].font; - width += static_cast(surface->WidthText(fontText, text + start, - static_cast(endSegment - start + 1))); - start = endSegment + 1; - } - return width; -} - -int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, const StyledText &st) { - int widthMax = 0; - size_t start = 0; - while (start < st.length) { - size_t lenLine = st.LineLength(start); - int widthSubLine; - if (st.multipleStyles) { - widthSubLine = WidthStyledText(surface, vs, styleOffset, st.text + start, st.styles + start, lenLine); - } else { - FontAlias fontText = vs.styles[styleOffset + st.style].font; - widthSubLine = static_cast(surface->WidthText(fontText, - st.text + start, static_cast(lenLine))); - } - if (widthSubLine > widthMax) - widthMax = widthSubLine; - start += lenLine + 1; - } - return widthMax; -} - -void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase, - const char *s, int len, DrawPhase phase) { - FontAlias fontText = style.font; - if (phase & drawBack) { - if (phase & drawText) { - // Drawing both - surface->DrawTextNoClip(rc, fontText, ybase, s, len, - style.fore, style.back); - } else { - surface->FillRectangle(rc, style.back); - } - } else if (phase & drawText) { - surface->DrawTextTransparent(rc, fontText, ybase, s, len, style.fore); - } -} - -void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRectangle rcText, - const StyledText &st, size_t start, size_t length, DrawPhase phase) { - - if (st.multipleStyles) { - int x = static_cast(rcText.left); - size_t i = 0; - while (i < length) { - size_t end = i; - size_t style = st.styles[i + start]; - while (end < length - 1 && st.styles[start + end + 1] == style) - end++; - style += styleOffset; - FontAlias fontText = vs.styles[style].font; - const int width = static_cast(surface->WidthText(fontText, - st.text + start + i, static_cast(end - i + 1))); - PRectangle rcSegment = rcText; - rcSegment.left = static_cast(x); - rcSegment.right = static_cast(x + width + 1); - DrawTextNoClipPhase(surface, rcSegment, vs.styles[style], - rcText.top + vs.maxAscent, st.text + start + i, - static_cast(end - i + 1), phase); - x += width; - i = end + 1; - } - } else { - const size_t style = st.style + styleOffset; - DrawTextNoClipPhase(surface, rcText, vs.styles[style], - rcText.top + vs.maxAscent, st.text + start, - static_cast(length), phase); - } -} - -#ifdef SCI_NAMESPACE -} -#endif - -const XYPOSITION epsilon = 0.0001f; // A small nudge to avoid floating point precision issues - -EditView::EditView() { - ldTabstops = NULL; - tabWidthMinimumPixels = 2; // needed for calculating tab stops for fractional proportional fonts - hideSelection = false; - drawOverstrikeCaret = true; - bufferedDraw = true; - phasesDraw = phasesTwo; - lineWidthMaxSeen = 0; - additionalCaretsBlink = true; - additionalCaretsVisible = true; - imeCaretBlockOverride = false; - pixmapLine = 0; - pixmapIndentGuide = 0; - pixmapIndentGuideHighlight = 0; - llc.SetLevel(LineLayoutCache::llcCaret); - posCache.SetSize(0x400); - tabArrowHeight = 4; - customDrawTabArrow = NULL; - customDrawWrapMarker = NULL; -} - -EditView::~EditView() { - delete ldTabstops; - ldTabstops = NULL; -} - -bool EditView::SetTwoPhaseDraw(bool twoPhaseDraw) { - const PhasesDraw phasesDrawNew = twoPhaseDraw ? phasesTwo : phasesOne; - const bool redraw = phasesDraw != phasesDrawNew; - phasesDraw = phasesDrawNew; - return redraw; -} - -bool EditView::SetPhasesDraw(int phases) { - const PhasesDraw phasesDrawNew = static_cast(phases); - const bool redraw = phasesDraw != phasesDrawNew; - phasesDraw = phasesDrawNew; - return redraw; -} - -bool EditView::LinesOverlap() const { - return phasesDraw == phasesMultiple; -} - -void EditView::ClearAllTabstops() { - delete ldTabstops; - ldTabstops = 0; -} - -XYPOSITION EditView::NextTabstopPos(int line, XYPOSITION x, XYPOSITION tabWidth) const { - int next = GetNextTabstop(line, static_cast(x + tabWidthMinimumPixels)); - if (next > 0) - return static_cast(next); - return (static_cast((x + tabWidthMinimumPixels) / tabWidth) + 1) * tabWidth; -} - -bool EditView::ClearTabstops(int line) { - LineTabstops *lt = static_cast(ldTabstops); - return lt && lt->ClearTabstops(line); -} - -bool EditView::AddTabstop(int line, int x) { - if (!ldTabstops) { - ldTabstops = new LineTabstops(); - } - LineTabstops *lt = static_cast(ldTabstops); - return lt && lt->AddTabstop(line, x); -} - -int EditView::GetNextTabstop(int line, int x) const { - LineTabstops *lt = static_cast(ldTabstops); - if (lt) { - return lt->GetNextTabstop(line, x); - } else { - return 0; - } -} - -void EditView::LinesAddedOrRemoved(int lineOfPos, int linesAdded) { - if (ldTabstops) { - if (linesAdded > 0) { - for (int line = lineOfPos; line < lineOfPos + linesAdded; line++) { - ldTabstops->InsertLine(line); - } - } else { - for (int line = (lineOfPos + -linesAdded) - 1; line >= lineOfPos; line--) { - ldTabstops->RemoveLine(line); - } - } - } -} - -void EditView::DropGraphics(bool freeObjects) { - if (freeObjects) { - delete pixmapLine; - pixmapLine = 0; - delete pixmapIndentGuide; - pixmapIndentGuide = 0; - delete pixmapIndentGuideHighlight; - pixmapIndentGuideHighlight = 0; - } else { - if (pixmapLine) - pixmapLine->Release(); - if (pixmapIndentGuide) - pixmapIndentGuide->Release(); - if (pixmapIndentGuideHighlight) - pixmapIndentGuideHighlight->Release(); - } -} - -void EditView::AllocateGraphics(const ViewStyle &vsDraw) { - if (!pixmapLine) - pixmapLine = Surface::Allocate(vsDraw.technology); - if (!pixmapIndentGuide) - pixmapIndentGuide = Surface::Allocate(vsDraw.technology); - if (!pixmapIndentGuideHighlight) - pixmapIndentGuideHighlight = Surface::Allocate(vsDraw.technology); -} - -static const char *ControlCharacterString(unsigned char ch) { - const char *reps[] = { - "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", - "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", - "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", - "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" - }; - if (ch < ELEMENTS(reps)) { - return reps[ch]; - } else { - return "BAD"; - } -} - -static void DrawTabArrow(Surface *surface, PRectangle rcTab, int ymid, const ViewStyle &vsDraw) { - if ((rcTab.left + 2) < (rcTab.right - 1)) - surface->MoveTo(static_cast(rcTab.left) + 2, ymid); - else - surface->MoveTo(static_cast(rcTab.right) - 1, ymid); - surface->LineTo(static_cast(rcTab.right) - 1, ymid); - - // Draw the arrow head if needed - if (vsDraw.tabDrawMode == tdLongArrow) { - int ydiff = static_cast(rcTab.bottom - rcTab.top) / 2; - int xhead = static_cast(rcTab.right) - 1 - ydiff; - if (xhead <= rcTab.left) { - ydiff -= static_cast(rcTab.left) - xhead - 1; - xhead = static_cast(rcTab.left) - 1; - } - surface->LineTo(xhead, ymid - ydiff); - surface->MoveTo(static_cast(rcTab.right) - 1, ymid); - surface->LineTo(xhead, ymid + ydiff); - } -} - -void EditView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw) { - if (!pixmapIndentGuide->Initialised()) { - // 1 extra pixel in height so can handle odd/even positions and so produce a continuous line - pixmapIndentGuide->InitPixMap(1, vsDraw.lineHeight + 1, surfaceWindow, wid); - pixmapIndentGuideHighlight->InitPixMap(1, vsDraw.lineHeight + 1, surfaceWindow, wid); - PRectangle rcIG = PRectangle::FromInts(0, 0, 1, vsDraw.lineHeight); - pixmapIndentGuide->FillRectangle(rcIG, vsDraw.styles[STYLE_INDENTGUIDE].back); - pixmapIndentGuide->PenColour(vsDraw.styles[STYLE_INDENTGUIDE].fore); - pixmapIndentGuideHighlight->FillRectangle(rcIG, vsDraw.styles[STYLE_BRACELIGHT].back); - pixmapIndentGuideHighlight->PenColour(vsDraw.styles[STYLE_BRACELIGHT].fore); - for (int stripe = 1; stripe < vsDraw.lineHeight + 1; stripe += 2) { - PRectangle rcPixel = PRectangle::FromInts(0, stripe, 1, stripe + 1); - pixmapIndentGuide->FillRectangle(rcPixel, vsDraw.styles[STYLE_INDENTGUIDE].fore); - pixmapIndentGuideHighlight->FillRectangle(rcPixel, vsDraw.styles[STYLE_BRACELIGHT].fore); - } - } -} - -LineLayout *EditView::RetrieveLineLayout(int lineNumber, const EditModel &model) { - int posLineStart = model.pdoc->LineStart(lineNumber); - int posLineEnd = model.pdoc->LineStart(lineNumber + 1); - PLATFORM_ASSERT(posLineEnd >= posLineStart); - int lineCaret = model.pdoc->LineFromPosition(model.sel.MainCaret()); - return llc.Retrieve(lineNumber, lineCaret, - posLineEnd - posLineStart, model.pdoc->GetStyleClock(), - model.LinesOnScreen() + 1, model.pdoc->LinesTotal()); -} - -/** -* Fill in the LineLayout data for the given line. -* Copy the given @a line and its styles from the document into local arrays. -* Also determine the x position at which each character starts. -*/ -void EditView::LayoutLine(const EditModel &model, int line, Surface *surface, const ViewStyle &vstyle, LineLayout *ll, int width) { - if (!ll) - return; - - PLATFORM_ASSERT(line < model.pdoc->LinesTotal()); - PLATFORM_ASSERT(ll->chars != NULL); - int posLineStart = model.pdoc->LineStart(line); - int posLineEnd = model.pdoc->LineStart(line + 1); - // If the line is very long, limit the treatment to a length that should fit in the viewport - if (posLineEnd >(posLineStart + ll->maxLineLength)) { - posLineEnd = posLineStart + ll->maxLineLength; - } - if (ll->validity == LineLayout::llCheckTextAndStyle) { - int lineLength = posLineEnd - posLineStart; - if (!vstyle.viewEOL) { - lineLength = model.pdoc->LineEnd(line) - posLineStart; - } - if (lineLength == ll->numCharsInLine) { - // See if chars, styles, indicators, are all the same - bool allSame = true; - // Check base line layout - int styleByte = 0; - int numCharsInLine = 0; - while (numCharsInLine < lineLength) { - int charInDoc = numCharsInLine + posLineStart; - char chDoc = model.pdoc->CharAt(charInDoc); - styleByte = model.pdoc->StyleIndexAt(charInDoc); - allSame = allSame && - (ll->styles[numCharsInLine] == styleByte); - if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseMixed) - allSame = allSame && - (ll->chars[numCharsInLine] == chDoc); - else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower) - allSame = allSame && - (ll->chars[numCharsInLine] == MakeLowerCase(chDoc)); - else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper) - allSame = allSame && - (ll->chars[numCharsInLine] == MakeUpperCase(chDoc)); - else { // Style::caseCamel - if ((model.pdoc->IsASCIIWordByte(ll->chars[numCharsInLine])) && - ((numCharsInLine == 0) || (!model.pdoc->IsASCIIWordByte(ll->chars[numCharsInLine - 1])))) { - allSame = allSame && (ll->chars[numCharsInLine] == MakeUpperCase(chDoc)); - } else { - allSame = allSame && (ll->chars[numCharsInLine] == MakeLowerCase(chDoc)); - } - } - numCharsInLine++; - } - allSame = allSame && (ll->styles[numCharsInLine] == styleByte); // For eolFilled - if (allSame) { - ll->validity = LineLayout::llPositions; - } else { - ll->validity = LineLayout::llInvalid; - } - } else { - ll->validity = LineLayout::llInvalid; - } - } - if (ll->validity == LineLayout::llInvalid) { - ll->widthLine = LineLayout::wrapWidthInfinite; - ll->lines = 1; - if (vstyle.edgeState == EDGE_BACKGROUND) { - ll->edgeColumn = model.pdoc->FindColumn(line, vstyle.theEdge.column); - if (ll->edgeColumn >= posLineStart) { - ll->edgeColumn -= posLineStart; - } - } else { - ll->edgeColumn = -1; - } - - // Fill base line layout - const int lineLength = posLineEnd - posLineStart; - model.pdoc->GetCharRange(ll->chars, posLineStart, lineLength); - model.pdoc->GetStyleRange(ll->styles, posLineStart, lineLength); - int numCharsBeforeEOL = model.pdoc->LineEnd(line) - posLineStart; - const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL; - for (int styleInLine = 0; styleInLine < numCharsInLine; styleInLine++) { - const unsigned char styleByte = ll->styles[styleInLine]; - ll->styles[styleInLine] = styleByte; - } - const unsigned char styleByteLast = (lineLength > 0) ? ll->styles[lineLength - 1] : 0; - if (vstyle.someStylesForceCase) { - for (int charInLine = 0; charInLinechars[charInLine]; - if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper) - ll->chars[charInLine] = static_cast(MakeUpperCase(chDoc)); - else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower) - ll->chars[charInLine] = static_cast(MakeLowerCase(chDoc)); - else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseCamel) { - if ((model.pdoc->IsASCIIWordByte(ll->chars[charInLine])) && - ((charInLine == 0) || (!model.pdoc->IsASCIIWordByte(ll->chars[charInLine - 1])))) { - ll->chars[charInLine] = static_cast(MakeUpperCase(chDoc)); - } else { - ll->chars[charInLine] = static_cast(MakeLowerCase(chDoc)); - } - } - } - } - ll->xHighlightGuide = 0; - // Extra element at the end of the line to hold end x position and act as - ll->chars[numCharsInLine] = 0; // Also triggers processing in the loops as this is a control character - ll->styles[numCharsInLine] = styleByteLast; // For eolFilled - - // Layout the line, determining the position of each character, - // with an extra element at the end for the end of the line. - ll->positions[0] = 0; - bool lastSegItalics = false; - - BreakFinder bfLayout(ll, NULL, Range(0, numCharsInLine), posLineStart, 0, false, model.pdoc, &model.reprs, NULL); - while (bfLayout.More()) { - - const TextSegment ts = bfLayout.Next(); - - std::fill(&ll->positions[ts.start + 1], &ll->positions[ts.end() + 1], 0.0f); - if (vstyle.styles[ll->styles[ts.start]].visible) { - if (ts.representation) { - XYPOSITION representationWidth = vstyle.controlCharWidth; - if (ll->chars[ts.start] == '\t') { - // Tab is a special case of representation, taking a variable amount of space - const XYPOSITION x = ll->positions[ts.start]; - representationWidth = NextTabstopPos(line, x, vstyle.tabWidth) - ll->positions[ts.start]; - } else { - if (representationWidth <= 0.0) { - XYPOSITION positionsRepr[256]; // Should expand when needed - posCache.MeasureWidths(surface, vstyle, STYLE_CONTROLCHAR, ts.representation->stringRep.c_str(), - static_cast(ts.representation->stringRep.length()), positionsRepr, model.pdoc); - representationWidth = positionsRepr[ts.representation->stringRep.length() - 1] + vstyle.ctrlCharPadding; - } - } - for (int ii = 0; ii < ts.length; ii++) - ll->positions[ts.start + 1 + ii] = representationWidth; - } else { - if ((ts.length == 1) && (' ' == ll->chars[ts.start])) { - // Over half the segments are single characters and of these about half are space characters. - ll->positions[ts.start + 1] = vstyle.styles[ll->styles[ts.start]].spaceWidth; - } else { - posCache.MeasureWidths(surface, vstyle, ll->styles[ts.start], ll->chars + ts.start, - ts.length, ll->positions + ts.start + 1, model.pdoc); - } - } - lastSegItalics = (!ts.representation) && ((ll->chars[ts.end() - 1] != ' ') && vstyle.styles[ll->styles[ts.start]].italic); - } - - for (int posToIncrease = ts.start + 1; posToIncrease <= ts.end(); posToIncrease++) { - ll->positions[posToIncrease] += ll->positions[ts.start]; - } - } - - // Small hack to make lines that end with italics not cut off the edge of the last character - if (lastSegItalics) { - ll->positions[numCharsInLine] += vstyle.lastSegItalicsOffset; - } - ll->numCharsInLine = numCharsInLine; - ll->numCharsBeforeEOL = numCharsBeforeEOL; - ll->validity = LineLayout::llPositions; - } - // Hard to cope when too narrow, so just assume there is space - if (width < 20) { - width = 20; - } - if ((ll->validity == LineLayout::llPositions) || (ll->widthLine != width)) { - ll->widthLine = width; - if (width == LineLayout::wrapWidthInfinite) { - ll->lines = 1; - } else if (width > ll->positions[ll->numCharsInLine]) { - // Simple common case where line does not need wrapping. - ll->lines = 1; - } else { - if (vstyle.wrapVisualFlags & SC_WRAPVISUALFLAG_END) { - width -= static_cast(vstyle.aveCharWidth); // take into account the space for end wrap mark - } - XYPOSITION wrapAddIndent = 0; // This will be added to initial indent of line - if (vstyle.wrapIndentMode == SC_WRAPINDENT_INDENT) { - wrapAddIndent = model.pdoc->IndentSize() * vstyle.spaceWidth; - } else if (vstyle.wrapIndentMode == SC_WRAPINDENT_FIXED) { - wrapAddIndent = vstyle.wrapVisualStartIndent * vstyle.aveCharWidth; - } - ll->wrapIndent = wrapAddIndent; - if (vstyle.wrapIndentMode != SC_WRAPINDENT_FIXED) - for (int i = 0; i < ll->numCharsInLine; i++) { - if (!IsSpaceOrTab(ll->chars[i])) { - ll->wrapIndent += ll->positions[i]; // Add line indent - break; - } - } - // Check for text width minimum - if (ll->wrapIndent > width - static_cast(vstyle.aveCharWidth) * 15) - ll->wrapIndent = wrapAddIndent; - // Check for wrapIndent minimum - if ((vstyle.wrapVisualFlags & SC_WRAPVISUALFLAG_START) && (ll->wrapIndent < vstyle.aveCharWidth)) - ll->wrapIndent = vstyle.aveCharWidth; // Indent to show start visual - ll->lines = 0; - // Calculate line start positions based upon width. - int lastGoodBreak = 0; - int lastLineStart = 0; - XYACCUMULATOR startOffset = 0; - int p = 0; - while (p < ll->numCharsInLine) { - if ((ll->positions[p + 1] - startOffset) >= width) { - if (lastGoodBreak == lastLineStart) { - // Try moving to start of last character - if (p > 0) { - lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - - posLineStart; - } - if (lastGoodBreak == lastLineStart) { - // Ensure at least one character on line. - lastGoodBreak = model.pdoc->MovePositionOutsideChar(lastGoodBreak + posLineStart + 1, 1) - - posLineStart; - } - } - lastLineStart = lastGoodBreak; - ll->lines++; - ll->SetLineStart(ll->lines, lastGoodBreak); - startOffset = ll->positions[lastGoodBreak]; - // take into account the space for start wrap mark and indent - startOffset -= ll->wrapIndent; - p = lastGoodBreak + 1; - continue; - } - if (p > 0) { - if (vstyle.wrapState == eWrapChar) { - lastGoodBreak = model.pdoc->MovePositionOutsideChar(p + posLineStart, -1) - - posLineStart; - p = model.pdoc->MovePositionOutsideChar(p + 1 + posLineStart, 1) - posLineStart; - continue; - } else if ((vstyle.wrapState == eWrapWord) && (ll->styles[p] != ll->styles[p - 1])) { - lastGoodBreak = p; - } else if (IsSpaceOrTab(ll->chars[p - 1]) && !IsSpaceOrTab(ll->chars[p])) { - lastGoodBreak = p; - } - } - p++; - } - ll->lines++; - } - ll->validity = LineLayout::llLines; - } -} - -Point EditView::LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, - const ViewStyle &vs, PointEnd pe) { - Point pt; - if (pos.Position() == INVALID_POSITION) - return pt; - int lineDoc = model.pdoc->LineFromPosition(pos.Position()); - int posLineStart = model.pdoc->LineStart(lineDoc); - if ((pe & peLineEnd) && (lineDoc > 0) && (pos.Position() == posLineStart)) { - // Want point at end of first line - lineDoc--; - posLineStart = model.pdoc->LineStart(lineDoc); - } - const int lineVisible = model.cs.DisplayFromDoc(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); - if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); - const int posInLine = pos.Position() - posLineStart; - pt = ll->PointFromPosition(posInLine, vs.lineHeight, pe); - pt.y += (lineVisible - topLine) * vs.lineHeight; - pt.x += vs.textStart - model.xOffset; - } - pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth; - return pt; -} - -Range EditView::RangeDisplayLine(Surface *surface, const EditModel &model, int lineVisible, const ViewStyle &vs) { - Range rangeSubLine = Range(0,0); - if (lineVisible < 0) { - return rangeSubLine; - } - const int lineDoc = model.cs.DocFromDisplay(lineVisible); - const int positionLineStart = model.pdoc->LineStart(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); - if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); - const int lineStartSet = model.cs.DisplayFromDoc(lineDoc); - const int subLine = lineVisible - lineStartSet; - if (subLine < ll->lines) { - rangeSubLine = ll->SubLineRange(subLine); - if (subLine == ll->lines-1) { - rangeSubLine.end = model.pdoc->LineStart(lineDoc + 1) - - positionLineStart; - } - } - } - rangeSubLine.start += positionLineStart; - rangeSubLine.end += positionLineStart; - return rangeSubLine; -} - -SelectionPosition EditView::SPositionFromLocation(Surface *surface, const EditModel &model, PointDocument pt, bool canReturnInvalid, bool charPosition, bool virtualSpace, const ViewStyle &vs) { - pt.x = pt.x - vs.textStart; - int visibleLine = static_cast(floor(pt.y / vs.lineHeight)); - if (!canReturnInvalid && (visibleLine < 0)) - visibleLine = 0; - const int lineDoc = model.cs.DocFromDisplay(visibleLine); - if (canReturnInvalid && (lineDoc < 0)) - return SelectionPosition(INVALID_POSITION); - if (lineDoc >= model.pdoc->LinesTotal()) - return SelectionPosition(canReturnInvalid ? INVALID_POSITION : model.pdoc->Length()); - const int posLineStart = model.pdoc->LineStart(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); - if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); - const int lineStartSet = model.cs.DisplayFromDoc(lineDoc); - const int subLine = visibleLine - lineStartSet; - if (subLine < ll->lines) { - const Range rangeSubLine = ll->SubLineRange(subLine); - const XYPOSITION subLineStart = ll->positions[rangeSubLine.start]; - if (subLine > 0) // Wrapped - pt.x -= ll->wrapIndent; - const int positionInLine = ll->FindPositionFromX(static_cast(pt.x + subLineStart), - rangeSubLine, charPosition); - if (positionInLine < rangeSubLine.end) { - return SelectionPosition(model.pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1)); - } - if (virtualSpace) { - const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; - const int spaceOffset = static_cast( - (pt.x + subLineStart - ll->positions[rangeSubLine.end] + spaceWidth / 2) / spaceWidth); - return SelectionPosition(rangeSubLine.end + posLineStart, spaceOffset); - } else if (canReturnInvalid) { - if (pt.x < (ll->positions[rangeSubLine.end] - subLineStart)) { - return SelectionPosition(model.pdoc->MovePositionOutsideChar(rangeSubLine.end + posLineStart, 1)); - } - } else { - return SelectionPosition(rangeSubLine.end + posLineStart); - } - } - if (!canReturnInvalid) - return SelectionPosition(ll->numCharsInLine + posLineStart); - } - return SelectionPosition(canReturnInvalid ? INVALID_POSITION : posLineStart); -} - -/** -* Find the document position corresponding to an x coordinate on a particular document line. -* Ensure is between whole characters when document is in multi-byte or UTF-8 mode. -* This method is used for rectangular selections and does not work on wrapped lines. -*/ -SelectionPosition EditView::SPositionFromLineX(Surface *surface, const EditModel &model, int lineDoc, int x, const ViewStyle &vs) { - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); - if (surface && ll) { - const int posLineStart = model.pdoc->LineStart(lineDoc); - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); - const Range rangeSubLine = ll->SubLineRange(0); - const XYPOSITION subLineStart = ll->positions[rangeSubLine.start]; - const int positionInLine = ll->FindPositionFromX(x + subLineStart, rangeSubLine, false); - if (positionInLine < rangeSubLine.end) { - return SelectionPosition(model.pdoc->MovePositionOutsideChar(positionInLine + posLineStart, 1)); - } - const XYPOSITION spaceWidth = vs.styles[ll->EndLineStyle()].spaceWidth; - const int spaceOffset = static_cast( - (x + subLineStart - ll->positions[rangeSubLine.end] + spaceWidth / 2) / spaceWidth); - return SelectionPosition(rangeSubLine.end + posLineStart, spaceOffset); - } - return SelectionPosition(0); -} - -int EditView::DisplayFromPosition(Surface *surface, const EditModel &model, int pos, const ViewStyle &vs) { - int lineDoc = model.pdoc->LineFromPosition(pos); - int lineDisplay = model.cs.DisplayFromDoc(lineDoc); - AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc, model)); - if (surface && ll) { - LayoutLine(model, lineDoc, surface, vs, ll, model.wrapWidth); - unsigned int posLineStart = model.pdoc->LineStart(lineDoc); - int posInLine = pos - posLineStart; - lineDisplay--; // To make up for first increment ahead. - for (int subLine = 0; subLine < ll->lines; subLine++) { - if (posInLine >= ll->LineStart(subLine)) { - lineDisplay++; - } - } - } - return lineDisplay; -} - -int EditView::StartEndDisplayLine(Surface *surface, const EditModel &model, int pos, bool start, const ViewStyle &vs) { - int line = model.pdoc->LineFromPosition(pos); - AutoLineLayout ll(llc, RetrieveLineLayout(line, model)); - int posRet = INVALID_POSITION; - if (surface && ll) { - unsigned int posLineStart = model.pdoc->LineStart(line); - LayoutLine(model, line, surface, vs, ll, model.wrapWidth); - int posInLine = pos - posLineStart; - if (posInLine <= ll->maxLineLength) { - for (int subLine = 0; subLine < ll->lines; subLine++) { - if ((posInLine >= ll->LineStart(subLine)) && - (posInLine <= ll->LineStart(subLine + 1)) && - (posInLine <= ll->numCharsBeforeEOL)) { - if (start) { - posRet = ll->LineStart(subLine) + posLineStart; - } else { - if (subLine == ll->lines - 1) - posRet = ll->numCharsBeforeEOL + posLineStart; - else - posRet = ll->LineStart(subLine + 1) + posLineStart - 1; - } - } - } - } - } - return posRet; -} - -static ColourDesired SelectionBackground(const ViewStyle &vsDraw, bool main, bool primarySelection) { - return main ? - (primarySelection ? vsDraw.selColours.back : vsDraw.selBackground2) : - vsDraw.selAdditionalBackground; -} - -static ColourDesired TextBackground(const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - ColourOptional background, int inSelection, bool inHotspot, int styleMain, int i) { - if (inSelection == 1) { - if (vsDraw.selColours.back.isSet && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) { - return SelectionBackground(vsDraw, true, model.primarySelection); - } - } else if (inSelection == 2) { - if (vsDraw.selColours.back.isSet && (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)) { - return SelectionBackground(vsDraw, false, model.primarySelection); - } - } else { - if ((vsDraw.edgeState == EDGE_BACKGROUND) && - (i >= ll->edgeColumn) && - (i < ll->numCharsBeforeEOL)) - return vsDraw.theEdge.colour; - if (inHotspot && vsDraw.hotspotColours.back.isSet) - return vsDraw.hotspotColours.back; - } - if (background.isSet && (styleMain != STYLE_BRACELIGHT) && (styleMain != STYLE_BRACEBAD)) { - return background; - } else { - return vsDraw.styles[styleMain].back; - } -} - -void EditView::DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight) { - Point from = Point::FromInts(0, ((lineVisible & 1) && (lineHeight & 1)) ? 1 : 0); - PRectangle rcCopyArea = PRectangle::FromInts(start + 1, static_cast(rcSegment.top), start + 2, static_cast(rcSegment.bottom)); - surface->Copy(rcCopyArea, from, - highlight ? *pixmapIndentGuideHighlight : *pixmapIndentGuide); -} - -static void SimpleAlphaRectangle(Surface *surface, PRectangle rc, ColourDesired fill, int alpha) { - if (alpha != SC_ALPHA_NOALPHA) { - surface->AlphaRectangle(rc, 0, fill, alpha, fill, alpha, 0); - } -} - -static void DrawTextBlob(Surface *surface, const ViewStyle &vsDraw, PRectangle rcSegment, - const char *s, ColourDesired textBack, ColourDesired textFore, bool fillBackground) { - if (rcSegment.Empty()) - return; - if (fillBackground) { - surface->FillRectangle(rcSegment, textBack); - } - FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; - int normalCharHeight = static_cast(surface->Ascent(ctrlCharsFont) - - surface->InternalLeading(ctrlCharsFont)); - PRectangle rcCChar = rcSegment; - rcCChar.left = rcCChar.left + 1; - rcCChar.top = rcSegment.top + vsDraw.maxAscent - normalCharHeight; - rcCChar.bottom = rcSegment.top + vsDraw.maxAscent + 1; - PRectangle rcCentral = rcCChar; - rcCentral.top++; - rcCentral.bottom--; - surface->FillRectangle(rcCentral, textFore); - PRectangle rcChar = rcCChar; - rcChar.left++; - rcChar.right--; - surface->DrawTextClipped(rcChar, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, s, static_cast(s ? strlen(s) : 0), - textBack, textFore); -} - -void EditView::DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - PRectangle rcLine, int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, - ColourOptional background) { - - const int posLineStart = model.pdoc->LineStart(line); - PRectangle rcSegment = rcLine; - - const bool lastSubLine = subLine == (ll->lines - 1); - XYPOSITION virtualSpace = 0; - if (lastSubLine) { - const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; - virtualSpace = model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)) * spaceWidth; - } - XYPOSITION xEol = static_cast(ll->positions[lineEnd] - subLineStart); - - // Fill the virtual space and show selections within it - if (virtualSpace > 0.0f) { - rcSegment.left = xEol + xStart; - rcSegment.right = xEol + xStart + virtualSpace; - surface->FillRectangle(rcSegment, background.isSet ? background : vsDraw.styles[ll->styles[ll->numCharsInLine]].back); - if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) { - SelectionSegment virtualSpaceRange(SelectionPosition(model.pdoc->LineEnd(line)), SelectionPosition(model.pdoc->LineEnd(line), model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)))); - for (size_t r = 0; rEndLineStyle()].spaceWidth; - rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - - static_cast(subLineStart)+portion.start.VirtualSpace() * spaceWidth; - rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - - static_cast(subLineStart)+portion.end.VirtualSpace() * spaceWidth; - rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; - rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; - surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == model.sel.Main(), model.primarySelection)); - } - } - } - } - } - - int eolInSelection = 0; - int alpha = SC_ALPHA_NOALPHA; - if (!hideSelection) { - int posAfterLineEnd = model.pdoc->LineStart(line + 1); - eolInSelection = (lastSubLine == true) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; - alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; - } - - // Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on - XYPOSITION blobsWidth = 0; - if (lastSubLine) { - for (int eolPos = ll->numCharsBeforeEOL; eolPosnumCharsInLine; eolPos++) { - rcSegment.left = xStart + ll->positions[eolPos] - static_cast(subLineStart)+virtualSpace; - rcSegment.right = xStart + ll->positions[eolPos + 1] - static_cast(subLineStart)+virtualSpace; - blobsWidth += rcSegment.Width(); - char hexits[4]; - const char *ctrlChar; - unsigned char chEOL = ll->chars[eolPos]; - int styleMain = ll->styles[eolPos]; - ColourDesired textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, false, styleMain, eolPos); - if (UTF8IsAscii(chEOL)) { - ctrlChar = ControlCharacterString(chEOL); - } else { - const Representation *repr = model.reprs.RepresentationFromCharacter(ll->chars + eolPos, ll->numCharsInLine - eolPos); - if (repr) { - ctrlChar = repr->stringRep.c_str(); - eolPos = ll->numCharsInLine; - } else { - sprintf(hexits, "x%2X", chEOL); - ctrlChar = hexits; - } - } - ColourDesired textFore = vsDraw.styles[styleMain].fore; - if (eolInSelection && vsDraw.selColours.fore.isSet) { - textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; - } - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1)) { - if (alpha == SC_ALPHA_NOALPHA) { - surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); - } else { - surface->FillRectangle(rcSegment, textBack); - } - } else { - surface->FillRectangle(rcSegment, textBack); - } - DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, phasesDraw == phasesOne); - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); - } - } - } - - // Draw the eol-is-selected rectangle - rcSegment.left = xEol + xStart + virtualSpace + blobsWidth; - rcSegment.right = rcSegment.left + vsDraw.aveCharWidth; - - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { - surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); - } else { - if (background.isSet) { - surface->FillRectangle(rcSegment, background); - } else if (line < model.pdoc->LinesTotal() - 1) { - surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); - } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { - surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); - } else { - surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back); - } - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); - } - } - - rcSegment.left = rcSegment.right; - if (rcSegment.left < rcLine.left) - rcSegment.left = rcLine.left; - rcSegment.right = rcLine.right; - - bool fillRemainder = !lastSubLine || model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN || !model.cs.GetFoldDisplayTextShown(line); - if (fillRemainder) { - // Fill the remainder of the line - FillLineRemainder(surface, model, vsDraw, ll, line, rcSegment, subLine); - } - - bool drawWrapMarkEnd = false; - - if (vsDraw.wrapVisualFlags & SC_WRAPVISUALFLAG_END) { - if (subLine + 1 < ll->lines) { - drawWrapMarkEnd = ll->LineStart(subLine + 1) != 0; - } - } - - if (drawWrapMarkEnd) { - PRectangle rcPlace = rcSegment; - - if (vsDraw.wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) { - rcPlace.left = xEol + xStart + virtualSpace; - rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; - } else { - // rcLine is clipped to text area - rcPlace.right = rcLine.right; - rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; - } - if (customDrawWrapMarker == NULL) { - DrawWrapMarker(surface, rcPlace, true, vsDraw.WrapColour()); - } else { - customDrawWrapMarker(surface, rcPlace, true, vsDraw.WrapColour()); - } - } -} - -static void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, const ViewStyle &vsDraw, - const LineLayout *ll, int xStart, PRectangle rcLine, int secondCharacter, int subLine, Indicator::DrawState drawState, int value) { - const XYPOSITION subLineStart = ll->positions[ll->LineStart(subLine)]; - PRectangle rcIndic( - ll->positions[startPos] + xStart - subLineStart, - rcLine.top + vsDraw.maxAscent, - ll->positions[endPos] + xStart - subLineStart, - rcLine.top + vsDraw.maxAscent + 3); - PRectangle rcFirstCharacter = rcIndic; - // Allow full descent space for character indicators - rcFirstCharacter.bottom = rcLine.top + vsDraw.maxAscent + vsDraw.maxDescent; - if (secondCharacter >= 0) { - rcFirstCharacter.right = ll->positions[secondCharacter] + xStart - subLineStart; - } else { - // Indicator continued from earlier line so make an empty box and don't draw - rcFirstCharacter.right = rcFirstCharacter.left; - } - vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine, rcFirstCharacter, drawState, value); -} - -static void DrawIndicators(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int xStart, PRectangle rcLine, int subLine, int lineEnd, bool under, int hoverIndicatorPos) { - // Draw decorators - const int posLineStart = model.pdoc->LineStart(line); - const int lineStart = ll->LineStart(subLine); - const int posLineEnd = posLineStart + lineEnd; - - for (Decoration *deco = model.pdoc->decorations.root; deco; deco = deco->next) { - if (under == vsDraw.indicators[deco->indicator].under) { - int startPos = posLineStart + lineStart; - if (!deco->rs.ValueAt(startPos)) { - startPos = deco->rs.EndRun(startPos); - } - while ((startPos < posLineEnd) && (deco->rs.ValueAt(startPos))) { - const Range rangeRun(deco->rs.StartRun(startPos), deco->rs.EndRun(startPos)); - const int endPos = std::min(rangeRun.end, posLineEnd); - const bool hover = vsDraw.indicators[deco->indicator].IsDynamic() && - rangeRun.ContainsCharacter(hoverIndicatorPos); - const int value = deco->rs.ValueAt(startPos); - Indicator::DrawState drawState = hover ? Indicator::drawHover : Indicator::drawNormal; - const int posSecond = model.pdoc->MovePositionOutsideChar(rangeRun.First() + 1, 1); - DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart, - surface, vsDraw, ll, xStart, rcLine, posSecond - posLineStart, subLine, drawState, value); - startPos = endPos; - if (!deco->rs.ValueAt(startPos)) { - startPos = deco->rs.EndRun(startPos); - } - } - } - } - - // Use indicators to highlight matching braces - if ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACELIGHT)) || - (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACEBAD))) { - int braceIndicator = (model.bracesMatchStyle == STYLE_BRACELIGHT) ? vsDraw.braceHighlightIndicator : vsDraw.braceBadLightIndicator; - if (under == vsDraw.indicators[braceIndicator].under) { - Range rangeLine(posLineStart + lineStart, posLineEnd); - if (rangeLine.ContainsCharacter(model.braces[0])) { - int braceOffset = model.braces[0] - posLineStart; - if (braceOffset < ll->numCharsInLine) { - const int secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[0] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::drawNormal, 1); - } - } - if (rangeLine.ContainsCharacter(model.braces[1])) { - int braceOffset = model.braces[1] - posLineStart; - if (braceOffset < ll->numCharsInLine) { - const int secondOffset = model.pdoc->MovePositionOutsideChar(model.braces[1] + 1, 1) - posLineStart; - DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, ll, xStart, rcLine, secondOffset, subLine, Indicator::drawNormal, 1); - } - } - } - } -} - -void EditView::DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase) { - const bool lastSubLine = subLine == (ll->lines - 1); - if (!lastSubLine) - return; - - if ((model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_HIDDEN) || !model.cs.GetFoldDisplayTextShown(line)) - return; - - PRectangle rcSegment = rcLine; - const char *foldDisplayText = model.cs.GetFoldDisplayText(line); - const int lengthFoldDisplayText = static_cast(strlen(foldDisplayText)); - FontAlias fontText = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font; - const int widthFoldDisplayText = static_cast(surface->WidthText(fontText, foldDisplayText, lengthFoldDisplayText)); - - int eolInSelection = 0; - int alpha = SC_ALPHA_NOALPHA; - if (!hideSelection) { - int posAfterLineEnd = model.pdoc->LineStart(line + 1); - eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; - alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; - } - - const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; - XYPOSITION virtualSpace = model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)) * spaceWidth; - rcSegment.left = xStart + static_cast(ll->positions[ll->numCharsInLine] - subLineStart) + spaceWidth + virtualSpace; - rcSegment.right = rcSegment.left + static_cast(widthFoldDisplayText); - - ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - FontAlias textFont = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].font; - ColourDesired textFore = vsDraw.styles[STYLE_FOLDDISPLAYTEXT].fore; - if (eolInSelection && (vsDraw.selColours.fore.isSet)) { - textFore = (eolInSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; - } - ColourDesired textBack = TextBackground(model, vsDraw, ll, background, eolInSelection, - false, STYLE_FOLDDISPLAYTEXT, -1); - - if (model.trackLineWidth) { - if (rcSegment.right + 1> lineWidthMaxSeen) { - // Fold display text border drawn on rcSegment.right with width 1 is the last visble object of the line - lineWidthMaxSeen = static_cast(rcSegment.right + 1); - } - } - - if ((phasesDraw != phasesOne) && (phase & drawBack)) { - surface->FillRectangle(rcSegment, textBack); - - // Fill Remainder of the line - PRectangle rcRemainder = rcSegment; - rcRemainder.left = rcRemainder.right + 1; - if (rcRemainder.left < rcLine.left) - rcRemainder.left = rcLine.left; - rcRemainder.right = rcLine.right; - FillLineRemainder(surface, model, vsDraw, ll, line, rcRemainder, subLine); - } - - if (phase & drawText) { - if (phasesDraw != phasesOne) { - surface->DrawTextTransparent(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, foldDisplayText, - lengthFoldDisplayText, textFore); - } else { - surface->DrawTextNoClip(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, foldDisplayText, - lengthFoldDisplayText, textFore, textBack); - } - } - - if (phase & drawIndicatorsFore) { - if (model.foldDisplayTextStyle == SC_FOLDDISPLAYTEXT_BOXED) { - surface->PenColour(textFore); - surface->MoveTo(static_cast(rcSegment.left), static_cast(rcSegment.top)); - surface->LineTo(static_cast(rcSegment.left), static_cast(rcSegment.bottom)); - surface->MoveTo(static_cast(rcSegment.right), static_cast(rcSegment.top)); - surface->LineTo(static_cast(rcSegment.right), static_cast(rcSegment.bottom)); - surface->MoveTo(static_cast(rcSegment.left), static_cast(rcSegment.top)); - surface->LineTo(static_cast(rcSegment.right), static_cast(rcSegment.top)); - surface->MoveTo(static_cast(rcSegment.left), static_cast(rcSegment.bottom - 1)); - surface->LineTo(static_cast(rcSegment.right), static_cast(rcSegment.bottom - 1)); - } - } - - if (phase & drawSelectionTranslucent) { - if (eolInSelection && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && alpha != SC_ALPHA_NOALPHA) { - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); - } - } -} - -static bool AnnotationBoxedOrIndented(int annotationVisible) { - return annotationVisible == ANNOTATION_BOXED || annotationVisible == ANNOTATION_INDENTED; -} - -void EditView::DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase) { - int indent = static_cast(model.pdoc->GetLineIndentation(line) * vsDraw.spaceWidth); - PRectangle rcSegment = rcLine; - int annotationLine = subLine - ll->lines; - const StyledText stAnnotation = model.pdoc->AnnotationStyledText(line); - if (stAnnotation.text && ValidStyledText(vsDraw, vsDraw.annotationStyleOffset, stAnnotation)) { - if (phase & drawBack) { - surface->FillRectangle(rcSegment, vsDraw.styles[0].back); - } - rcSegment.left = static_cast(xStart); - if (model.trackLineWidth || AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { - // Only care about calculating width if tracking or need to draw indented box - int widthAnnotation = WidestLineWidth(surface, vsDraw, vsDraw.annotationStyleOffset, stAnnotation); - if (AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { - widthAnnotation += static_cast(vsDraw.spaceWidth * 2); // Margins - rcSegment.left = static_cast(xStart + indent); - rcSegment.right = rcSegment.left + widthAnnotation; - } - if (widthAnnotation > lineWidthMaxSeen) - lineWidthMaxSeen = widthAnnotation; - } - const int annotationLines = model.pdoc->AnnotationLines(line); - size_t start = 0; - size_t lengthAnnotation = stAnnotation.LineLength(start); - int lineInAnnotation = 0; - while ((lineInAnnotation < annotationLine) && (start < stAnnotation.length)) { - start += lengthAnnotation + 1; - lengthAnnotation = stAnnotation.LineLength(start); - lineInAnnotation++; - } - PRectangle rcText = rcSegment; - if ((phase & drawBack) && AnnotationBoxedOrIndented(vsDraw.annotationVisible)) { - surface->FillRectangle(rcText, - vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back); - rcText.left += vsDraw.spaceWidth; - } - DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, - stAnnotation, start, lengthAnnotation, phase); - if ((phase & drawBack) && (vsDraw.annotationVisible == ANNOTATION_BOXED)) { - surface->PenColour(vsDraw.styles[vsDraw.annotationStyleOffset].fore); - surface->MoveTo(static_cast(rcSegment.left), static_cast(rcSegment.top)); - surface->LineTo(static_cast(rcSegment.left), static_cast(rcSegment.bottom)); - surface->MoveTo(static_cast(rcSegment.right), static_cast(rcSegment.top)); - surface->LineTo(static_cast(rcSegment.right), static_cast(rcSegment.bottom)); - if (subLine == ll->lines) { - surface->MoveTo(static_cast(rcSegment.left), static_cast(rcSegment.top)); - surface->LineTo(static_cast(rcSegment.right), static_cast(rcSegment.top)); - } - if (subLine == ll->lines + annotationLines - 1) { - surface->MoveTo(static_cast(rcSegment.left), static_cast(rcSegment.bottom - 1)); - surface->LineTo(static_cast(rcSegment.right), static_cast(rcSegment.bottom - 1)); - } - } - } -} - -static void DrawBlockCaret(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret, ColourDesired caretColour) { - - int lineStart = ll->LineStart(subLine); - int posBefore = posCaret; - int posAfter = model.pdoc->MovePositionOutsideChar(posCaret + 1, 1); - int numCharsToDraw = posAfter - posCaret; - - // Work out where the starting and ending offsets are. We need to - // see if the previous character shares horizontal space, such as a - // glyph / combining character. If so we'll need to draw that too. - int offsetFirstChar = offset; - int offsetLastChar = offset + (posAfter - posCaret); - while ((posBefore > 0) && ((offsetLastChar - numCharsToDraw) >= lineStart)) { - if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - numCharsToDraw]) > 0) { - // The char does not share horizontal space - break; - } - // Char shares horizontal space, update the numChars to draw - // Update posBefore to point to the prev char - posBefore = model.pdoc->MovePositionOutsideChar(posBefore - 1, -1); - numCharsToDraw = posAfter - posBefore; - offsetFirstChar = offset - (posCaret - posBefore); - } - - // See if the next character shares horizontal space, if so we'll - // need to draw that too. - if (offsetFirstChar < 0) - offsetFirstChar = 0; - numCharsToDraw = offsetLastChar - offsetFirstChar; - while ((offsetLastChar < ll->LineStart(subLine + 1)) && (offsetLastChar <= ll->numCharsInLine)) { - // Update posAfter to point to the 2nd next char, this is where - // the next character ends, and 2nd next begins. We'll need - // to compare these two - posBefore = posAfter; - posAfter = model.pdoc->MovePositionOutsideChar(posAfter + 1, 1); - offsetLastChar = offset + (posAfter - posCaret); - if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - (posAfter - posBefore)]) > 0) { - // The char does not share horizontal space - break; - } - // Char shares horizontal space, update the numChars to draw - numCharsToDraw = offsetLastChar - offsetFirstChar; - } - - // We now know what to draw, update the caret drawing rectangle - rcCaret.left = ll->positions[offsetFirstChar] - ll->positions[lineStart] + xStart; - rcCaret.right = ll->positions[offsetFirstChar + numCharsToDraw] - ll->positions[lineStart] + xStart; - - // Adjust caret position to take into account any word wrapping symbols. - if ((ll->wrapIndent != 0) && (lineStart != 0)) { - XYPOSITION wordWrapCharWidth = ll->wrapIndent; - rcCaret.left += wordWrapCharWidth; - rcCaret.right += wordWrapCharWidth; - } - - // This character is where the caret block is, we override the colours - // (inversed) for drawing the caret here. - int styleMain = ll->styles[offsetFirstChar]; - FontAlias fontText = vsDraw.styles[styleMain].font; - surface->DrawTextClipped(rcCaret, fontText, - rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar, - numCharsToDraw, vsDraw.styles[styleMain].back, - caretColour); -} - -void EditView::DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int lineDoc, int xStart, PRectangle rcLine, int subLine) const { - // When drag is active it is the only caret drawn - bool drawDrag = model.posDrag.IsValid(); - if (hideSelection && !drawDrag) - return; - const int posLineStart = model.pdoc->LineStart(lineDoc); - // For each selection draw - for (size_t r = 0; (rEndLineStyle()].spaceWidth; - const XYPOSITION virtualOffset = posCaret.VirtualSpace() * spaceWidth; - if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) { - XYPOSITION xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)]; - if (ll->wrapIndent != 0) { - int lineStart = ll->LineStart(subLine); - if (lineStart != 0) // Wrapped - xposCaret += ll->wrapIndent; - } - bool caretBlinkState = (model.caret.active && model.caret.on) || (!additionalCaretsBlink && !mainCaret); - bool caretVisibleState = additionalCaretsVisible || mainCaret; - if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) && - ((model.posDrag.IsValid()) || (caretBlinkState && caretVisibleState))) { - bool caretAtEOF = false; - bool caretAtEOL = false; - bool drawBlockCaret = false; - XYPOSITION widthOverstrikeCaret; - XYPOSITION caretWidthOffset = 0; - PRectangle rcCaret = rcLine; - - if (posCaret.Position() == model.pdoc->Length()) { // At end of document - caretAtEOF = true; - widthOverstrikeCaret = vsDraw.aveCharWidth; - } else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) { // At end of line - caretAtEOL = true; - widthOverstrikeCaret = vsDraw.aveCharWidth; - } else { - const int widthChar = model.pdoc->LenChar(posCaret.Position()); - widthOverstrikeCaret = ll->positions[offset + widthChar] - ll->positions[offset]; - } - if (widthOverstrikeCaret < 3) // Make sure its visible - widthOverstrikeCaret = 3; - - if (xposCaret > 0) - caretWidthOffset = 0.51f; // Move back so overlaps both character cells. - xposCaret += xStart; - if (model.posDrag.IsValid()) { - /* Dragging text, use a line caret */ - rcCaret.left = static_cast(RoundXYPosition(xposCaret - caretWidthOffset)); - rcCaret.right = rcCaret.left + vsDraw.caretWidth; - } else if (model.inOverstrike && drawOverstrikeCaret) { - /* Overstrike (insert mode), use a modified bar caret */ - rcCaret.top = rcCaret.bottom - 2; - rcCaret.left = xposCaret + 1; - rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1; - } else if ((vsDraw.caretStyle == CARETSTYLE_BLOCK) || imeCaretBlockOverride) { - /* Block caret */ - rcCaret.left = xposCaret; - if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) { - drawBlockCaret = true; - rcCaret.right = xposCaret + widthOverstrikeCaret; - } else { - rcCaret.right = xposCaret + vsDraw.aveCharWidth; - } - } else { - /* Line caret */ - rcCaret.left = static_cast(RoundXYPosition(xposCaret - caretWidthOffset)); - rcCaret.right = rcCaret.left + vsDraw.caretWidth; - } - ColourDesired caretColour = mainCaret ? vsDraw.caretcolour : vsDraw.additionalCaretColour; - if (drawBlockCaret) { - DrawBlockCaret(surface, model, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour); - } else { - surface->FillRectangle(rcCaret, caretColour); - } - } - } - if (drawDrag) - break; - } -} - -static void DrawWrapIndentAndMarker(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, - int xStart, PRectangle rcLine, ColourOptional background, DrawWrapMarkerFn customDrawWrapMarker) { - // default bgnd here.. - surface->FillRectangle(rcLine, background.isSet ? background : - vsDraw.styles[STYLE_DEFAULT].back); - - if (vsDraw.wrapVisualFlags & SC_WRAPVISUALFLAG_START) { - - // draw continuation rect - PRectangle rcPlace = rcLine; - - rcPlace.left = static_cast(xStart); - rcPlace.right = rcPlace.left + ll->wrapIndent; - - if (vsDraw.wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_START_BY_TEXT) - rcPlace.left = rcPlace.right - vsDraw.aveCharWidth; - else - rcPlace.right = rcPlace.left + vsDraw.aveCharWidth; - - if (customDrawWrapMarker == NULL) { - DrawWrapMarker(surface, rcPlace, false, vsDraw.WrapColour()); - } else { - customDrawWrapMarker(surface, rcPlace, false, vsDraw.WrapColour()); - } - } -} - -void EditView::DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - PRectangle rcLine, Range lineRange, int posLineStart, int xStart, - int subLine, ColourOptional background) const { - - const bool selBackDrawn = vsDraw.SelectionBackgroundDrawn(); - bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. - const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; - // Does not take margin into account but not significant - const int xStartVisible = static_cast(subLineStart)-xStart; - - BreakFinder bfBack(ll, &model.sel, lineRange, posLineStart, xStartVisible, selBackDrawn, model.pdoc, &model.reprs, NULL); - - const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background.isSet; - - // Background drawing loop - while (bfBack.More()) { - - const TextSegment ts = bfBack.Next(); - const int i = ts.end() - 1; - const int iDoc = i + posLineStart; - - PRectangle rcSegment = rcLine; - rcSegment.left = ll->positions[ts.start] + xStart - static_cast(subLineStart); - rcSegment.right = ll->positions[ts.end()] + xStart - static_cast(subLineStart); - // Only try to draw if really visible - enhances performance by not calling environment to - // draw strings that are completely past the right side of the window. - if (!rcSegment.Empty() && rcSegment.Intersects(rcLine)) { - // Clip to line rectangle, since may have a huge position which will not work with some platforms - if (rcSegment.left < rcLine.left) - rcSegment.left = rcLine.left; - if (rcSegment.right > rcLine.right) - rcSegment.right = rcLine.right; - - const int inSelection = hideSelection ? 0 : model.sel.CharacterInSelection(iDoc); - const bool inHotspot = (ll->hotspot.Valid()) && ll->hotspot.ContainsCharacter(iDoc); - ColourDesired textBack = TextBackground(model, vsDraw, ll, background, inSelection, - inHotspot, ll->styles[i], i); - if (ts.representation) { - if (ll->chars[i] == '\t') { - // Tab display - if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) - textBack = vsDraw.whitespaceColours.back; - } else { - // Blob display - inIndentation = false; - } - surface->FillRectangle(rcSegment, textBack); - } else { - // Normal text display - surface->FillRectangle(rcSegment, textBack); - if (vsDraw.viewWhitespace != wsInvisible) { - for (int cpos = 0; cpos <= i - ts.start; cpos++) { - if (ll->chars[cpos + ts.start] == ' ') { - if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) { - PRectangle rcSpace( - ll->positions[cpos + ts.start] + xStart - static_cast(subLineStart), - rcSegment.top, - ll->positions[cpos + ts.start + 1] + xStart - static_cast(subLineStart), - rcSegment.bottom); - surface->FillRectangle(rcSpace, vsDraw.whitespaceColours.back); - } - } else { - inIndentation = false; - } - } - } - } - } else if (rcSegment.left > rcLine.right) { - break; - } - } -} - -static void DrawEdgeLine(Surface *surface, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, - Range lineRange, int xStart) { - if (vsDraw.edgeState == EDGE_LINE) { - PRectangle rcSegment = rcLine; - int edgeX = static_cast(vsDraw.theEdge.column * vsDraw.spaceWidth); - rcSegment.left = static_cast(edgeX + xStart); - if ((ll->wrapIndent != 0) && (lineRange.start != 0)) - rcSegment.left -= ll->wrapIndent; - rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vsDraw.theEdge.colour); - } else if (vsDraw.edgeState == EDGE_MULTILINE) { - for (size_t edge = 0; edge < vsDraw.theMultiEdge.size(); edge++) { - if (vsDraw.theMultiEdge[edge].column >= 0) { - PRectangle rcSegment = rcLine; - int edgeX = static_cast(vsDraw.theMultiEdge[edge].column * vsDraw.spaceWidth); - rcSegment.left = static_cast(edgeX + xStart); - if ((ll->wrapIndent != 0) && (lineRange.start != 0)) - rcSegment.left -= ll->wrapIndent; - rcSegment.right = rcSegment.left + 1; - surface->FillRectangle(rcSegment, vsDraw.theMultiEdge[edge].colour); - } - } - } -} - -// Draw underline mark as part of background if not transparent -static void DrawMarkUnderline(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, - int line, PRectangle rcLine) { - int marks = model.pdoc->GetMark(line); - for (int markBit = 0; (markBit < 32) && marks; markBit++) { - if ((marks & 1) && (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) && - (vsDraw.markers[markBit].alpha == SC_ALPHA_NOALPHA)) { - PRectangle rcUnderline = rcLine; - rcUnderline.top = rcUnderline.bottom - 2; - surface->FillRectangle(rcUnderline, vsDraw.markers[markBit].back); - } - marks >>= 1; - } -} -static void DrawTranslucentSelection(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, PRectangle rcLine, int subLine, Range lineRange, int xStart) { - if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA)) { - const int posLineStart = model.pdoc->LineStart(line); - const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; - // For each selection draw - int virtualSpaces = 0; - if (subLine == (ll->lines - 1)) { - virtualSpaces = model.sel.VirtualSpaceFor(model.pdoc->LineEnd(line)); - } - SelectionPosition posStart(posLineStart + lineRange.start); - SelectionPosition posEnd(posLineStart + lineRange.end, virtualSpaces); - SelectionSegment virtualSpaceRange(posStart, posEnd); - for (size_t r = 0; r < model.sel.Count(); r++) { - int alpha = (r == model.sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; - if (alpha != SC_ALPHA_NOALPHA) { - SelectionSegment portion = model.sel.Range(r).Intersect(virtualSpaceRange); - if (!portion.Empty()) { - const XYPOSITION spaceWidth = vsDraw.styles[ll->EndLineStyle()].spaceWidth; - PRectangle rcSegment = rcLine; - rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - - static_cast(subLineStart)+portion.start.VirtualSpace() * spaceWidth; - rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - - static_cast(subLineStart)+portion.end.VirtualSpace() * spaceWidth; - if ((ll->wrapIndent != 0) && (lineRange.start != 0)) { - if ((portion.start.Position() - posLineStart) == lineRange.start && model.sel.Range(r).ContainsCharacter(portion.start.Position() - 1)) - rcSegment.left -= static_cast(ll->wrapIndent); // indentation added to xStart was truncated to int, so we do the same here - } - rcSegment.left = (rcSegment.left > rcLine.left) ? rcSegment.left : rcLine.left; - rcSegment.right = (rcSegment.right < rcLine.right) ? rcSegment.right : rcLine.right; - if (rcSegment.right > rcLine.left) - SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == model.sel.Main(), model.primarySelection), alpha); - } - } - } - } -} - -// Draw any translucent whole line states -static void DrawTranslucentLineState(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, PRectangle rcLine) { - if ((model.caret.active || vsDraw.alwaysShowCaretLineBackground) && vsDraw.showCaretLineBackground && ll->containsCaret) { - SimpleAlphaRectangle(surface, rcLine, vsDraw.caretLineBackground, vsDraw.caretLineAlpha); - } - const int marksOfLine = model.pdoc->GetMark(line); - int marksDrawnInText = marksOfLine & vsDraw.maskDrawInText; - for (int markBit = 0; (markBit < 32) && marksDrawnInText; markBit++) { - if (marksDrawnInText & 1) { - if (vsDraw.markers[markBit].markType == SC_MARK_BACKGROUND) { - SimpleAlphaRectangle(surface, rcLine, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); - } else if (vsDraw.markers[markBit].markType == SC_MARK_UNDERLINE) { - PRectangle rcUnderline = rcLine; - rcUnderline.top = rcUnderline.bottom - 2; - SimpleAlphaRectangle(surface, rcUnderline, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); - } - } - marksDrawnInText >>= 1; - } - int marksDrawnInLine = marksOfLine & vsDraw.maskInLine; - for (int markBit = 0; (markBit < 32) && marksDrawnInLine; markBit++) { - if (marksDrawnInLine & 1) { - SimpleAlphaRectangle(surface, rcLine, vsDraw.markers[markBit].back, vsDraw.markers[markBit].alpha); - } - marksDrawnInLine >>= 1; - } -} - -void EditView::DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int lineVisible, PRectangle rcLine, Range lineRange, int posLineStart, int xStart, - int subLine, ColourOptional background) { - - const bool selBackDrawn = vsDraw.SelectionBackgroundDrawn(); - const bool drawWhitespaceBackground = vsDraw.WhitespaceBackgroundDrawn() && !background.isSet; - bool inIndentation = subLine == 0; // Do not handle indentation except on first subline. - - const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; - const XYPOSITION indentWidth = model.pdoc->IndentSize() * vsDraw.spaceWidth; - - // Does not take margin into account but not significant - const int xStartVisible = static_cast(subLineStart)-xStart; - - // Foreground drawing loop - BreakFinder bfFore(ll, &model.sel, lineRange, posLineStart, xStartVisible, - (((phasesDraw == phasesOne) && selBackDrawn) || vsDraw.selColours.fore.isSet), model.pdoc, &model.reprs, &vsDraw); - - while (bfFore.More()) { - - const TextSegment ts = bfFore.Next(); - const int i = ts.end() - 1; - const int iDoc = i + posLineStart; - - PRectangle rcSegment = rcLine; - rcSegment.left = ll->positions[ts.start] + xStart - static_cast(subLineStart); - rcSegment.right = ll->positions[ts.end()] + xStart - static_cast(subLineStart); - // Only try to draw if really visible - enhances performance by not calling environment to - // draw strings that are completely past the right side of the window. - if (rcSegment.Intersects(rcLine)) { - int styleMain = ll->styles[i]; - ColourDesired textFore = vsDraw.styles[styleMain].fore; - FontAlias textFont = vsDraw.styles[styleMain].font; - //hotspot foreground - const bool inHotspot = (ll->hotspot.Valid()) && ll->hotspot.ContainsCharacter(iDoc); - if (inHotspot) { - if (vsDraw.hotspotColours.fore.isSet) - textFore = vsDraw.hotspotColours.fore; - } - if (vsDraw.indicatorsSetFore > 0) { - // At least one indicator sets the text colour so see if it applies to this segment - for (Decoration *deco = model.pdoc->decorations.root; deco; deco = deco->next) { - const int indicatorValue = deco->rs.ValueAt(ts.start + posLineStart); - if (indicatorValue) { - const Indicator &indicator = vsDraw.indicators[deco->indicator]; - const bool hover = indicator.IsDynamic() && - ((model.hoverIndicatorPos >= ts.start + posLineStart) && - (model.hoverIndicatorPos <= ts.end() + posLineStart)); - if (hover) { - if (indicator.sacHover.style == INDIC_TEXTFORE) { - textFore = indicator.sacHover.fore; - } - } else { - if (indicator.sacNormal.style == INDIC_TEXTFORE) { - if (indicator.Flags() & SC_INDICFLAG_VALUEFORE) - textFore = indicatorValue & SC_INDICVALUEMASK; - else - textFore = indicator.sacNormal.fore; - } - } - } - } - } - const int inSelection = hideSelection ? 0 : model.sel.CharacterInSelection(iDoc); - if (inSelection && (vsDraw.selColours.fore.isSet)) { - textFore = (inSelection == 1) ? vsDraw.selColours.fore : vsDraw.selAdditionalForeground; - } - ColourDesired textBack = TextBackground(model, vsDraw, ll, background, inSelection, inHotspot, styleMain, i); - if (ts.representation) { - if (ll->chars[i] == '\t') { - // Tab display - if (phasesDraw == phasesOne) { - if (drawWhitespaceBackground && vsDraw.WhiteSpaceVisible(inIndentation)) - textBack = vsDraw.whitespaceColours.back; - surface->FillRectangle(rcSegment, textBack); - } - if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { - for (int indentCount = static_cast((ll->positions[i] + epsilon) / indentWidth); - indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth; - indentCount++) { - if (indentCount > 0) { - int xIndent = static_cast(indentCount * indentWidth); - DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, - (ll->xHighlightGuide == xIndent)); - } - } - } - if (vsDraw.viewWhitespace != wsInvisible) { - if (vsDraw.WhiteSpaceVisible(inIndentation)) { - if (vsDraw.whitespaceColours.fore.isSet) - textFore = vsDraw.whitespaceColours.fore; - surface->PenColour(textFore); - PRectangle rcTab(rcSegment.left + 1, rcSegment.top + tabArrowHeight, - rcSegment.right - 1, rcSegment.bottom - vsDraw.maxDescent); - if (customDrawTabArrow == NULL) - DrawTabArrow(surface, rcTab, static_cast(rcSegment.top + vsDraw.lineHeight / 2), vsDraw); - else - customDrawTabArrow(surface, rcTab, static_cast(rcSegment.top + vsDraw.lineHeight / 2)); - } - } - } else { - inIndentation = false; - if (vsDraw.controlCharSymbol >= 32) { - // Using one font for all control characters so it can be controlled independently to ensure - // the box goes around the characters tightly. Seems to be no way to work out what height - // is taken by an individual character - internal leading gives varying results. - FontAlias ctrlCharsFont = vsDraw.styles[STYLE_CONTROLCHAR].font; - char cc[2] = { static_cast(vsDraw.controlCharSymbol), '\0' }; - surface->DrawTextNoClip(rcSegment, ctrlCharsFont, - rcSegment.top + vsDraw.maxAscent, - cc, 1, textBack, textFore); - } else { - DrawTextBlob(surface, vsDraw, rcSegment, ts.representation->stringRep.c_str(), - textBack, textFore, phasesDraw == phasesOne); - } - } - } else { - // Normal text display - if (vsDraw.styles[styleMain].visible) { - if (phasesDraw != phasesOne) { - surface->DrawTextTransparent(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, ll->chars + ts.start, - i - ts.start + 1, textFore); - } else { - surface->DrawTextNoClip(rcSegment, textFont, - rcSegment.top + vsDraw.maxAscent, ll->chars + ts.start, - i - ts.start + 1, textFore, textBack); - } - } - if (vsDraw.viewWhitespace != wsInvisible || - (inIndentation && vsDraw.viewIndentationGuides != ivNone)) { - for (int cpos = 0; cpos <= i - ts.start; cpos++) { - if (ll->chars[cpos + ts.start] == ' ') { - if (vsDraw.viewWhitespace != wsInvisible) { - if (vsDraw.whitespaceColours.fore.isSet) - textFore = vsDraw.whitespaceColours.fore; - if (vsDraw.WhiteSpaceVisible(inIndentation)) { - XYPOSITION xmid = (ll->positions[cpos + ts.start] + ll->positions[cpos + ts.start + 1]) / 2; - if ((phasesDraw == phasesOne) && drawWhitespaceBackground) { - textBack = vsDraw.whitespaceColours.back; - PRectangle rcSpace( - ll->positions[cpos + ts.start] + xStart - static_cast(subLineStart), - rcSegment.top, - ll->positions[cpos + ts.start + 1] + xStart - static_cast(subLineStart), - rcSegment.bottom); - surface->FillRectangle(rcSpace, textBack); - } - const int halfDotWidth = vsDraw.whitespaceSize / 2; - PRectangle rcDot(xmid + xStart - halfDotWidth - static_cast(subLineStart), - rcSegment.top + vsDraw.lineHeight / 2, 0.0f, 0.0f); - rcDot.right = rcDot.left + vsDraw.whitespaceSize; - rcDot.bottom = rcDot.top + vsDraw.whitespaceSize; - surface->FillRectangle(rcDot, textFore); - } - } - if (inIndentation && vsDraw.viewIndentationGuides == ivReal) { - for (int indentCount = static_cast((ll->positions[cpos + ts.start] + epsilon) / indentWidth); - indentCount <= (ll->positions[cpos + ts.start + 1] - epsilon) / indentWidth; - indentCount++) { - if (indentCount > 0) { - int xIndent = static_cast(indentCount * indentWidth); - DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment, - (ll->xHighlightGuide == xIndent)); - } - } - } - } else { - inIndentation = false; - } - } - } - } - if (ll->hotspot.Valid() && vsDraw.hotspotUnderline && ll->hotspot.ContainsCharacter(iDoc)) { - PRectangle rcUL = rcSegment; - rcUL.top = rcUL.top + vsDraw.maxAscent + 1; - rcUL.bottom = rcUL.top + 1; - if (vsDraw.hotspotColours.fore.isSet) - surface->FillRectangle(rcUL, vsDraw.hotspotColours.fore); - else - surface->FillRectangle(rcUL, textFore); - } else if (vsDraw.styles[styleMain].underline) { - PRectangle rcUL = rcSegment; - rcUL.top = rcUL.top + vsDraw.maxAscent + 1; - rcUL.bottom = rcUL.top + 1; - surface->FillRectangle(rcUL, textFore); - } - } else if (rcSegment.left > rcLine.right) { - break; - } - } -} - -void EditView::DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int lineVisible, PRectangle rcLine, int xStart, int subLine) { - if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth) - && (subLine == 0)) { - const int posLineStart = model.pdoc->LineStart(line); - int indentSpace = model.pdoc->GetLineIndentation(line); - int xStartText = static_cast(ll->positions[model.pdoc->GetLineIndentPosition(line) - posLineStart]); - - // Find the most recent line with some text - - int lineLastWithText = line; - while (lineLastWithText > Platform::Maximum(line - 20, 0) && model.pdoc->IsWhiteLine(lineLastWithText)) { - lineLastWithText--; - } - if (lineLastWithText < line) { - xStartText = 100000; // Don't limit to visible indentation on empty line - // This line is empty, so use indentation of last line with text - int indentLastWithText = model.pdoc->GetLineIndentation(lineLastWithText); - int isFoldHeader = model.pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG; - if (isFoldHeader) { - // Level is one more level than parent - indentLastWithText += model.pdoc->IndentSize(); - } - if (vsDraw.viewIndentationGuides == ivLookForward) { - // In viLookForward mode, previous line only used if it is a fold header - if (isFoldHeader) { - indentSpace = Platform::Maximum(indentSpace, indentLastWithText); - } - } else { // viLookBoth - indentSpace = Platform::Maximum(indentSpace, indentLastWithText); - } - } - - int lineNextWithText = line; - while (lineNextWithText < Platform::Minimum(line + 20, model.pdoc->LinesTotal()) && model.pdoc->IsWhiteLine(lineNextWithText)) { - lineNextWithText++; - } - if (lineNextWithText > line) { - xStartText = 100000; // Don't limit to visible indentation on empty line - // This line is empty, so use indentation of first next line with text - indentSpace = Platform::Maximum(indentSpace, - model.pdoc->GetLineIndentation(lineNextWithText)); - } - - for (int indentPos = model.pdoc->IndentSize(); indentPos < indentSpace; indentPos += model.pdoc->IndentSize()) { - int xIndent = static_cast(indentPos * vsDraw.spaceWidth); - if (xIndent < xStartText) { - DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcLine, - (ll->xHighlightGuide == xIndent)); - } - } - } -} - -void EditView::DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase) { - - if (subLine >= ll->lines) { - DrawAnnotation(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, phase); - return; // No further drawing - } - - // See if something overrides the line background color. - const ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - - const int posLineStart = model.pdoc->LineStart(line); - - const Range lineRange = ll->SubLineRange(subLine); - const XYACCUMULATOR subLineStart = ll->positions[lineRange.start]; - - if ((ll->wrapIndent != 0) && (subLine > 0)) { - if (phase & drawBack) { - DrawWrapIndentAndMarker(surface, vsDraw, ll, xStart, rcLine, background, customDrawWrapMarker); - } - xStart += static_cast(ll->wrapIndent); - } - - if ((phasesDraw != phasesOne) && (phase & drawBack)) { - DrawBackground(surface, model, vsDraw, ll, rcLine, lineRange, posLineStart, xStart, - subLine, background); - DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, - xStart, subLine, subLineStart, background); - } - - if (phase & drawIndicatorsBack) { - DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, lineRange.end, true, model.hoverIndicatorPos); - DrawEdgeLine(surface, vsDraw, ll, rcLine, lineRange, xStart); - DrawMarkUnderline(surface, model, vsDraw, line, rcLine); - } - - if (phase & drawText) { - DrawForeground(surface, model, vsDraw, ll, lineVisible, rcLine, lineRange, posLineStart, xStart, - subLine, background); - } - - if (phase & drawIndentationGuides) { - DrawIndentGuidesOverEmpty(surface, model, vsDraw, ll, line, lineVisible, rcLine, xStart, subLine); - } - - if (phase & drawIndicatorsFore) { - DrawIndicators(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, lineRange.end, false, model.hoverIndicatorPos); - } - - // End of the drawing of the current line - if (phasesDraw == phasesOne) { - DrawEOL(surface, model, vsDraw, ll, rcLine, line, lineRange.end, - xStart, subLine, subLineStart, background); - } - - DrawFoldDisplayText(surface, model, vsDraw, ll, line, xStart, rcLine, subLine, subLineStart, phase); - - if (!hideSelection && (phase & drawSelectionTranslucent)) { - DrawTranslucentSelection(surface, model, vsDraw, ll, line, rcLine, subLine, lineRange, xStart); - } - - if (phase & drawLineTranslucent) { - DrawTranslucentLineState(surface, model, vsDraw, ll, line, rcLine); - } -} - -static void DrawFoldLines(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, int line, PRectangle rcLine) { - bool expanded = model.cs.GetExpanded(line); - const int level = model.pdoc->GetLevel(line); - const int levelNext = model.pdoc->GetLevel(line + 1); - if ((level & SC_FOLDLEVELHEADERFLAG) && - (LevelNumber(level) < LevelNumber(levelNext))) { - // Paint the line above the fold - if ((expanded && (model.foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED)) - || - (!expanded && (model.foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) { - PRectangle rcFoldLine = rcLine; - rcFoldLine.bottom = rcFoldLine.top + 1; - surface->FillRectangle(rcFoldLine, vsDraw.styles[STYLE_DEFAULT].fore); - } - // Paint the line below the fold - if ((expanded && (model.foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED)) - || - (!expanded && (model.foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) { - PRectangle rcFoldLine = rcLine; - rcFoldLine.top = rcFoldLine.bottom - 1; - surface->FillRectangle(rcFoldLine, vsDraw.styles[STYLE_DEFAULT].fore); - } - } -} - -void EditView::PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, - PRectangle rcClient, const ViewStyle &vsDraw) { - // Allow text at start of line to overlap 1 pixel into the margin as this displays - // serifs and italic stems for aliased text. - const int leftTextOverlap = ((model.xOffset == 0) && (vsDraw.leftMarginWidth > 0)) ? 1 : 0; - - // Do the painting - if (rcArea.right > vsDraw.textStart - leftTextOverlap) { - - Surface *surface = surfaceWindow; - if (bufferedDraw) { - surface = pixmapLine; - PLATFORM_ASSERT(pixmapLine->Initialised()); - } - surface->SetUnicodeMode(SC_CP_UTF8 == model.pdoc->dbcsCodePage); - surface->SetDBCSMode(model.pdoc->dbcsCodePage); - - const Point ptOrigin = model.GetVisibleOriginInMain(); - - const int screenLinePaintFirst = static_cast(rcArea.top) / vsDraw.lineHeight; - const int xStart = vsDraw.textStart - model.xOffset + static_cast(ptOrigin.x); - - SelectionPosition posCaret = model.sel.RangeMain().caret; - if (model.posDrag.IsValid()) - posCaret = model.posDrag; - const int lineCaret = model.pdoc->LineFromPosition(posCaret.Position()); - - PRectangle rcTextArea = rcClient; - if (vsDraw.marginInside) { - rcTextArea.left += vsDraw.textStart; - rcTextArea.right -= vsDraw.rightMarginWidth; - } else { - rcTextArea = rcArea; - } - - // Remove selection margin from drawing area so text will not be drawn - // on it in unbuffered mode. - if (!bufferedDraw && vsDraw.marginInside) { - PRectangle rcClipText = rcTextArea; - rcClipText.left -= leftTextOverlap; - surfaceWindow->SetClip(rcClipText); - } - - // Loop on visible lines - //double durLayout = 0.0; - //double durPaint = 0.0; - //double durCopy = 0.0; - //ElapsedTime etWhole; - - const bool bracesIgnoreStyle = ((vsDraw.braceHighlightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACELIGHT)) || - (vsDraw.braceBadLightIndicatorSet && (model.bracesMatchStyle == STYLE_BRACEBAD))); - - int lineDocPrevious = -1; // Used to avoid laying out one document line multiple times - AutoLineLayout ll(llc, 0); - std::vector phases; - if ((phasesDraw == phasesMultiple) && !bufferedDraw) { - for (DrawPhase phase = drawBack; phase <= drawCarets; phase = static_cast(phase * 2)) { - phases.push_back(phase); - } - } else { - phases.push_back(drawAll); - } - for (std::vector::iterator it = phases.begin(); it != phases.end(); ++it) { - int ypos = 0; - if (!bufferedDraw) - ypos += screenLinePaintFirst * vsDraw.lineHeight; - int yposScreen = screenLinePaintFirst * vsDraw.lineHeight; - int visibleLine = model.TopLineOfMain() + screenLinePaintFirst; - while (visibleLine < model.cs.LinesDisplayed() && yposScreen < rcArea.bottom) { - - const int lineDoc = model.cs.DocFromDisplay(visibleLine); - // Only visible lines should be handled by the code within the loop - PLATFORM_ASSERT(model.cs.GetVisible(lineDoc)); - const int lineStartSet = model.cs.DisplayFromDoc(lineDoc); - const int subLine = visibleLine - lineStartSet; - - // Copy this line and its styles from the document into local arrays - // and determine the x position at which each character starts. - //ElapsedTime et; - if (lineDoc != lineDocPrevious) { - ll.Set(0); - ll.Set(RetrieveLineLayout(lineDoc, model)); - LayoutLine(model, lineDoc, surface, vsDraw, ll, model.wrapWidth); - lineDocPrevious = lineDoc; - } - //durLayout += et.Duration(true); - - if (ll) { - ll->containsCaret = !hideSelection && (lineDoc == lineCaret); - ll->hotspot = model.GetHotSpotRange(); - - PRectangle rcLine = rcTextArea; - rcLine.top = static_cast(ypos); - rcLine.bottom = static_cast(ypos + vsDraw.lineHeight); - - Range rangeLine(model.pdoc->LineStart(lineDoc), model.pdoc->LineStart(lineDoc + 1)); - - // Highlight the current braces if any - ll->SetBracesHighlight(rangeLine, model.braces, static_cast(model.bracesMatchStyle), - static_cast(model.highlightGuideColumn * vsDraw.spaceWidth), bracesIgnoreStyle); - - if (leftTextOverlap && (bufferedDraw || ((phasesDraw < phasesMultiple) && (*it & drawBack)))) { - // Clear the left margin - PRectangle rcSpacer = rcLine; - rcSpacer.right = rcSpacer.left; - rcSpacer.left -= 1; - surface->FillRectangle(rcSpacer, vsDraw.styles[STYLE_DEFAULT].back); - } - - DrawLine(surface, model, vsDraw, ll, lineDoc, visibleLine, xStart, rcLine, subLine, *it); - //durPaint += et.Duration(true); - - // Restore the previous styles for the brace highlights in case layout is in cache. - ll->RestoreBracesHighlight(rangeLine, model.braces, bracesIgnoreStyle); - - if (*it & drawFoldLines) { - DrawFoldLines(surface, model, vsDraw, lineDoc, rcLine); - } - - if (*it & drawCarets) { - DrawCarets(surface, model, vsDraw, ll, lineDoc, xStart, rcLine, subLine); - } - - if (bufferedDraw) { - Point from = Point::FromInts(vsDraw.textStart - leftTextOverlap, 0); - PRectangle rcCopyArea = PRectangle::FromInts(vsDraw.textStart - leftTextOverlap, yposScreen, - static_cast(rcClient.right - vsDraw.rightMarginWidth), - yposScreen + vsDraw.lineHeight); - surfaceWindow->Copy(rcCopyArea, from, *pixmapLine); - } - - lineWidthMaxSeen = Platform::Maximum( - lineWidthMaxSeen, static_cast(ll->positions[ll->numCharsInLine])); - //durCopy += et.Duration(true); - } - - if (!bufferedDraw) { - ypos += vsDraw.lineHeight; - } - - yposScreen += vsDraw.lineHeight; - visibleLine++; - } - } - ll.Set(0); - //if (durPaint < 0.00000001) - // durPaint = 0.00000001; - - // Right column limit indicator - PRectangle rcBeyondEOF = (vsDraw.marginInside) ? rcClient : rcArea; - rcBeyondEOF.left = static_cast(vsDraw.textStart); - rcBeyondEOF.right = rcBeyondEOF.right - ((vsDraw.marginInside) ? vsDraw.rightMarginWidth : 0); - rcBeyondEOF.top = static_cast((model.cs.LinesDisplayed() - model.TopLineOfMain()) * vsDraw.lineHeight); - if (rcBeyondEOF.top < rcBeyondEOF.bottom) { - surfaceWindow->FillRectangle(rcBeyondEOF, vsDraw.styles[STYLE_DEFAULT].back); - if (vsDraw.edgeState == EDGE_LINE) { - int edgeX = static_cast(vsDraw.theEdge.column * vsDraw.spaceWidth); - rcBeyondEOF.left = static_cast(edgeX + xStart); - rcBeyondEOF.right = rcBeyondEOF.left + 1; - surfaceWindow->FillRectangle(rcBeyondEOF, vsDraw.theEdge.colour); - } else if (vsDraw.edgeState == EDGE_MULTILINE) { - for (size_t edge = 0; edge < vsDraw.theMultiEdge.size(); edge++) { - if (vsDraw.theMultiEdge[edge].column >= 0) { - int edgeX = static_cast(vsDraw.theMultiEdge[edge].column * vsDraw.spaceWidth); - rcBeyondEOF.left = static_cast(edgeX + xStart); - rcBeyondEOF.right = rcBeyondEOF.left + 1; - surfaceWindow->FillRectangle(rcBeyondEOF, vsDraw.theMultiEdge[edge].colour); - } - } - } - } - //Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset); - - //Platform::DebugPrintf( - //"Layout:%9.6g Paint:%9.6g Ratio:%9.6g Copy:%9.6g Total:%9.6g\n", - //durLayout, durPaint, durLayout / durPaint, durCopy, etWhole.Duration()); - } -} - -void EditView::FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, PRectangle rcArea, int subLine) { - int eolInSelection = 0; - int alpha = SC_ALPHA_NOALPHA; - if (!hideSelection) { - int posAfterLineEnd = model.pdoc->LineStart(line + 1); - eolInSelection = (subLine == (ll->lines - 1)) ? model.sel.InSelectionForEOL(posAfterLineEnd) : 0; - alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha; - } - - ColourOptional background = vsDraw.Background(model.pdoc->GetMark(line), model.caret.active, ll->containsCaret); - - if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) { - surface->FillRectangle(rcArea, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection)); - } else { - if (background.isSet) { - surface->FillRectangle(rcArea, background); - } else if (vsDraw.styles[ll->styles[ll->numCharsInLine]].eolFilled) { - surface->FillRectangle(rcArea, vsDraw.styles[ll->styles[ll->numCharsInLine]].back); - } else { - surface->FillRectangle(rcArea, vsDraw.styles[STYLE_DEFAULT].back); - } - if (eolInSelection && vsDraw.selEOLFilled && vsDraw.selColours.back.isSet && (line < model.pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) { - SimpleAlphaRectangle(surface, rcArea, SelectionBackground(vsDraw, eolInSelection == 1, model.primarySelection), alpha); - } - } -} - -// Space (3 space characters) between line numbers and text when printing. -#define lineNumberPrintSpace " " - -static ColourDesired InvertedLight(ColourDesired orig) { - unsigned int r = orig.GetRed(); - unsigned int g = orig.GetGreen(); - unsigned int b = orig.GetBlue(); - unsigned int l = (r + g + b) / 3; // There is a better calculation for this that matches human eye - unsigned int il = 0xff - l; - if (l == 0) - return ColourDesired(0xff, 0xff, 0xff); - r = r * il / l; - g = g * il / l; - b = b * il / l; - return ColourDesired(Platform::Minimum(r, 0xff), Platform::Minimum(g, 0xff), Platform::Minimum(b, 0xff)); -} - -long EditView::FormatRange(bool draw, Sci_RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure, - const EditModel &model, const ViewStyle &vs) { - // Can't use measurements cached for screen - posCache.Clear(); - - ViewStyle vsPrint(vs); - vsPrint.technology = SC_TECHNOLOGY_DEFAULT; - - // Modify the view style for printing as do not normally want any of the transient features to be printed - // Printing supports only the line number margin. - int lineNumberIndex = -1; - for (size_t margin = 0; margin < vs.ms.size(); margin++) { - if ((vsPrint.ms[margin].style == SC_MARGIN_NUMBER) && (vsPrint.ms[margin].width > 0)) { - lineNumberIndex = static_cast(margin); - } else { - vsPrint.ms[margin].width = 0; - } - } - vsPrint.fixedColumnWidth = 0; - vsPrint.zoomLevel = printParameters.magnification; - // Don't show indentation guides - // If this ever gets changed, cached pixmap would need to be recreated if technology != SC_TECHNOLOGY_DEFAULT - vsPrint.viewIndentationGuides = ivNone; - // Don't show the selection when printing - vsPrint.selColours.back.isSet = false; - vsPrint.selColours.fore.isSet = false; - vsPrint.selAlpha = SC_ALPHA_NOALPHA; - vsPrint.selAdditionalAlpha = SC_ALPHA_NOALPHA; - vsPrint.whitespaceColours.back.isSet = false; - vsPrint.whitespaceColours.fore.isSet = false; - vsPrint.showCaretLineBackground = false; - vsPrint.alwaysShowCaretLineBackground = false; - // Don't highlight matching braces using indicators - vsPrint.braceHighlightIndicatorSet = false; - vsPrint.braceBadLightIndicatorSet = false; - - // Set colours for printing according to users settings - for (size_t sty = 0; sty < vsPrint.styles.size(); sty++) { - if (printParameters.colourMode == SC_PRINT_INVERTLIGHT) { - vsPrint.styles[sty].fore = InvertedLight(vsPrint.styles[sty].fore); - vsPrint.styles[sty].back = InvertedLight(vsPrint.styles[sty].back); - } else if (printParameters.colourMode == SC_PRINT_BLACKONWHITE) { - vsPrint.styles[sty].fore = ColourDesired(0, 0, 0); - vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); - } else if (printParameters.colourMode == SC_PRINT_COLOURONWHITE) { - vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); - } else if (printParameters.colourMode == SC_PRINT_COLOURONWHITEDEFAULTBG) { - if (sty <= STYLE_DEFAULT) { - vsPrint.styles[sty].back = ColourDesired(0xff, 0xff, 0xff); - } - } - } - // White background for the line numbers - vsPrint.styles[STYLE_LINENUMBER].back = ColourDesired(0xff, 0xff, 0xff); - - // Printing uses different margins, so reset screen margins - vsPrint.leftMarginWidth = 0; - vsPrint.rightMarginWidth = 0; - - vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars); - // Determining width must happen after fonts have been realised in Refresh - int lineNumberWidth = 0; - if (lineNumberIndex >= 0) { - lineNumberWidth = static_cast(surfaceMeasure->WidthText(vsPrint.styles[STYLE_LINENUMBER].font, - "99999" lineNumberPrintSpace, 5 + static_cast(strlen(lineNumberPrintSpace)))); - vsPrint.ms[lineNumberIndex].width = lineNumberWidth; - vsPrint.Refresh(*surfaceMeasure, model.pdoc->tabInChars); // Recalculate fixedColumnWidth - } - - int linePrintStart = model.pdoc->LineFromPosition(static_cast(pfr->chrg.cpMin)); - int linePrintLast = linePrintStart + (pfr->rc.bottom - pfr->rc.top) / vsPrint.lineHeight - 1; - if (linePrintLast < linePrintStart) - linePrintLast = linePrintStart; - int linePrintMax = model.pdoc->LineFromPosition(static_cast(pfr->chrg.cpMax)); - if (linePrintLast > linePrintMax) - linePrintLast = linePrintMax; - //Platform::DebugPrintf("Formatting lines=[%0d,%0d,%0d] top=%0d bottom=%0d line=%0d %0d\n", - // linePrintStart, linePrintLast, linePrintMax, pfr->rc.top, pfr->rc.bottom, vsPrint.lineHeight, - // surfaceMeasure->Height(vsPrint.styles[STYLE_LINENUMBER].font)); - int endPosPrint = model.pdoc->Length(); - if (linePrintLast < model.pdoc->LinesTotal()) - endPosPrint = model.pdoc->LineStart(linePrintLast + 1); - - // Ensure we are styled to where we are formatting. - model.pdoc->EnsureStyledTo(endPosPrint); - - int xStart = vsPrint.fixedColumnWidth + pfr->rc.left; - int ypos = pfr->rc.top; - - int lineDoc = linePrintStart; - - int nPrintPos = static_cast(pfr->chrg.cpMin); - int visibleLine = 0; - int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth; - if (printParameters.wrapState == eWrapNone) - widthPrint = LineLayout::wrapWidthInfinite; - - while (lineDoc <= linePrintLast && ypos < pfr->rc.bottom) { - - // When printing, the hdc and hdcTarget may be the same, so - // changing the state of surfaceMeasure may change the underlying - // state of surface. Therefore, any cached state is discarded before - // using each surface. - surfaceMeasure->FlushCachedState(); - - // Copy this line and its styles from the document into local arrays - // and determine the x position at which each character starts. - LineLayout ll(model.pdoc->LineStart(lineDoc + 1) - model.pdoc->LineStart(lineDoc) + 1); - LayoutLine(model, lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint); - - ll.containsCaret = false; - - PRectangle rcLine = PRectangle::FromInts( - pfr->rc.left, - ypos, - pfr->rc.right - 1, - ypos + vsPrint.lineHeight); - - // When document line is wrapped over multiple display lines, find where - // to start printing from to ensure a particular position is on the first - // line of the page. - if (visibleLine == 0) { - int startWithinLine = nPrintPos - model.pdoc->LineStart(lineDoc); - for (int iwl = 0; iwl < ll.lines - 1; iwl++) { - if (ll.LineStart(iwl) <= startWithinLine && ll.LineStart(iwl + 1) >= startWithinLine) { - visibleLine = -iwl; - } - } - - if (ll.lines > 1 && startWithinLine >= ll.LineStart(ll.lines - 1)) { - visibleLine = -(ll.lines - 1); - } - } - - if (draw && lineNumberWidth && - (ypos + vsPrint.lineHeight <= pfr->rc.bottom) && - (visibleLine >= 0)) { - char number[100]; - sprintf(number, "%d" lineNumberPrintSpace, lineDoc + 1); - PRectangle rcNumber = rcLine; - rcNumber.right = rcNumber.left + lineNumberWidth; - // Right justify - rcNumber.left = rcNumber.right - surfaceMeasure->WidthText( - vsPrint.styles[STYLE_LINENUMBER].font, number, static_cast(strlen(number))); - surface->FlushCachedState(); - surface->DrawTextNoClip(rcNumber, vsPrint.styles[STYLE_LINENUMBER].font, - static_cast(ypos + vsPrint.maxAscent), number, static_cast(strlen(number)), - vsPrint.styles[STYLE_LINENUMBER].fore, - vsPrint.styles[STYLE_LINENUMBER].back); - } - - // Draw the line - surface->FlushCachedState(); - - for (int iwl = 0; iwl < ll.lines; iwl++) { - if (ypos + vsPrint.lineHeight <= pfr->rc.bottom) { - if (visibleLine >= 0) { - if (draw) { - rcLine.top = static_cast(ypos); - rcLine.bottom = static_cast(ypos + vsPrint.lineHeight); - DrawLine(surface, model, vsPrint, &ll, lineDoc, visibleLine, xStart, rcLine, iwl, drawAll); - } - ypos += vsPrint.lineHeight; - } - visibleLine++; - if (iwl == ll.lines - 1) - nPrintPos = model.pdoc->LineStart(lineDoc + 1); - else - nPrintPos += ll.LineStart(iwl + 1) - ll.LineStart(iwl); - } - } - - ++lineDoc; - } - - // Clear cache so measurements are not used for screen - posCache.Clear(); - - return nPrintPos; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/EditView.h b/qrenderdoc/3rdparty/scintilla/src/EditView.h deleted file mode 100644 index 8551daa3b..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/EditView.h +++ /dev/null @@ -1,180 +0,0 @@ -// Scintilla source code edit control -/** @file EditView.h - ** Defines the appearance of the main text area of the editor window. - **/ -// Copyright 1998-2014 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef EDITVIEW_H -#define EDITVIEW_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -struct PrintParameters { - int magnification; - int colourMode; - WrapMode wrapState; - PrintParameters(); -}; - -/** -* The view may be drawn in separate phases. -*/ -enum DrawPhase { - drawBack = 0x1, - drawIndicatorsBack = 0x2, - drawText = 0x4, - drawIndentationGuides = 0x8, - drawIndicatorsFore = 0x10, - drawSelectionTranslucent = 0x20, - drawLineTranslucent = 0x40, - drawFoldLines = 0x80, - drawCarets = 0x100, - drawAll = 0x1FF -}; - -bool ValidStyledText(const ViewStyle &vs, size_t styleOffset, const StyledText &st); -int WidestLineWidth(Surface *surface, const ViewStyle &vs, int styleOffset, const StyledText &st); -void DrawTextNoClipPhase(Surface *surface, PRectangle rc, const Style &style, XYPOSITION ybase, - const char *s, int len, DrawPhase phase); -void DrawStyledText(Surface *surface, const ViewStyle &vs, int styleOffset, PRectangle rcText, - const StyledText &st, size_t start, size_t length, DrawPhase phase); - -typedef void (*DrawTabArrowFn)(Surface *surface, PRectangle rcTab, int ymid); - -/** -* EditView draws the main text area. -*/ -class EditView { -public: - PrintParameters printParameters; - PerLine *ldTabstops; - int tabWidthMinimumPixels; - - bool hideSelection; - bool drawOverstrikeCaret; - - /** In bufferedDraw mode, graphics operations are drawn to a pixmap and then copied to - * the screen. This avoids flashing but is about 30% slower. */ - bool bufferedDraw; - /** In phasesTwo mode, drawing is performed in two phases, first the background - * and then the foreground. This avoids chopping off characters that overlap the next run. - * In multiPhaseDraw mode, drawing is performed in multiple phases with each phase drawing - * one feature over the whole drawing area, instead of within one line. This allows text to - * overlap from one line to the next. */ - enum PhasesDraw { phasesOne, phasesTwo, phasesMultiple }; - PhasesDraw phasesDraw; - - int lineWidthMaxSeen; - - bool additionalCaretsBlink; - bool additionalCaretsVisible; - - bool imeCaretBlockOverride; - - Surface *pixmapLine; - Surface *pixmapIndentGuide; - Surface *pixmapIndentGuideHighlight; - - LineLayoutCache llc; - PositionCache posCache; - - int tabArrowHeight; // draw arrow heads this many pixels above/below line midpoint - /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native - * DrawTabArrow function for drawing tab characters. Allow those platforms to - * override it instead of creating a new method in the Surface class that - * existing platforms must implement as empty. */ - DrawTabArrowFn customDrawTabArrow; - DrawWrapMarkerFn customDrawWrapMarker; - - EditView(); - virtual ~EditView(); - - bool SetTwoPhaseDraw(bool twoPhaseDraw); - bool SetPhasesDraw(int phases); - bool LinesOverlap() const; - - void ClearAllTabstops(); - XYPOSITION NextTabstopPos(int line, XYPOSITION x, XYPOSITION tabWidth) const; - bool ClearTabstops(int line); - bool AddTabstop(int line, int x); - int GetNextTabstop(int line, int x) const; - void LinesAddedOrRemoved(int lineOfPos, int linesAdded); - - void DropGraphics(bool freeObjects); - void AllocateGraphics(const ViewStyle &vsDraw); - void RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw); - - LineLayout *RetrieveLineLayout(int lineNumber, const EditModel &model); - void LayoutLine(const EditModel &model, int line, Surface *surface, const ViewStyle &vstyle, - LineLayout *ll, int width = LineLayout::wrapWidthInfinite); - - Point LocationFromPosition(Surface *surface, const EditModel &model, SelectionPosition pos, int topLine, - const ViewStyle &vs, PointEnd pe); - Range RangeDisplayLine(Surface *surface, const EditModel &model, int lineVisible, const ViewStyle &vs); - SelectionPosition SPositionFromLocation(Surface *surface, const EditModel &model, PointDocument pt, bool canReturnInvalid, - bool charPosition, bool virtualSpace, const ViewStyle &vs); - SelectionPosition SPositionFromLineX(Surface *surface, const EditModel &model, int lineDoc, int x, const ViewStyle &vs); - int DisplayFromPosition(Surface *surface, const EditModel &model, int pos, const ViewStyle &vs); - int StartEndDisplayLine(Surface *surface, const EditModel &model, int pos, bool start, const ViewStyle &vs); - - void DrawIndentGuide(Surface *surface, int lineVisible, int lineHeight, int start, PRectangle rcSegment, bool highlight); - void DrawEOL(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, - int line, int lineEnd, int xStart, int subLine, XYACCUMULATOR subLineStart, - ColourOptional background); - void DrawFoldDisplayText(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int xStart, PRectangle rcLine, int subLine, XYACCUMULATOR subLineStart, DrawPhase phase); - void DrawAnnotation(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int xStart, PRectangle rcLine, int subLine, DrawPhase phase); - void DrawCarets(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, int line, - int xStart, PRectangle rcLine, int subLine) const; - void DrawBackground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, PRectangle rcLine, - Range lineRange, int posLineStart, int xStart, - int subLine, ColourOptional background) const; - void DrawForeground(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, int lineVisible, - PRectangle rcLine, Range lineRange, int posLineStart, int xStart, - int subLine, ColourOptional background); - void DrawIndentGuidesOverEmpty(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, int lineVisible, PRectangle rcLine, int xStart, int subLine); - void DrawLine(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, int line, - int lineVisible, int xStart, PRectangle rcLine, int subLine, DrawPhase phase); - void PaintText(Surface *surfaceWindow, const EditModel &model, PRectangle rcArea, PRectangle rcClient, - const ViewStyle &vsDraw); - void FillLineRemainder(Surface *surface, const EditModel &model, const ViewStyle &vsDraw, const LineLayout *ll, - int line, PRectangle rcArea, int subLine); - long FormatRange(bool draw, Sci_RangeToFormat *pfr, Surface *surface, Surface *surfaceMeasure, - const EditModel &model, const ViewStyle &vs); -}; - -/** -* Convenience class to ensure LineLayout objects are always disposed. -*/ -class AutoLineLayout { - LineLayoutCache &llc; - LineLayout *ll; - AutoLineLayout &operator=(const AutoLineLayout &); -public: - AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {} - ~AutoLineLayout() { - llc.Dispose(ll); - ll = 0; - } - LineLayout *operator->() const { - return ll; - } - operator LineLayout *() const { - return ll; - } - void Set(LineLayout *ll_) { - llc.Dispose(ll); - ll = ll_; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Editor.cxx b/qrenderdoc/3rdparty/scintilla/src/Editor.cxx deleted file mode 100644 index 8e4ebf18a..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Editor.cxx +++ /dev/null @@ -1,8154 +0,0 @@ -// Scintilla source code edit control -/** @file Editor.cxx - ** Main code for the edit control. - **/ -// Copyright 1998-2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "StringCopy.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "PerLine.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "UniConversion.h" -#include "Selection.h" -#include "PositionCache.h" -#include "EditModel.h" -#include "MarginView.h" -#include "EditView.h" -#include "Editor.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -/* - return whether this modification represents an operation that - may reasonably be deferred (not done now OR [possibly] at all) -*/ -static bool CanDeferToLastStep(const DocModification &mh) { - if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) - return true; // CAN skip - if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) - return false; // MUST do - if (mh.modificationType & SC_MULTISTEPUNDOREDO) - return true; // CAN skip - return false; // PRESUMABLY must do -} - -static bool CanEliminate(const DocModification &mh) { - return - (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0; -} - -/* - return whether this modification represents the FINAL step - in a [possibly lengthy] multi-step Undo/Redo sequence -*/ -static bool IsLastStep(const DocModification &mh) { - return - (mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0 - && (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0 - && (mh.modificationType & SC_LASTSTEPINUNDOREDO) != 0 - && (mh.modificationType & SC_MULTILINEUNDOREDO) != 0; -} - -Timer::Timer() : - ticking(false), ticksToWait(0), tickerID(0) {} - -Idler::Idler() : - state(false), idlerID(0) {} - -static inline bool IsAllSpacesOrTabs(const char *s, unsigned int len) { - for (unsigned int i = 0; i < len; i++) { - // This is safe because IsSpaceOrTab() will return false for null terminators - if (!IsSpaceOrTab(s[i])) - return false; - } - return true; -} - -Editor::Editor() { - ctrlID = 0; - - stylesValid = false; - technology = SC_TECHNOLOGY_DEFAULT; - scaleRGBAImage = 100.0f; - - cursorMode = SC_CURSORNORMAL; - - hasFocus = false; - errorStatus = 0; - mouseDownCaptures = true; - mouseWheelCaptures = true; - - lastClickTime = 0; - doubleClickCloseThreshold = Point(3, 3); - dwellDelay = SC_TIME_FOREVER; - ticksToDwell = SC_TIME_FOREVER; - dwelling = false; - ptMouseLast.x = 0; - ptMouseLast.y = 0; - inDragDrop = ddNone; - dropWentOutside = false; - posDrop = SelectionPosition(invalidPosition); - hotSpotClickPos = INVALID_POSITION; - selectionType = selChar; - - lastXChosen = 0; - lineAnchorPos = 0; - originalAnchorPos = 0; - wordSelectAnchorStartPos = 0; - wordSelectAnchorEndPos = 0; - wordSelectInitialCaretPos = -1; - - caretXPolicy = CARET_SLOP | CARET_EVEN; - caretXSlop = 50; - - caretYPolicy = CARET_EVEN; - caretYSlop = 0; - - visiblePolicy = 0; - visibleSlop = 0; - - searchAnchor = 0; - - xCaretMargin = 50; - horizontalScrollBarVisible = true; - scrollWidth = 2000; - verticalScrollBarVisible = true; - endAtLastLine = true; - caretSticky = SC_CARETSTICKY_OFF; - marginOptions = SC_MARGINOPTION_NONE; - mouseSelectionRectangularSwitch = false; - multipleSelection = false; - additionalSelectionTyping = false; - multiPasteMode = SC_MULTIPASTE_ONCE; - virtualSpaceOptions = SCVS_NONE; - - targetStart = 0; - targetEnd = 0; - searchFlags = 0; - - topLine = 0; - posTopLine = 0; - - lengthForEncode = -1; - - needUpdateUI = 0; - ContainerNeedsUpdate(SC_UPDATE_CONTENT); - - paintState = notPainting; - paintAbandonedByStyling = false; - paintingAllText = false; - willRedrawAll = false; - idleStyling = SC_IDLESTYLING_NONE; - needIdleStyling = false; - - modEventMask = SC_MODEVENTMASKALL; - - pdoc->AddWatcher(this, 0); - - recordingMacro = false; - foldAutomatic = 0; - - convertPastes = true; - - SetRepresentations(); -} - -Editor::~Editor() { - pdoc->RemoveWatcher(this, 0); - DropGraphics(true); -} - -void Editor::Finalise() { - SetIdle(false); - CancelModes(); -} - -void Editor::SetRepresentations() { - reprs.Clear(); - - // C0 control set - const char *reps[] = { - "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", - "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", - "DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", - "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US" - }; - for (size_t j=0; j < ELEMENTS(reps); j++) { - char c[2] = { static_cast(j), 0 }; - reprs.SetRepresentation(c, reps[j]); - } - - // C1 control set - // As well as Unicode mode, ISO-8859-1 should use these - if (IsUnicodeMode()) { - const char *repsC1[] = { - "PAD", "HOP", "BPH", "NBH", "IND", "NEL", "SSA", "ESA", - "HTS", "HTJ", "VTS", "PLD", "PLU", "RI", "SS2", "SS3", - "DCS", "PU1", "PU2", "STS", "CCH", "MW", "SPA", "EPA", - "SOS", "SGCI", "SCI", "CSI", "ST", "OSC", "PM", "APC" - }; - for (size_t j=0; j < ELEMENTS(repsC1); j++) { - char c1[3] = { '\xc2', static_cast(0x80+j), 0 }; - reprs.SetRepresentation(c1, repsC1[j]); - } - reprs.SetRepresentation("\xe2\x80\xa8", "LS"); - reprs.SetRepresentation("\xe2\x80\xa9", "PS"); - } - - // UTF-8 invalid bytes - if (IsUnicodeMode()) { - for (int k=0x80; k < 0x100; k++) { - char hiByte[2] = { static_cast(k), 0 }; - char hexits[4]; - sprintf(hexits, "x%2X", k); - reprs.SetRepresentation(hiByte, hexits); - } - } -} - -void Editor::DropGraphics(bool freeObjects) { - marginView.DropGraphics(freeObjects); - view.DropGraphics(freeObjects); -} - -void Editor::AllocateGraphics() { - marginView.AllocateGraphics(vs); - view.AllocateGraphics(vs); -} - -void Editor::InvalidateStyleData() { - stylesValid = false; - vs.technology = technology; - DropGraphics(false); - AllocateGraphics(); - view.llc.Invalidate(LineLayout::llInvalid); - view.posCache.Clear(); -} - -void Editor::InvalidateStyleRedraw() { - NeedWrapping(); - InvalidateStyleData(); - Redraw(); -} - -void Editor::RefreshStyleData() { - if (!stylesValid) { - stylesValid = true; - AutoSurface surface(this); - if (surface) { - vs.Refresh(*surface, pdoc->tabInChars); - } - SetScrollBars(); - SetRectangularRange(); - } -} - -Point Editor::GetVisibleOriginInMain() const { - return Point(0,0); -} - -PointDocument Editor::DocumentPointFromView(Point ptView) const { - PointDocument ptDocument(ptView); - if (wMargin.GetID()) { - Point ptOrigin = GetVisibleOriginInMain(); - ptDocument.x += ptOrigin.x; - ptDocument.y += ptOrigin.y; - } else { - ptDocument.x += xOffset; - ptDocument.y += topLine * vs.lineHeight; - } - return ptDocument; -} - -int Editor::TopLineOfMain() const { - if (wMargin.GetID()) - return 0; - else - return topLine; -} - -PRectangle Editor::GetClientRectangle() const { - Window win = wMain; - return win.GetClientPosition(); -} - -PRectangle Editor::GetClientDrawingRectangle() { - return GetClientRectangle(); -} - -PRectangle Editor::GetTextRectangle() const { - PRectangle rc = GetClientRectangle(); - rc.left += vs.textStart; - rc.right -= vs.rightMarginWidth; - return rc; -} - -int Editor::LinesOnScreen() const { - PRectangle rcClient = GetClientRectangle(); - int htClient = static_cast(rcClient.bottom - rcClient.top); - //Platform::DebugPrintf("lines on screen = %d\n", htClient / lineHeight + 1); - return htClient / vs.lineHeight; -} - -int Editor::LinesToScroll() const { - int retVal = LinesOnScreen() - 1; - if (retVal < 1) - return 1; - else - return retVal; -} - -int Editor::MaxScrollPos() const { - //Platform::DebugPrintf("Lines %d screen = %d maxScroll = %d\n", - //LinesTotal(), LinesOnScreen(), LinesTotal() - LinesOnScreen() + 1); - int retVal = cs.LinesDisplayed(); - if (endAtLastLine) { - retVal -= LinesOnScreen(); - } else { - retVal--; - } - if (retVal < 0) { - return 0; - } else { - return retVal; - } -} - -SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const { - if (sp.Position() < 0) { - return SelectionPosition(0); - } else if (sp.Position() > pdoc->Length()) { - return SelectionPosition(pdoc->Length()); - } else { - // If not at end of line then set offset to 0 - if (!pdoc->IsLineEndPosition(sp.Position())) - sp.SetVirtualSpace(0); - return sp; - } -} - -Point Editor::LocationFromPosition(SelectionPosition pos, PointEnd pe) { - RefreshStyleData(); - AutoSurface surface(this); - return view.LocationFromPosition(surface, *this, pos, topLine, vs, pe); -} - -Point Editor::LocationFromPosition(int pos, PointEnd pe) { - return LocationFromPosition(SelectionPosition(pos), pe); -} - -int Editor::XFromPosition(int pos) { - Point pt = LocationFromPosition(pos); - return static_cast(pt.x) - vs.textStart + xOffset; -} - -int Editor::XFromPosition(SelectionPosition sp) { - Point pt = LocationFromPosition(sp); - return static_cast(pt.x) - vs.textStart + xOffset; -} - -SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace) { - RefreshStyleData(); - AutoSurface surface(this); - - if (canReturnInvalid) { - PRectangle rcClient = GetTextRectangle(); - // May be in scroll view coordinates so translate back to main view - Point ptOrigin = GetVisibleOriginInMain(); - rcClient.Move(-ptOrigin.x, -ptOrigin.y); - if (!rcClient.Contains(pt)) - return SelectionPosition(INVALID_POSITION); - if (pt.x < vs.textStart) - return SelectionPosition(INVALID_POSITION); - if (pt.y < 0) - return SelectionPosition(INVALID_POSITION); - } - PointDocument ptdoc = DocumentPointFromView(pt); - return view.SPositionFromLocation(surface, *this, ptdoc, canReturnInvalid, charPosition, virtualSpace, vs); -} - -int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) { - return SPositionFromLocation(pt, canReturnInvalid, charPosition, false).Position(); -} - -/** -* Find the document position corresponding to an x coordinate on a particular document line. -* Ensure is between whole characters when document is in multi-byte or UTF-8 mode. -* This method is used for rectangular selections and does not work on wrapped lines. -*/ -SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) { - RefreshStyleData(); - if (lineDoc >= pdoc->LinesTotal()) - return SelectionPosition(pdoc->Length()); - //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine); - AutoSurface surface(this); - return view.SPositionFromLineX(surface, *this, lineDoc, x, vs); -} - -int Editor::PositionFromLineX(int lineDoc, int x) { - return SPositionFromLineX(lineDoc, x).Position(); -} - -int Editor::LineFromLocation(Point pt) const { - return cs.DocFromDisplay(static_cast(pt.y) / vs.lineHeight + topLine); -} - -void Editor::SetTopLine(int topLineNew) { - if ((topLine != topLineNew) && (topLineNew >= 0)) { - topLine = topLineNew; - ContainerNeedsUpdate(SC_UPDATE_V_SCROLL); - } - posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine)); -} - -/** - * If painting then abandon the painting because a wider redraw is needed. - * @return true if calling code should stop drawing. - */ -bool Editor::AbandonPaint() { - if ((paintState == painting) && !paintingAllText) { - paintState = paintAbandoned; - } - return paintState == paintAbandoned; -} - -void Editor::RedrawRect(PRectangle rc) { - //Platform::DebugPrintf("Redraw %0d,%0d - %0d,%0d\n", rc.left, rc.top, rc.right, rc.bottom); - - // Clip the redraw rectangle into the client area - PRectangle rcClient = GetClientRectangle(); - if (rc.top < rcClient.top) - rc.top = rcClient.top; - if (rc.bottom > rcClient.bottom) - rc.bottom = rcClient.bottom; - if (rc.left < rcClient.left) - rc.left = rcClient.left; - if (rc.right > rcClient.right) - rc.right = rcClient.right; - - if ((rc.bottom > rc.top) && (rc.right > rc.left)) { - wMain.InvalidateRectangle(rc); - } -} - -void Editor::DiscardOverdraw() { - // Overridden on platforms that may draw outside visible area. -} - -void Editor::Redraw() { - //Platform::DebugPrintf("Redraw all\n"); - PRectangle rcClient = GetClientRectangle(); - wMain.InvalidateRectangle(rcClient); - if (wMargin.GetID()) - wMargin.InvalidateAll(); - //wMain.InvalidateAll(); -} - -void Editor::RedrawSelMargin(int line, bool allAfter) { - const bool markersInText = vs.maskInLine || vs.maskDrawInText; - if (!wMargin.GetID() || markersInText) { // May affect text area so may need to abandon and retry - if (AbandonPaint()) { - return; - } - } - if (wMargin.GetID() && markersInText) { - Redraw(); - return; - } - PRectangle rcMarkers = GetClientRectangle(); - if (!markersInText) { - // Normal case: just draw the margin - rcMarkers.right = rcMarkers.left + vs.fixedColumnWidth; - } - if (line != -1) { - PRectangle rcLine = RectangleFromRange(Range(pdoc->LineStart(line)), 0); - - // Inflate line rectangle if there are image markers with height larger than line height - if (vs.largestMarkerHeight > vs.lineHeight) { - int delta = (vs.largestMarkerHeight - vs.lineHeight + 1) / 2; - rcLine.top -= delta; - rcLine.bottom += delta; - if (rcLine.top < rcMarkers.top) - rcLine.top = rcMarkers.top; - if (rcLine.bottom > rcMarkers.bottom) - rcLine.bottom = rcMarkers.bottom; - } - - rcMarkers.top = rcLine.top; - if (!allAfter) - rcMarkers.bottom = rcLine.bottom; - if (rcMarkers.Empty()) - return; - } - if (wMargin.GetID()) { - Point ptOrigin = GetVisibleOriginInMain(); - rcMarkers.Move(-ptOrigin.x, -ptOrigin.y); - wMargin.InvalidateRectangle(rcMarkers); - } else { - wMain.InvalidateRectangle(rcMarkers); - } -} - -PRectangle Editor::RectangleFromRange(Range r, int overlap) { - const int minLine = cs.DisplayFromDoc(pdoc->LineFromPosition(r.First())); - const int maxLine = cs.DisplayLastFromDoc(pdoc->LineFromPosition(r.Last())); - const PRectangle rcClientDrawing = GetClientDrawingRectangle(); - PRectangle rc; - const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0; - rc.left = static_cast(vs.textStart - leftTextOverlap); - rc.top = static_cast((minLine - TopLineOfMain()) * vs.lineHeight - overlap); - if (rc.top < rcClientDrawing.top) - rc.top = rcClientDrawing.top; - // Extend to right of prepared area if any to prevent artifacts from caret line highlight - rc.right = rcClientDrawing.right; - rc.bottom = static_cast((maxLine - TopLineOfMain() + 1) * vs.lineHeight + overlap); - - return rc; -} - -void Editor::InvalidateRange(int start, int end) { - RedrawRect(RectangleFromRange(Range(start, end), view.LinesOverlap() ? vs.lineOverlap : 0)); -} - -int Editor::CurrentPosition() const { - return sel.MainCaret(); -} - -bool Editor::SelectionEmpty() const { - return sel.Empty(); -} - -SelectionPosition Editor::SelectionStart() { - return sel.RangeMain().Start(); -} - -SelectionPosition Editor::SelectionEnd() { - return sel.RangeMain().End(); -} - -void Editor::SetRectangularRange() { - if (sel.IsRectangular()) { - int xAnchor = XFromPosition(sel.Rectangular().anchor); - int xCaret = XFromPosition(sel.Rectangular().caret); - if (sel.selType == Selection::selThin) { - xCaret = xAnchor; - } - int lineAnchorRect = pdoc->LineFromPosition(sel.Rectangular().anchor.Position()); - int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position()); - int increment = (lineCaret > lineAnchorRect) ? 1 : -1; - for (int line=lineAnchorRect; line != lineCaret+increment; line += increment) { - SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor)); - if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0) - range.ClearVirtualSpace(); - if (line == lineAnchorRect) - sel.SetSelection(range); - else - sel.AddSelectionWithoutTrim(range); - } - } -} - -void Editor::ThinRectangularRange() { - if (sel.IsRectangular()) { - sel.selType = Selection::selThin; - if (sel.Rectangular().caret < sel.Rectangular().anchor) { - sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).caret, sel.Range(0).anchor); - } else { - sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).anchor, sel.Range(0).caret); - } - SetRectangularRange(); - } -} - -void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection) { - if (sel.Count() > 1 || !(sel.RangeMain().anchor == newMain.anchor) || sel.IsRectangular()) { - invalidateWholeSelection = true; - } - int firstAffected = Platform::Minimum(sel.RangeMain().Start().Position(), newMain.Start().Position()); - // +1 for lastAffected ensures caret repainted - int lastAffected = Platform::Maximum(newMain.caret.Position()+1, newMain.anchor.Position()); - lastAffected = Platform::Maximum(lastAffected, sel.RangeMain().End().Position()); - if (invalidateWholeSelection) { - for (size_t r=0; rLineFromPosition(currentPos_.Position()); - /* For Line selection - ensure the anchor and caret are always - at the beginning and end of the region lines. */ - if (sel.selType == Selection::selLines) { - if (currentPos_ > anchor_) { - anchor_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(anchor_.Position()))); - currentPos_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(currentPos_.Position()))); - } else { - currentPos_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(currentPos_.Position()))); - anchor_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(anchor_.Position()))); - } - } - SelectionRange rangeNew(currentPos_, anchor_); - if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) { - InvalidateSelection(rangeNew); - } - sel.RangeMain() = rangeNew; - SetRectangularRange(); - ClaimSelection(); - SetHoverIndicatorPosition(sel.MainCaret()); - - if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { - RedrawSelMargin(); - } - QueueIdleWork(WorkNeeded::workUpdateUI); -} - -void Editor::SetSelection(int currentPos_, int anchor_) { - SetSelection(SelectionPosition(currentPos_), SelectionPosition(anchor_)); -} - -// Just move the caret on the main selection -void Editor::SetSelection(SelectionPosition currentPos_) { - currentPos_ = ClampPositionIntoDocument(currentPos_); - int currentLine = pdoc->LineFromPosition(currentPos_.Position()); - if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) { - InvalidateSelection(SelectionRange(currentPos_)); - } - if (sel.IsRectangular()) { - sel.Rectangular() = - SelectionRange(SelectionPosition(currentPos_), sel.Rectangular().anchor); - SetRectangularRange(); - } else { - sel.RangeMain() = - SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor); - } - ClaimSelection(); - SetHoverIndicatorPosition(sel.MainCaret()); - - if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { - RedrawSelMargin(); - } - QueueIdleWork(WorkNeeded::workUpdateUI); -} - -void Editor::SetSelection(int currentPos_) { - SetSelection(SelectionPosition(currentPos_)); -} - -void Editor::SetEmptySelection(SelectionPosition currentPos_) { - int currentLine = pdoc->LineFromPosition(currentPos_.Position()); - SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_)); - if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) { - InvalidateSelection(rangeNew); - } - sel.Clear(); - sel.RangeMain() = rangeNew; - SetRectangularRange(); - ClaimSelection(); - SetHoverIndicatorPosition(sel.MainCaret()); - - if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { - RedrawSelMargin(); - } - QueueIdleWork(WorkNeeded::workUpdateUI); -} - -void Editor::SetEmptySelection(int currentPos_) { - SetEmptySelection(SelectionPosition(currentPos_)); -} - -void Editor::MultipleSelectAdd(AddNumber addNumber) { - if (SelectionEmpty() || !multipleSelection) { - // Select word at caret - const int startWord = pdoc->ExtendWordSelect(sel.MainCaret(), -1, true); - const int endWord = pdoc->ExtendWordSelect(startWord, 1, true); - TrimAndSetSelection(endWord, startWord); - - } else { - - if (!pdoc->HasCaseFolder()) - pdoc->SetCaseFolder(CaseFolderForEncoding()); - - const Range rangeMainSelection(sel.RangeMain().Start().Position(), sel.RangeMain().End().Position()); - const std::string selectedText = RangeText(rangeMainSelection.start, rangeMainSelection.end); - - const Range rangeTarget(targetStart, targetEnd); - std::vector searchRanges; - // Search should be over the target range excluding the current selection so - // may need to search 2 ranges, after the selection then before the selection. - if (rangeTarget.Overlaps(rangeMainSelection)) { - // Common case is that the selection is completely within the target but - // may also have overlap at start or end. - if (rangeMainSelection.end < rangeTarget.end) - searchRanges.push_back(Range(rangeMainSelection.end, rangeTarget.end)); - if (rangeTarget.start < rangeMainSelection.start) - searchRanges.push_back(Range(rangeTarget.start, rangeMainSelection.start)); - } else { - // No overlap - searchRanges.push_back(rangeTarget); - } - - for (std::vector::const_iterator it = searchRanges.begin(); it != searchRanges.end(); ++it) { - int searchStart = it->start; - const int searchEnd = it->end; - for (;;) { - int lengthFound = static_cast(selectedText.length()); - int pos = static_cast(pdoc->FindText(searchStart, searchEnd, - selectedText.c_str(), searchFlags, &lengthFound)); - if (pos >= 0) { - sel.AddSelection(SelectionRange(pos + lengthFound, pos)); - ScrollRange(sel.RangeMain()); - Redraw(); - if (addNumber == addOne) - return; - searchStart = pos + lengthFound; - } else { - break; - } - } - } - } -} - -bool Editor::RangeContainsProtected(int start, int end) const { - if (vs.ProtectionActive()) { - if (start > end) { - int t = start; - start = end; - end = t; - } - for (int pos = start; pos < end; pos++) { - if (vs.styles[pdoc->StyleIndexAt(pos)].IsProtected()) - return true; - } - } - return false; -} - -bool Editor::SelectionContainsProtected() { - for (size_t r=0; rMovePositionOutsideChar(pos.Position(), moveDir, checkLineEnd); - if (posMoved != pos.Position()) - pos.SetPosition(posMoved); - if (vs.ProtectionActive()) { - if (moveDir > 0) { - if ((pos.Position() > 0) && vs.styles[pdoc->StyleIndexAt(pos.Position() - 1)].IsProtected()) { - while ((pos.Position() < pdoc->Length()) && - (vs.styles[pdoc->StyleIndexAt(pos.Position())].IsProtected())) - pos.Add(1); - } - } else if (moveDir < 0) { - if (vs.styles[pdoc->StyleIndexAt(pos.Position())].IsProtected()) { - while ((pos.Position() > 0) && - (vs.styles[pdoc->StyleIndexAt(pos.Position() - 1)].IsProtected())) - pos.Add(-1); - } - } - } - return pos; -} - -void Editor::MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, bool ensureVisible) { - const int currentLine = pdoc->LineFromPosition(newPos.Position()); - if (ensureVisible) { - // In case in need of wrapping to ensure DisplayFromDoc works. - if (currentLine >= wrapPending.start) - WrapLines(wsAll); - XYScrollPosition newXY = XYScrollToMakeVisible( - SelectionRange(posDrag.IsValid() ? posDrag : newPos), xysDefault); - if (previousPos.IsValid() && (newXY.xOffset == xOffset)) { - // simple vertical scroll then invalidate - ScrollTo(newXY.topLine); - InvalidateSelection(SelectionRange(previousPos), true); - } else { - SetXYScroll(newXY); - } - } - - ShowCaretAtCurrentPosition(); - NotifyCaretMove(); - - ClaimSelection(); - SetHoverIndicatorPosition(sel.MainCaret()); - QueueIdleWork(WorkNeeded::workUpdateUI); - - if (marginView.highlightDelimiter.NeedsDrawing(currentLine)) { - RedrawSelMargin(); - } -} - -void Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) { - const SelectionPosition spCaret = ((sel.Count() == 1) && sel.Empty()) ? - sel.Last() : SelectionPosition(INVALID_POSITION); - - int delta = newPos.Position() - sel.MainCaret(); - newPos = ClampPositionIntoDocument(newPos); - newPos = MovePositionOutsideChar(newPos, delta); - if (!multipleSelection && sel.IsRectangular() && (selt == Selection::selStream)) { - // Can't turn into multiple selection so clear additional selections - InvalidateSelection(SelectionRange(newPos), true); - sel.DropAdditionalRanges(); - } - if (!sel.IsRectangular() && (selt == Selection::selRectangle)) { - // Switching to rectangular - InvalidateSelection(sel.RangeMain(), false); - SelectionRange rangeMain = sel.RangeMain(); - sel.Clear(); - sel.Rectangular() = rangeMain; - } - if (selt != Selection::noSel) { - sel.selType = selt; - } - if (selt != Selection::noSel || sel.MoveExtends()) { - SetSelection(newPos); - } else { - SetEmptySelection(newPos); - } - - MovedCaret(newPos, spCaret, ensureVisible); -} - -void Editor::MovePositionTo(int newPos, Selection::selTypes selt, bool ensureVisible) { - MovePositionTo(SelectionPosition(newPos), selt, ensureVisible); -} - -SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveDir) { - pos = ClampPositionIntoDocument(pos); - pos = MovePositionOutsideChar(pos, moveDir); - int lineDoc = pdoc->LineFromPosition(pos.Position()); - if (cs.GetVisible(lineDoc)) { - return pos; - } else { - int lineDisplay = cs.DisplayFromDoc(lineDoc); - if (moveDir > 0) { - // lineDisplay is already line before fold as lines in fold use display line of line after fold - lineDisplay = Platform::Clamp(lineDisplay, 0, cs.LinesDisplayed()); - return SelectionPosition(pdoc->LineStart(cs.DocFromDisplay(lineDisplay))); - } else { - lineDisplay = Platform::Clamp(lineDisplay - 1, 0, cs.LinesDisplayed()); - return SelectionPosition(pdoc->LineEnd(cs.DocFromDisplay(lineDisplay))); - } - } -} - -SelectionPosition Editor::MovePositionSoVisible(int pos, int moveDir) { - return MovePositionSoVisible(SelectionPosition(pos), moveDir); -} - -Point Editor::PointMainCaret() { - return LocationFromPosition(sel.Range(sel.Main()).caret); -} - -/** - * Choose the x position that the caret will try to stick to - * as it moves up and down. - */ -void Editor::SetLastXChosen() { - Point pt = PointMainCaret(); - lastXChosen = static_cast(pt.x) + xOffset; -} - -void Editor::ScrollTo(int line, bool moveThumb) { - int topLineNew = Platform::Clamp(line, 0, MaxScrollPos()); - if (topLineNew != topLine) { - // Try to optimise small scrolls -#ifndef UNDER_CE - int linesToMove = topLine - topLineNew; - bool performBlit = (abs(linesToMove) <= 10) && (paintState == notPainting); - willRedrawAll = !performBlit; -#endif - SetTopLine(topLineNew); - // Optimize by styling the view as this will invalidate any needed area - // which could abort the initial paint if discovered later. - StyleAreaBounded(GetClientRectangle(), true); -#ifndef UNDER_CE - // Perform redraw rather than scroll if many lines would be redrawn anyway. - if (performBlit) { - ScrollText(linesToMove); - } else { - Redraw(); - } - willRedrawAll = false; -#else - Redraw(); -#endif - if (moveThumb) { - SetVerticalScrollPos(); - } - } -} - -void Editor::ScrollText(int /* linesToMove */) { - //Platform::DebugPrintf("Editor::ScrollText %d\n", linesToMove); - Redraw(); -} - -void Editor::HorizontalScrollTo(int xPos) { - //Platform::DebugPrintf("HorizontalScroll %d\n", xPos); - if (xPos < 0) - xPos = 0; - if (!Wrapping() && (xOffset != xPos)) { - xOffset = xPos; - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); - SetHorizontalScrollPos(); - RedrawRect(GetClientRectangle()); - } -} - -void Editor::VerticalCentreCaret() { - int lineDoc = pdoc->LineFromPosition(sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret()); - int lineDisplay = cs.DisplayFromDoc(lineDoc); - int newTop = lineDisplay - (LinesOnScreen() / 2); - if (topLine != newTop) { - SetTopLine(newTop > 0 ? newTop : 0); - RedrawRect(GetClientRectangle()); - } -} - -// Avoid 64 bit compiler warnings. -// Scintilla does not support text buffers larger than 2**31 -static int istrlen(const char *s) { - return static_cast(s ? strlen(s) : 0); -} - -void Editor::MoveSelectedLines(int lineDelta) { - - // if selection doesn't start at the beginning of the line, set the new start - int selectionStart = SelectionStart().Position(); - int startLine = pdoc->LineFromPosition(selectionStart); - int beginningOfStartLine = pdoc->LineStart(startLine); - selectionStart = beginningOfStartLine; - - // if selection doesn't end at the beginning of a line greater than that of the start, - // then set it at the beginning of the next one - int selectionEnd = SelectionEnd().Position(); - int endLine = pdoc->LineFromPosition(selectionEnd); - int beginningOfEndLine = pdoc->LineStart(endLine); - bool appendEol = false; - if (selectionEnd > beginningOfEndLine - || selectionStart == selectionEnd) { - selectionEnd = pdoc->LineStart(endLine + 1); - appendEol = (selectionEnd == pdoc->Length() && pdoc->LineFromPosition(selectionEnd) == endLine); - } - - // if there's nowhere for the selection to move - // (i.e. at the beginning going up or at the end going down), - // stop it right there! - if ((selectionStart == 0 && lineDelta < 0) - || (selectionEnd == pdoc->Length() && lineDelta > 0) - || selectionStart == selectionEnd) { - return; - } - - UndoGroup ug(pdoc); - - if (lineDelta > 0 && selectionEnd == pdoc->LineStart(pdoc->LinesTotal() - 1)) { - SetSelection(pdoc->MovePositionOutsideChar(selectionEnd - 1, -1), selectionEnd); - ClearSelection(); - selectionEnd = CurrentPosition(); - } - SetSelection(selectionStart, selectionEnd); - - SelectionText selectedText; - CopySelectionRange(&selectedText); - - int selectionLength = SelectionRange(selectionStart, selectionEnd).Length(); - Point currentLocation = LocationFromPosition(CurrentPosition()); - int currentLine = LineFromLocation(currentLocation); - - if (appendEol) - SetSelection(pdoc->MovePositionOutsideChar(selectionStart - 1, -1), selectionEnd); - ClearSelection(); - - const char *eol = StringFromEOLMode(pdoc->eolMode); - if (currentLine + lineDelta >= pdoc->LinesTotal()) - pdoc->InsertString(pdoc->Length(), eol, istrlen(eol)); - GoToLine(currentLine + lineDelta); - - selectionLength = pdoc->InsertString(CurrentPosition(), selectedText.Data(), selectionLength); - if (appendEol) { - const int lengthInserted = pdoc->InsertString(CurrentPosition() + selectionLength, eol, istrlen(eol)); - selectionLength += lengthInserted; - } - SetSelection(CurrentPosition(), CurrentPosition() + selectionLength); -} - -void Editor::MoveSelectedLinesUp() { - MoveSelectedLines(-1); -} - -void Editor::MoveSelectedLinesDown() { - MoveSelectedLines(1); -} - -void Editor::MoveCaretInsideView(bool ensureVisible) { - PRectangle rcClient = GetTextRectangle(); - Point pt = PointMainCaret(); - if (pt.y < rcClient.top) { - MovePositionTo(SPositionFromLocation( - Point::FromInts(lastXChosen - xOffset, static_cast(rcClient.top)), - false, false, UserVirtualSpace()), - Selection::noSel, ensureVisible); - } else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) { - int yOfLastLineFullyDisplayed = static_cast(rcClient.top) + (LinesOnScreen() - 1) * vs.lineHeight; - MovePositionTo(SPositionFromLocation( - Point::FromInts(lastXChosen - xOffset, static_cast(rcClient.top) + yOfLastLineFullyDisplayed), - false, false, UserVirtualSpace()), - Selection::noSel, ensureVisible); - } -} - -int Editor::DisplayFromPosition(int pos) { - AutoSurface surface(this); - return view.DisplayFromPosition(surface, *this, pos, vs); -} - -/** - * Ensure the caret is reasonably visible in context. - * -Caret policy in SciTE - -If slop is set, we can define a slop value. -This value defines an unwanted zone (UZ) where the caret is... unwanted. -This zone is defined as a number of pixels near the vertical margins, -and as a number of lines near the horizontal margins. -By keeping the caret away from the edges, it is seen within its context, -so it is likely that the identifier that the caret is on can be completely seen, -and that the current line is seen with some of the lines following it which are -often dependent on that line. - -If strict is set, the policy is enforced... strictly. -The caret is centred on the display if slop is not set, -and cannot go in the UZ if slop is set. - -If jumps is set, the display is moved more energetically -so the caret can move in the same direction longer before the policy is applied again. -'3UZ' notation is used to indicate three time the size of the UZ as a distance to the margin. - -If even is not set, instead of having symmetrical UZs, -the left and bottom UZs are extended up to right and top UZs respectively. -This way, we favour the displaying of useful information: the beginning of lines, -where most code reside, and the lines after the caret, eg. the body of a function. - - | | | | | -slop | strict | jumps | even | Caret can go to the margin | When reaching limit (caret going out of - | | | | | visibility or going into the UZ) display is... ------+--------+-------+------+--------------------------------------------+-------------------------------------------------------------- - 0 | 0 | 0 | 0 | Yes | moved to put caret on top/on right - 0 | 0 | 0 | 1 | Yes | moved by one position - 0 | 0 | 1 | 0 | Yes | moved to put caret on top/on right - 0 | 0 | 1 | 1 | Yes | centred on the caret - 0 | 1 | - | 0 | Caret is always on top/on right of display | - - 0 | 1 | - | 1 | No, caret is always centred | - - 1 | 0 | 0 | 0 | Yes | moved to put caret out of the asymmetrical UZ - 1 | 0 | 0 | 1 | Yes | moved to put caret out of the UZ - 1 | 0 | 1 | 0 | Yes | moved to put caret at 3UZ of the top or right margin - 1 | 0 | 1 | 1 | Yes | moved to put caret at 3UZ of the margin - 1 | 1 | - | 0 | Caret is always at UZ of top/right margin | - - 1 | 1 | 0 | 1 | No, kept out of UZ | moved by one position - 1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin -*/ - -Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options) { - PRectangle rcClient = GetTextRectangle(); - Point pt = LocationFromPosition(range.caret); - Point ptAnchor = LocationFromPosition(range.anchor); - const Point ptOrigin = GetVisibleOriginInMain(); - pt.x += ptOrigin.x; - pt.y += ptOrigin.y; - ptAnchor.x += ptOrigin.x; - ptAnchor.y += ptOrigin.y; - const Point ptBottomCaret(pt.x, pt.y + vs.lineHeight - 1); - - XYScrollPosition newXY(xOffset, topLine); - if (rcClient.Empty()) { - return newXY; - } - - // Vertical positioning - if ((options & xysVertical) && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) { - const int lineCaret = DisplayFromPosition(range.caret.Position()); - const int linesOnScreen = LinesOnScreen(); - const int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2; - const bool bSlop = (caretYPolicy & CARET_SLOP) != 0; - const bool bStrict = (caretYPolicy & CARET_STRICT) != 0; - const bool bJump = (caretYPolicy & CARET_JUMPS) != 0; - const bool bEven = (caretYPolicy & CARET_EVEN) != 0; - - // It should be possible to scroll the window to show the caret, - // but this fails to remove the caret on GTK+ - if (bSlop) { // A margin is defined - int yMoveT, yMoveB; - if (bStrict) { - int yMarginT, yMarginB; - if (!(options & xysUseMargin)) { - // In drag mode, avoid moves - // otherwise, a double click will select several lines. - yMarginT = yMarginB = 0; - } else { - // yMarginT must equal to caretYSlop, with a minimum of 1 and - // a maximum of slightly less than half the heigth of the text area. - yMarginT = Platform::Clamp(caretYSlop, 1, halfScreen); - if (bEven) { - yMarginB = yMarginT; - } else { - yMarginB = linesOnScreen - yMarginT - 1; - } - } - yMoveT = yMarginT; - if (bEven) { - if (bJump) { - yMoveT = Platform::Clamp(caretYSlop * 3, 1, halfScreen); - } - yMoveB = yMoveT; - } else { - yMoveB = linesOnScreen - yMoveT - 1; - } - if (lineCaret < topLine + yMarginT) { - // Caret goes too high - newXY.topLine = lineCaret - yMoveT; - } else if (lineCaret > topLine + linesOnScreen - 1 - yMarginB) { - // Caret goes too low - newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB; - } - } else { // Not strict - yMoveT = bJump ? caretYSlop * 3 : caretYSlop; - yMoveT = Platform::Clamp(yMoveT, 1, halfScreen); - if (bEven) { - yMoveB = yMoveT; - } else { - yMoveB = linesOnScreen - yMoveT - 1; - } - if (lineCaret < topLine) { - // Caret goes too high - newXY.topLine = lineCaret - yMoveT; - } else if (lineCaret > topLine + linesOnScreen - 1) { - // Caret goes too low - newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB; - } - } - } else { // No slop - if (!bStrict && !bJump) { - // Minimal move - if (lineCaret < topLine) { - // Caret goes too high - newXY.topLine = lineCaret; - } else if (lineCaret > topLine + linesOnScreen - 1) { - // Caret goes too low - if (bEven) { - newXY.topLine = lineCaret - linesOnScreen + 1; - } else { - newXY.topLine = lineCaret; - } - } - } else { // Strict or going out of display - if (bEven) { - // Always center caret - newXY.topLine = lineCaret - halfScreen; - } else { - // Always put caret on top of display - newXY.topLine = lineCaret; - } - } - } - if (!(range.caret == range.anchor)) { - const int lineAnchor = DisplayFromPosition(range.anchor.Position()); - if (lineAnchor < lineCaret) { - // Shift up to show anchor or as much of range as possible - newXY.topLine = std::min(newXY.topLine, lineAnchor); - newXY.topLine = std::max(newXY.topLine, lineCaret - LinesOnScreen()); - } else { - // Shift down to show anchor or as much of range as possible - newXY.topLine = std::max(newXY.topLine, lineAnchor - LinesOnScreen()); - newXY.topLine = std::min(newXY.topLine, lineCaret); - } - } - newXY.topLine = Platform::Clamp(newXY.topLine, 0, MaxScrollPos()); - } - - // Horizontal positioning - if ((options & xysHorizontal) && !Wrapping()) { - const int halfScreen = Platform::Maximum(static_cast(rcClient.Width()) - 4, 4) / 2; - const bool bSlop = (caretXPolicy & CARET_SLOP) != 0; - const bool bStrict = (caretXPolicy & CARET_STRICT) != 0; - const bool bJump = (caretXPolicy & CARET_JUMPS) != 0; - const bool bEven = (caretXPolicy & CARET_EVEN) != 0; - - if (bSlop) { // A margin is defined - int xMoveL, xMoveR; - if (bStrict) { - int xMarginL, xMarginR; - if (!(options & xysUseMargin)) { - // In drag mode, avoid moves unless very near of the margin - // otherwise, a simple click will select text. - xMarginL = xMarginR = 2; - } else { - // xMargin must equal to caretXSlop, with a minimum of 2 and - // a maximum of slightly less than half the width of the text area. - xMarginR = Platform::Clamp(caretXSlop, 2, halfScreen); - if (bEven) { - xMarginL = xMarginR; - } else { - xMarginL = static_cast(rcClient.Width()) - xMarginR - 4; - } - } - if (bJump && bEven) { - // Jump is used only in even mode - xMoveL = xMoveR = Platform::Clamp(caretXSlop * 3, 1, halfScreen); - } else { - xMoveL = xMoveR = 0; // Not used, avoid a warning - } - if (pt.x < rcClient.left + xMarginL) { - // Caret is on the left of the display - if (bJump && bEven) { - newXY.xOffset -= xMoveL; - } else { - // Move just enough to allow to display the caret - newXY.xOffset -= static_cast((rcClient.left + xMarginL) - pt.x); - } - } else if (pt.x >= rcClient.right - xMarginR) { - // Caret is on the right of the display - if (bJump && bEven) { - newXY.xOffset += xMoveR; - } else { - // Move just enough to allow to display the caret - newXY.xOffset += static_cast(pt.x - (rcClient.right - xMarginR) + 1); - } - } - } else { // Not strict - xMoveR = bJump ? caretXSlop * 3 : caretXSlop; - xMoveR = Platform::Clamp(xMoveR, 1, halfScreen); - if (bEven) { - xMoveL = xMoveR; - } else { - xMoveL = static_cast(rcClient.Width()) - xMoveR - 4; - } - if (pt.x < rcClient.left) { - // Caret is on the left of the display - newXY.xOffset -= xMoveL; - } else if (pt.x >= rcClient.right) { - // Caret is on the right of the display - newXY.xOffset += xMoveR; - } - } - } else { // No slop - if (bStrict || - (bJump && (pt.x < rcClient.left || pt.x >= rcClient.right))) { - // Strict or going out of display - if (bEven) { - // Center caret - newXY.xOffset += static_cast(pt.x - rcClient.left - halfScreen); - } else { - // Put caret on right - newXY.xOffset += static_cast(pt.x - rcClient.right + 1); - } - } else { - // Move just enough to allow to display the caret - if (pt.x < rcClient.left) { - // Caret is on the left of the display - if (bEven) { - newXY.xOffset -= static_cast(rcClient.left - pt.x); - } else { - newXY.xOffset += static_cast(pt.x - rcClient.right) + 1; - } - } else if (pt.x >= rcClient.right) { - // Caret is on the right of the display - newXY.xOffset += static_cast(pt.x - rcClient.right) + 1; - } - } - } - // In case of a jump (find result) largely out of display, adjust the offset to display the caret - if (pt.x + xOffset < rcClient.left + newXY.xOffset) { - newXY.xOffset = static_cast(pt.x + xOffset - rcClient.left) - 2; - } else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) { - newXY.xOffset = static_cast(pt.x + xOffset - rcClient.right) + 2; - if ((vs.caretStyle == CARETSTYLE_BLOCK) || view.imeCaretBlockOverride) { - // Ensure we can see a good portion of the block caret - newXY.xOffset += static_cast(vs.aveCharWidth); - } - } - if (!(range.caret == range.anchor)) { - if (ptAnchor.x < pt.x) { - // Shift to left to show anchor or as much of range as possible - int maxOffset = static_cast(ptAnchor.x + xOffset - rcClient.left) - 1; - int minOffset = static_cast(pt.x + xOffset - rcClient.right) + 1; - newXY.xOffset = std::min(newXY.xOffset, maxOffset); - newXY.xOffset = std::max(newXY.xOffset, minOffset); - } else { - // Shift to right to show anchor or as much of range as possible - int minOffset = static_cast(ptAnchor.x + xOffset - rcClient.right) + 1; - int maxOffset = static_cast(pt.x + xOffset - rcClient.left) - 1; - newXY.xOffset = std::max(newXY.xOffset, minOffset); - newXY.xOffset = std::min(newXY.xOffset, maxOffset); - } - } - if (newXY.xOffset < 0) { - newXY.xOffset = 0; - } - } - - return newXY; -} - -void Editor::SetXYScroll(XYScrollPosition newXY) { - if ((newXY.topLine != topLine) || (newXY.xOffset != xOffset)) { - if (newXY.topLine != topLine) { - SetTopLine(newXY.topLine); - SetVerticalScrollPos(); - } - if (newXY.xOffset != xOffset) { - xOffset = newXY.xOffset; - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); - if (newXY.xOffset > 0) { - PRectangle rcText = GetTextRectangle(); - if (horizontalScrollBarVisible && - rcText.Width() + xOffset > scrollWidth) { - scrollWidth = xOffset + static_cast(rcText.Width()); - SetScrollBars(); - } - } - SetHorizontalScrollPos(); - } - Redraw(); - UpdateSystemCaret(); - } -} - -void Editor::ScrollRange(SelectionRange range) { - SetXYScroll(XYScrollToMakeVisible(range, xysDefault)); -} - -void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) { - SetXYScroll(XYScrollToMakeVisible(SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret), - static_cast((useMargin?xysUseMargin:0)|(vert?xysVertical:0)|(horiz?xysHorizontal:0)))); -} - -void Editor::ShowCaretAtCurrentPosition() { - if (hasFocus) { - caret.active = true; - caret.on = true; - if (FineTickerAvailable()) { - FineTickerCancel(tickCaret); - if (caret.period > 0) - FineTickerStart(tickCaret, caret.period, caret.period/10); - } else { - SetTicking(true); - } - } else { - caret.active = false; - caret.on = false; - if (FineTickerAvailable()) { - FineTickerCancel(tickCaret); - } - } - InvalidateCaret(); -} - -void Editor::DropCaret() { - caret.active = false; - if (FineTickerAvailable()) { - FineTickerCancel(tickCaret); - } - InvalidateCaret(); -} - -void Editor::CaretSetPeriod(int period) { - if (caret.period != period) { - caret.period = period; - caret.on = true; - if (FineTickerAvailable()) { - FineTickerCancel(tickCaret); - if ((caret.active) && (caret.period > 0)) - FineTickerStart(tickCaret, caret.period, caret.period/10); - } - InvalidateCaret(); - } -} - -void Editor::InvalidateCaret() { - if (posDrag.IsValid()) { - InvalidateRange(posDrag.Position(), posDrag.Position() + 1); - } else { - for (size_t r=0; rlines; - } - return cs.SetHeight(lineToWrap, linesWrapped + - (vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0)); -} - -// Perform wrapping for a subset of the lines needing wrapping. -// wsAll: wrap all lines which need wrapping in this single call -// wsVisible: wrap currently visible lines -// wsIdle: wrap one page + 100 lines -// Return true if wrapping occurred. -bool Editor::WrapLines(enum wrapScope ws) { - int goodTopLine = topLine; - bool wrapOccurred = false; - if (!Wrapping()) { - if (wrapWidth != LineLayout::wrapWidthInfinite) { - wrapWidth = LineLayout::wrapWidthInfinite; - for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) { - cs.SetHeight(lineDoc, 1 + - (vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0)); - } - wrapOccurred = true; - } - wrapPending.Reset(); - - } else if (wrapPending.NeedsWrap()) { - wrapPending.start = std::min(wrapPending.start, pdoc->LinesTotal()); - if (!SetIdle(true)) { - // Idle processing not supported so full wrap required. - ws = wsAll; - } - // Decide where to start wrapping - int lineToWrap = wrapPending.start; - int lineToWrapEnd = std::min(wrapPending.end, pdoc->LinesTotal()); - const int lineDocTop = cs.DocFromDisplay(topLine); - const int subLineTop = topLine - cs.DisplayFromDoc(lineDocTop); - if (ws == wsVisible) { - lineToWrap = Platform::Clamp(lineDocTop-5, wrapPending.start, pdoc->LinesTotal()); - // Priority wrap to just after visible area. - // Since wrapping could reduce display lines, treat each - // as taking only one display line. - lineToWrapEnd = lineDocTop; - int lines = LinesOnScreen() + 1; - while ((lineToWrapEnd < cs.LinesInDoc()) && (lines>0)) { - if (cs.GetVisible(lineToWrapEnd)) - lines--; - lineToWrapEnd++; - } - // .. and if the paint window is outside pending wraps - if ((lineToWrap > wrapPending.end) || (lineToWrapEnd < wrapPending.start)) { - // Currently visible text does not need wrapping - return false; - } - } else if (ws == wsIdle) { - lineToWrapEnd = lineToWrap + LinesOnScreen() + 100; - } - const int lineEndNeedWrap = std::min(wrapPending.end, pdoc->LinesTotal()); - lineToWrapEnd = std::min(lineToWrapEnd, lineEndNeedWrap); - - // Ensure all lines being wrapped are styled. - pdoc->EnsureStyledTo(pdoc->LineStart(lineToWrapEnd)); - - if (lineToWrap < lineToWrapEnd) { - - PRectangle rcTextArea = GetClientRectangle(); - rcTextArea.left = static_cast(vs.textStart); - rcTextArea.right -= vs.rightMarginWidth; - wrapWidth = static_cast(rcTextArea.Width()); - RefreshStyleData(); - AutoSurface surface(this); - if (surface) { -//Platform::DebugPrintf("Wraplines: scope=%0d need=%0d..%0d perform=%0d..%0d\n", ws, wrapPending.start, wrapPending.end, lineToWrap, lineToWrapEnd); - - while (lineToWrap < lineToWrapEnd) { - if (WrapOneLine(surface, lineToWrap)) { - wrapOccurred = true; - } - wrapPending.Wrapped(lineToWrap); - lineToWrap++; - } - - goodTopLine = cs.DisplayFromDoc(lineDocTop) + std::min(subLineTop, cs.GetHeight(lineDocTop)-1); - } - } - - // If wrapping is done, bring it to resting position - if (wrapPending.start >= lineEndNeedWrap) { - wrapPending.Reset(); - } - } - - if (wrapOccurred) { - SetScrollBars(); - SetTopLine(Platform::Clamp(goodTopLine, 0, MaxScrollPos())); - SetVerticalScrollPos(); - } - - return wrapOccurred; -} - -void Editor::LinesJoin() { - if (!RangeContainsProtected(targetStart, targetEnd)) { - UndoGroup ug(pdoc); - bool prevNonWS = true; - for (int pos = targetStart; pos < targetEnd; pos++) { - if (pdoc->IsPositionInLineEnd(pos)) { - targetEnd -= pdoc->LenChar(pos); - pdoc->DelChar(pos); - if (prevNonWS) { - // Ensure at least one space separating previous lines - const int lengthInserted = pdoc->InsertString(pos, " ", 1); - targetEnd += lengthInserted; - } - } else { - prevNonWS = pdoc->CharAt(pos) != ' '; - } - } - } -} - -const char *Editor::StringFromEOLMode(int eolMode) { - if (eolMode == SC_EOL_CRLF) { - return "\r\n"; - } else if (eolMode == SC_EOL_CR) { - return "\r"; - } else { - return "\n"; - } -} - -void Editor::LinesSplit(int pixelWidth) { - if (!RangeContainsProtected(targetStart, targetEnd)) { - if (pixelWidth == 0) { - PRectangle rcText = GetTextRectangle(); - pixelWidth = static_cast(rcText.Width()); - } - int lineStart = pdoc->LineFromPosition(targetStart); - int lineEnd = pdoc->LineFromPosition(targetEnd); - const char *eol = StringFromEOLMode(pdoc->eolMode); - UndoGroup ug(pdoc); - for (int line = lineStart; line <= lineEnd; line++) { - AutoSurface surface(this); - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this)); - if (surface && ll) { - unsigned int posLineStart = pdoc->LineStart(line); - view.LayoutLine(*this, line, surface, vs, ll, pixelWidth); - int lengthInsertedTotal = 0; - for (int subLine = 1; subLine < ll->lines; subLine++) { - const int lengthInserted = pdoc->InsertString( - static_cast(posLineStart + lengthInsertedTotal + - ll->LineStart(subLine)), - eol, istrlen(eol)); - targetEnd += lengthInserted; - lengthInsertedTotal += lengthInserted; - } - } - lineEnd = pdoc->LineFromPosition(targetEnd); - } - } -} - -void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) { - if (vs.fixedColumnWidth == 0) - return; - - AllocateGraphics(); - RefreshStyleData(); - RefreshPixMaps(surfWindow); - - // On GTK+ with Ubuntu overlay scroll bars, the surface may have been finished - // at this point. The Initialised call checks for this case and sets the status - // to be bad which avoids crashes in following calls. - if (!surfWindow->Initialised()) { - return; - } - - PRectangle rcMargin = GetClientRectangle(); - Point ptOrigin = GetVisibleOriginInMain(); - rcMargin.Move(0, -ptOrigin.y); - rcMargin.left = 0; - rcMargin.right = static_cast(vs.fixedColumnWidth); - - if (!rc.Intersects(rcMargin)) - return; - - Surface *surface; - if (view.bufferedDraw) { - surface = marginView.pixmapSelMargin; - } else { - surface = surfWindow; - } - - // Clip vertically to paint area to avoid drawing line numbers - if (rcMargin.bottom > rc.bottom) - rcMargin.bottom = rc.bottom; - if (rcMargin.top < rc.top) - rcMargin.top = rc.top; - - marginView.PaintMargin(surface, topLine, rc, rcMargin, *this, vs); - - if (view.bufferedDraw) { - surfWindow->Copy(rcMargin, Point(rcMargin.left, rcMargin.top), *marginView.pixmapSelMargin); - } -} - -void Editor::RefreshPixMaps(Surface *surfaceWindow) { - view.RefreshPixMaps(surfaceWindow, wMain.GetID(), vs); - marginView.RefreshPixMaps(surfaceWindow, wMain.GetID(), vs); - if (view.bufferedDraw) { - PRectangle rcClient = GetClientRectangle(); - if (!view.pixmapLine->Initialised()) { - - view.pixmapLine->InitPixMap(static_cast(rcClient.Width()), vs.lineHeight, - surfaceWindow, wMain.GetID()); - } - if (!marginView.pixmapSelMargin->Initialised()) { - marginView.pixmapSelMargin->InitPixMap(vs.fixedColumnWidth, - static_cast(rcClient.Height()), surfaceWindow, wMain.GetID()); - } - } -} - -void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) { - //Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n", - // paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom); - AllocateGraphics(); - - RefreshStyleData(); - if (paintState == paintAbandoned) - return; // Scroll bars may have changed so need redraw - RefreshPixMaps(surfaceWindow); - - paintAbandonedByStyling = false; - - StyleAreaBounded(rcArea, false); - - PRectangle rcClient = GetClientRectangle(); - //Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n", - // rcClient.left, rcClient.top, rcClient.right, rcClient.bottom); - - if (NotifyUpdateUI()) { - RefreshStyleData(); - RefreshPixMaps(surfaceWindow); - } - - // Wrap the visible lines if needed. - if (WrapLines(wsVisible)) { - // The wrapping process has changed the height of some lines so - // abandon this paint for a complete repaint. - if (AbandonPaint()) { - return; - } - RefreshPixMaps(surfaceWindow); // In case pixmaps invalidated by scrollbar change - } - PLATFORM_ASSERT(marginView.pixmapSelPattern->Initialised()); - - if (!view.bufferedDraw) - surfaceWindow->SetClip(rcArea); - - if (paintState != paintAbandoned) { - if (vs.marginInside) { - PaintSelMargin(surfaceWindow, rcArea); - PRectangle rcRightMargin = rcClient; - rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth; - if (rcArea.Intersects(rcRightMargin)) { - surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back); - } - } else { // Else separate view so separate paint event but leftMargin included to allow overlap - PRectangle rcLeftMargin = rcArea; - rcLeftMargin.left = 0; - rcLeftMargin.right = rcLeftMargin.left + vs.leftMarginWidth; - if (rcArea.Intersects(rcLeftMargin)) { - surfaceWindow->FillRectangle(rcLeftMargin, vs.styles[STYLE_DEFAULT].back); - } - } - } - - if (paintState == paintAbandoned) { - // Either styling or NotifyUpdateUI noticed that painting is needed - // outside the current painting rectangle - //Platform::DebugPrintf("Abandoning paint\n"); - if (Wrapping()) { - if (paintAbandonedByStyling) { - // Styling has spilled over a line end, such as occurs by starting a multiline - // comment. The width of subsequent text may have changed, so rewrap. - NeedWrapping(cs.DocFromDisplay(topLine)); - } - } - return; - } - - view.PaintText(surfaceWindow, *this, rcArea, rcClient, vs); - - if (horizontalScrollBarVisible && trackLineWidth && (view.lineWidthMaxSeen > scrollWidth)) { - if (FineTickerAvailable()) { - scrollWidth = view.lineWidthMaxSeen; - if (!FineTickerRunning(tickWiden)) { - FineTickerStart(tickWiden, 50, 5); - } - } - } - - NotifyPainted(); -} - -// This is mostly copied from the Paint method but with some things omitted -// such as the margin markers, line numbers, selection and caret -// Should be merged back into a combined Draw method. -long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) { - if (!pfr) - return 0; - - AutoSurface surface(pfr->hdc, this, SC_TECHNOLOGY_DEFAULT); - if (!surface) - return 0; - AutoSurface surfaceMeasure(pfr->hdcTarget, this, SC_TECHNOLOGY_DEFAULT); - if (!surfaceMeasure) { - return 0; - } - return view.FormatRange(draw, pfr, surface, surfaceMeasure, *this, vs); -} - -int Editor::TextWidth(int style, const char *text) { - RefreshStyleData(); - AutoSurface surface(this); - if (surface) { - return static_cast(surface->WidthText(vs.styles[style].font, text, istrlen(text))); - } else { - return 1; - } -} - -// Empty method is overridden on GTK+ to show / hide scrollbars -void Editor::ReconfigureScrollBars() {} - -void Editor::SetScrollBars() { - RefreshStyleData(); - - int nMax = MaxScrollPos(); - int nPage = LinesOnScreen(); - bool modified = ModifyScrollBars(nMax + nPage - 1, nPage); - if (modified) { - DwellEnd(true); - } - - // TODO: ensure always showing as many lines as possible - // May not be, if, for example, window made larger - if (topLine > MaxScrollPos()) { - SetTopLine(Platform::Clamp(topLine, 0, MaxScrollPos())); - SetVerticalScrollPos(); - Redraw(); - } - if (modified) { - if (!AbandonPaint()) - Redraw(); - } - //Platform::DebugPrintf("end max = %d page = %d\n", nMax, nPage); -} - -void Editor::ChangeSize() { - DropGraphics(false); - SetScrollBars(); - if (Wrapping()) { - PRectangle rcTextArea = GetClientRectangle(); - rcTextArea.left = static_cast(vs.textStart); - rcTextArea.right -= vs.rightMarginWidth; - if (wrapWidth != rcTextArea.Width()) { - NeedWrapping(); - Redraw(); - } - } -} - -int Editor::RealizeVirtualSpace(int position, unsigned int virtualSpace) { - if (virtualSpace > 0) { - const int line = pdoc->LineFromPosition(position); - const int indent = pdoc->GetLineIndentPosition(line); - if (indent == position) { - return pdoc->SetLineIndentation(line, pdoc->GetLineIndentation(line) + virtualSpace); - } else { - std::string spaceText(virtualSpace, ' '); - const int lengthInserted = pdoc->InsertString(position, spaceText.c_str(), virtualSpace); - position += lengthInserted; - } - } - return position; -} - -SelectionPosition Editor::RealizeVirtualSpace(const SelectionPosition &position) { - // Return the new position with no virtual space - return SelectionPosition(RealizeVirtualSpace(position.Position(), position.VirtualSpace())); -} - -void Editor::AddChar(char ch) { - char s[2]; - s[0] = ch; - s[1] = '\0'; - AddCharUTF(s, 1); -} - -void Editor::FilterSelections() { - if (!additionalSelectionTyping && (sel.Count() > 1)) { - InvalidateWholeSelection(); - sel.DropAdditionalRanges(); - } -} - -static bool cmpSelPtrs(const SelectionRange *a, const SelectionRange *b) { - return *a < *b; -} - -// AddCharUTF inserts an array of bytes which may or may not be in UTF-8. -void Editor::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { - FilterSelections(); - { - UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike); - - // Vector elements point into selection in order to change selection. - std::vector selPtrs; - for (size_t r = 0; r < sel.Count(); r++) { - selPtrs.push_back(&sel.Range(r)); - } - // Order selections by position in document. - std::sort(selPtrs.begin(), selPtrs.end(), cmpSelPtrs); - - // Loop in reverse to avoid disturbing positions of selections yet to be processed. - for (std::vector::reverse_iterator rit = selPtrs.rbegin(); - rit != selPtrs.rend(); ++rit) { - SelectionRange *currentSel = *rit; - if (!RangeContainsProtected(currentSel->Start().Position(), - currentSel->End().Position())) { - int positionInsert = currentSel->Start().Position(); - if (!currentSel->Empty()) { - if (currentSel->Length()) { - pdoc->DeleteChars(positionInsert, currentSel->Length()); - currentSel->ClearVirtualSpace(); - } else { - // Range is all virtual so collapse to start of virtual space - currentSel->MinimizeVirtualSpace(); - } - } else if (inOverstrike) { - if (positionInsert < pdoc->Length()) { - if (!pdoc->IsPositionInLineEnd(positionInsert)) { - pdoc->DelChar(positionInsert); - currentSel->ClearVirtualSpace(); - } - } - } - positionInsert = RealizeVirtualSpace(positionInsert, currentSel->caret.VirtualSpace()); - const int lengthInserted = pdoc->InsertString(positionInsert, s, len); - if (lengthInserted > 0) { - currentSel->caret.SetPosition(positionInsert + lengthInserted); - currentSel->anchor.SetPosition(positionInsert + lengthInserted); - } - currentSel->ClearVirtualSpace(); - // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information - if (Wrapping()) { - AutoSurface surface(this); - if (surface) { - if (WrapOneLine(surface, pdoc->LineFromPosition(positionInsert))) { - SetScrollBars(); - SetVerticalScrollPos(); - Redraw(); - } - } - } - } - } - } - if (Wrapping()) { - SetScrollBars(); - } - ThinRectangularRange(); - // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information - EnsureCaretVisible(); - // Avoid blinking during rapid typing: - ShowCaretAtCurrentPosition(); - if ((caretSticky == SC_CARETSTICKY_OFF) || - ((caretSticky == SC_CARETSTICKY_WHITESPACE) && !IsAllSpacesOrTabs(s, len))) { - SetLastXChosen(); - } - - if (treatAsDBCS) { - NotifyChar((static_cast(s[0]) << 8) | - static_cast(s[1])); - } else if (len > 0) { - int byte = static_cast(s[0]); - if ((byte < 0xC0) || (1 == len)) { - // Handles UTF-8 characters between 0x01 and 0x7F and single byte - // characters when not in UTF-8 mode. - // Also treats \0 and naked trail bytes 0x80 to 0xBF as valid - // characters representing themselves. - } else { - unsigned int utf32[1] = { 0 }; - UTF32FromUTF8(s, len, utf32, ELEMENTS(utf32)); - byte = utf32[0]; - } - NotifyChar(byte); - } - - if (recordingMacro) { - NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(s)); - } -} - -void Editor::ClearBeforeTentativeStart() { - // Make positions for the first composition string. - FilterSelections(); - UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike); - for (size_t r = 0; rDeleteChars(positionInsert, sel.Range(r).Length()); - sel.Range(r).ClearVirtualSpace(); - } else { - // Range is all virtual so collapse to start of virtual space - sel.Range(r).MinimizeVirtualSpace(); - } - } - RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace()); - sel.Range(r).ClearVirtualSpace(); - } - } -} - -void Editor::InsertPaste(const char *text, int len) { - if (multiPasteMode == SC_MULTIPASTE_ONCE) { - SelectionPosition selStart = sel.Start(); - selStart = RealizeVirtualSpace(selStart); - const int lengthInserted = pdoc->InsertString(selStart.Position(), text, len); - if (lengthInserted > 0) { - SetEmptySelection(selStart.Position() + lengthInserted); - } - } else { - // SC_MULTIPASTE_EACH - for (size_t r=0; rDeleteChars(positionInsert, sel.Range(r).Length()); - sel.Range(r).ClearVirtualSpace(); - } else { - // Range is all virtual so collapse to start of virtual space - sel.Range(r).MinimizeVirtualSpace(); - } - } - positionInsert = RealizeVirtualSpace(positionInsert, sel.Range(r).caret.VirtualSpace()); - const int lengthInserted = pdoc->InsertString(positionInsert, text, len); - if (lengthInserted > 0) { - sel.Range(r).caret.SetPosition(positionInsert + lengthInserted); - sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted); - } - sel.Range(r).ClearVirtualSpace(); - } - } - } -} - -void Editor::InsertPasteShape(const char *text, int len, PasteShape shape) { - std::string convertedText; - if (convertPastes) { - // Convert line endings of the paste into our local line-endings mode - convertedText = Document::TransformLineEnds(text, len, pdoc->eolMode); - len = static_cast(convertedText.length()); - text = convertedText.c_str(); - } - if (shape == pasteRectangular) { - PasteRectangular(sel.Start(), text, len); - } else { - if (shape == pasteLine) { - int insertPos = pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())); - int lengthInserted = pdoc->InsertString(insertPos, text, len); - // add the newline if necessary - if ((len > 0) && (text[len - 1] != '\n' && text[len - 1] != '\r')) { - const char *endline = StringFromEOLMode(pdoc->eolMode); - int length = static_cast(strlen(endline)); - lengthInserted += pdoc->InsertString(insertPos + lengthInserted, endline, length); - } - if (sel.MainCaret() == insertPos) { - SetEmptySelection(sel.MainCaret() + lengthInserted); - } - } else { - InsertPaste(text, len); - } - } -} - -void Editor::ClearSelection(bool retainMultipleSelections) { - if (!sel.IsRectangular() && !retainMultipleSelections) - FilterSelections(); - UndoGroup ug(pdoc); - for (size_t r=0; rDeleteChars(sel.Range(r).Start().Position(), - sel.Range(r).Length()); - sel.Range(r) = SelectionRange(sel.Range(r).Start()); - } - } - } - ThinRectangularRange(); - sel.RemoveDuplicates(); - ClaimSelection(); - SetHoverIndicatorPosition(sel.MainCaret()); -} - -void Editor::ClearAll() { - { - UndoGroup ug(pdoc); - if (0 != pdoc->Length()) { - pdoc->DeleteChars(0, pdoc->Length()); - } - if (!pdoc->IsReadOnly()) { - cs.Clear(); - pdoc->AnnotationClearAll(); - pdoc->MarginClearAll(); - } - } - - view.ClearAllTabstops(); - - sel.Clear(); - SetTopLine(0); - SetVerticalScrollPos(); - InvalidateStyleRedraw(); -} - -void Editor::ClearDocumentStyle() { - Decoration *deco = pdoc->decorations.root; - while (deco) { - // Save next in case deco deleted - Decoration *decoNext = deco->next; - if (deco->indicator < INDIC_CONTAINER) { - pdoc->decorations.SetCurrentIndicator(deco->indicator); - pdoc->DecorationFillRange(0, 0, pdoc->Length()); - } - deco = decoNext; - } - pdoc->StartStyling(0, '\377'); - pdoc->SetStyleFor(pdoc->Length(), 0); - cs.ShowAll(); - SetAnnotationHeights(0, pdoc->LinesTotal()); - pdoc->ClearLevels(); -} - -void Editor::CopyAllowLine() { - SelectionText selectedText; - CopySelectionRange(&selectedText, true); - CopyToClipboard(selectedText); -} - -void Editor::Cut() { - pdoc->CheckReadOnly(); - if (!pdoc->IsReadOnly() && !SelectionContainsProtected()) { - Copy(); - ClearSelection(); - } -} - -void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, int len) { - if (pdoc->IsReadOnly() || SelectionContainsProtected()) { - return; - } - sel.Clear(); - sel.RangeMain() = SelectionRange(pos); - int line = pdoc->LineFromPosition(sel.MainCaret()); - UndoGroup ug(pdoc); - sel.RangeMain().caret = RealizeVirtualSpace(sel.RangeMain().caret); - int xInsert = XFromPosition(sel.RangeMain().caret); - bool prevCr = false; - while ((len > 0) && IsEOLChar(ptr[len-1])) - len--; - for (int i = 0; i < len; i++) { - if (IsEOLChar(ptr[i])) { - if ((ptr[i] == '\r') || (!prevCr)) - line++; - if (line >= pdoc->LinesTotal()) { - if (pdoc->eolMode != SC_EOL_LF) - pdoc->InsertString(pdoc->Length(), "\r", 1); - if (pdoc->eolMode != SC_EOL_CR) - pdoc->InsertString(pdoc->Length(), "\n", 1); - } - // Pad the end of lines with spaces if required - sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert)); - if ((XFromPosition(sel.MainCaret()) < xInsert) && (i + 1 < len)) { - while (XFromPosition(sel.MainCaret()) < xInsert) { - assert(pdoc); - const int lengthInserted = pdoc->InsertString(sel.MainCaret(), " ", 1); - sel.RangeMain().caret.Add(lengthInserted); - } - } - prevCr = ptr[i] == '\r'; - } else { - const int lengthInserted = pdoc->InsertString(sel.MainCaret(), ptr + i, 1); - sel.RangeMain().caret.Add(lengthInserted); - prevCr = false; - } - } - SetEmptySelection(pos); -} - -bool Editor::CanPaste() { - return !pdoc->IsReadOnly() && !SelectionContainsProtected(); -} - -void Editor::Clear() { - // If multiple selections, don't delete EOLS - if (sel.Empty()) { - bool singleVirtual = false; - if ((sel.Count() == 1) && - !RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1) && - sel.RangeMain().Start().VirtualSpace()) { - singleVirtual = true; - } - UndoGroup ug(pdoc, (sel.Count() > 1) || singleVirtual); - for (size_t r=0; rIsPositionInLineEnd(sel.Range(r).caret.Position())) { - pdoc->DelChar(sel.Range(r).caret.Position()); - sel.Range(r).ClearVirtualSpace(); - } // else multiple selection so don't eat line ends - } else { - sel.Range(r).ClearVirtualSpace(); - } - } - } else { - ClearSelection(); - } - sel.RemoveDuplicates(); - ShowCaretAtCurrentPosition(); // Avoid blinking -} - -void Editor::SelectAll() { - sel.Clear(); - SetSelection(0, pdoc->Length()); - Redraw(); -} - -void Editor::Undo() { - if (pdoc->CanUndo()) { - InvalidateCaret(); - int newPos = pdoc->Undo(); - if (newPos >= 0) - SetEmptySelection(newPos); - EnsureCaretVisible(); - } -} - -void Editor::Redo() { - if (pdoc->CanRedo()) { - int newPos = pdoc->Redo(); - if (newPos >= 0) - SetEmptySelection(newPos); - EnsureCaretVisible(); - } -} - -void Editor::DelCharBack(bool allowLineStartDeletion) { - RefreshStyleData(); - if (!sel.IsRectangular()) - FilterSelections(); - if (sel.IsRectangular()) - allowLineStartDeletion = false; - UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty()); - if (sel.Empty()) { - for (size_t r=0; rLineFromPosition(sel.Range(r).caret.Position()); - if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != sel.Range(r).caret.Position())) { - if (pdoc->GetColumn(sel.Range(r).caret.Position()) <= pdoc->GetLineIndentation(lineCurrentPos) && - pdoc->GetColumn(sel.Range(r).caret.Position()) > 0 && pdoc->backspaceUnindents) { - UndoGroup ugInner(pdoc, !ug.Needed()); - int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = pdoc->IndentSize(); - int indentationChange = indentation % indentationStep; - if (indentationChange == 0) - indentationChange = indentationStep; - const int posSelect = pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationChange); - // SetEmptySelection - sel.Range(r) = SelectionRange(posSelect); - } else { - pdoc->DelCharBack(sel.Range(r).caret.Position()); - } - } - } - } else { - sel.Range(r).ClearVirtualSpace(); - } - } - ThinRectangularRange(); - } else { - ClearSelection(); - } - sel.RemoveDuplicates(); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); - // Avoid blinking during rapid typing: - ShowCaretAtCurrentPosition(); -} - -int Editor::ModifierFlags(bool shift, bool ctrl, bool alt, bool meta, bool super) { - return - (shift ? SCI_SHIFT : 0) | - (ctrl ? SCI_CTRL : 0) | - (alt ? SCI_ALT : 0) | - (meta ? SCI_META : 0) | - (super ? SCI_SUPER : 0); -} - -void Editor::NotifyFocus(bool focus) { - SCNotification scn = {}; - scn.nmhdr.code = focus ? SCN_FOCUSIN : SCN_FOCUSOUT; - NotifyParent(scn); -} - -void Editor::SetCtrlID(int identifier) { - ctrlID = identifier; -} - -void Editor::NotifyStyleToNeeded(int endStyleNeeded) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_STYLENEEDED; - scn.position = endStyleNeeded; - NotifyParent(scn); -} - -void Editor::NotifyStyleNeeded(Document *, void *, int endStyleNeeded) { - NotifyStyleToNeeded(endStyleNeeded); -} - -void Editor::NotifyLexerChanged(Document *, void *) { -} - -void Editor::NotifyErrorOccurred(Document *, void *, int status) { - errorStatus = status; -} - -void Editor::NotifyChar(int ch) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_CHARADDED; - scn.ch = ch; - NotifyParent(scn); -} - -void Editor::NotifySavePoint(bool isSavePoint) { - SCNotification scn = {}; - if (isSavePoint) { - scn.nmhdr.code = SCN_SAVEPOINTREACHED; - } else { - scn.nmhdr.code = SCN_SAVEPOINTLEFT; - } - NotifyParent(scn); -} - -void Editor::NotifyModifyAttempt() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_MODIFYATTEMPTRO; - NotifyParent(scn); -} - -void Editor::NotifyDoubleClick(Point pt, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_DOUBLECLICK; - scn.line = LineFromLocation(pt); - scn.position = PositionFromLocation(pt, true); - scn.modifiers = modifiers; - NotifyParent(scn); -} - -void Editor::NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt) { - NotifyDoubleClick(pt, ModifierFlags(shift, ctrl, alt)); -} - -void Editor::NotifyHotSpotDoubleClicked(int position, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTDOUBLECLICK; - scn.position = position; - scn.modifiers = modifiers; - NotifyParent(scn); -} - -void Editor::NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt) { - NotifyHotSpotDoubleClicked(position, ModifierFlags(shift, ctrl, alt)); -} - -void Editor::NotifyHotSpotClicked(int position, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTCLICK; - scn.position = position; - scn.modifiers = modifiers; - NotifyParent(scn); -} - -void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt) { - NotifyHotSpotClicked(position, ModifierFlags(shift, ctrl, alt)); -} - -void Editor::NotifyHotSpotReleaseClick(int position, int modifiers) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK; - scn.position = position; - scn.modifiers = modifiers; - NotifyParent(scn); -} - -void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) { - NotifyHotSpotReleaseClick(position, ModifierFlags(shift, ctrl, alt)); -} - -bool Editor::NotifyUpdateUI() { - if (needUpdateUI) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_UPDATEUI; - scn.updated = needUpdateUI; - NotifyParent(scn); - needUpdateUI = 0; - return true; - } - return false; -} - -void Editor::NotifyPainted() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_PAINTED; - NotifyParent(scn); -} - -void Editor::NotifyIndicatorClick(bool click, int position, int modifiers) { - int mask = pdoc->decorations.AllOnFor(position); - if ((click && mask) || pdoc->decorations.clickNotified) { - SCNotification scn = {}; - pdoc->decorations.clickNotified = click; - scn.nmhdr.code = click ? SCN_INDICATORCLICK : SCN_INDICATORRELEASE; - scn.modifiers = modifiers; - scn.position = position; - NotifyParent(scn); - } -} - -void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt) { - NotifyIndicatorClick(click, position, ModifierFlags(shift, ctrl, alt)); -} - -bool Editor::NotifyMarginClick(Point pt, int modifiers) { - const int marginClicked = vs.MarginFromLocation(pt); - if ((marginClicked >= 0) && vs.ms[marginClicked].sensitive) { - int position = pdoc->LineStart(LineFromLocation(pt)); - if ((vs.ms[marginClicked].mask & SC_MASK_FOLDERS) && (foldAutomatic & SC_AUTOMATICFOLD_CLICK)) { - const bool ctrl = (modifiers & SCI_CTRL) != 0; - const bool shift = (modifiers & SCI_SHIFT) != 0; - int lineClick = pdoc->LineFromPosition(position); - if (shift && ctrl) { - FoldAll(SC_FOLDACTION_TOGGLE); - } else { - int levelClick = pdoc->GetLevel(lineClick); - if (levelClick & SC_FOLDLEVELHEADERFLAG) { - if (shift) { - // Ensure all children visible - FoldExpand(lineClick, SC_FOLDACTION_EXPAND, levelClick); - } else if (ctrl) { - FoldExpand(lineClick, SC_FOLDACTION_TOGGLE, levelClick); - } else { - // Toggle this line - FoldLine(lineClick, SC_FOLDACTION_TOGGLE); - } - } - } - return true; - } - SCNotification scn = {}; - scn.nmhdr.code = SCN_MARGINCLICK; - scn.modifiers = modifiers; - scn.position = position; - scn.margin = marginClicked; - NotifyParent(scn); - return true; - } else { - return false; - } -} - -bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) { - return NotifyMarginClick(pt, ModifierFlags(shift, ctrl, alt)); -} - -bool Editor::NotifyMarginRightClick(Point pt, int modifiers) { - int marginRightClicked = vs.MarginFromLocation(pt); - if ((marginRightClicked >= 0) && vs.ms[marginRightClicked].sensitive) { - int position = pdoc->LineStart(LineFromLocation(pt)); - SCNotification scn = {}; - scn.nmhdr.code = SCN_MARGINRIGHTCLICK; - scn.modifiers = modifiers; - scn.position = position; - scn.margin = marginRightClicked; - NotifyParent(scn); - return true; - } else { - return false; - } -} - -void Editor::NotifyNeedShown(int pos, int len) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_NEEDSHOWN; - scn.position = pos; - scn.length = len; - NotifyParent(scn); -} - -void Editor::NotifyDwelling(Point pt, bool state) { - SCNotification scn = {}; - scn.nmhdr.code = state ? SCN_DWELLSTART : SCN_DWELLEND; - scn.position = PositionFromLocation(pt, true); - scn.x = static_cast(pt.x + vs.ExternalMarginWidth()); - scn.y = static_cast(pt.y); - NotifyParent(scn); -} - -void Editor::NotifyZoom() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_ZOOM; - NotifyParent(scn); -} - -// Notifications from document -void Editor::NotifyModifyAttempt(Document *, void *) { - //Platform::DebugPrintf("** Modify Attempt\n"); - NotifyModifyAttempt(); -} - -void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) { - //Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off"); - NotifySavePoint(atSavePoint); -} - -void Editor::CheckModificationForWrap(DocModification mh) { - if (mh.modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { - view.llc.Invalidate(LineLayout::llCheckTextAndStyle); - int lineDoc = pdoc->LineFromPosition(mh.position); - int lines = Platform::Maximum(0, mh.linesAdded); - if (Wrapping()) { - NeedWrapping(lineDoc, lineDoc + lines + 1); - } - RefreshStyleData(); - // Fix up annotation heights - SetAnnotationHeights(lineDoc, lineDoc + lines + 2); - } -} - -// Move a position so it is still after the same character as before the insertion. -static inline int MovePositionForInsertion(int position, int startInsertion, int length) { - if (position > startInsertion) { - return position + length; - } - return position; -} - -// Move a position so it is still after the same character as before the deletion if that -// character is still present else after the previous surviving character. -static inline int MovePositionForDeletion(int position, int startDeletion, int length) { - if (position > startDeletion) { - int endDeletion = startDeletion + length; - if (position > endDeletion) { - return position - length; - } else { - return startDeletion; - } - } else { - return position; - } -} - -void Editor::NotifyModified(Document *, DocModification mh, void *) { - ContainerNeedsUpdate(SC_UPDATE_CONTENT); - if (paintState == painting) { - CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length)); - } - if (mh.modificationType & SC_MOD_CHANGELINESTATE) { - if (paintState == painting) { - CheckForChangeOutsidePaint( - Range(pdoc->LineStart(mh.line), pdoc->LineStart(mh.line + 1))); - } else { - // Could check that change is before last visible line. - Redraw(); - } - } - if (mh.modificationType & SC_MOD_CHANGETABSTOPS) { - Redraw(); - } - if (mh.modificationType & SC_MOD_LEXERSTATE) { - if (paintState == painting) { - CheckForChangeOutsidePaint( - Range(mh.position, mh.position + mh.length)); - } else { - Redraw(); - } - } - if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) { - if (mh.modificationType & SC_MOD_CHANGESTYLE) { - pdoc->IncrementStyleClock(); - } - if (paintState == notPainting) { - if (mh.position < pdoc->LineStart(topLine)) { - // Styling performed before this view - Redraw(); - } else { - InvalidateRange(mh.position, mh.position + mh.length); - } - } - if (mh.modificationType & SC_MOD_CHANGESTYLE) { - view.llc.Invalidate(LineLayout::llCheckTextAndStyle); - } - } else { - // Move selection and brace highlights - if (mh.modificationType & SC_MOD_INSERTTEXT) { - sel.MovePositions(true, mh.position, mh.length); - braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length); - braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length); - } else if (mh.modificationType & SC_MOD_DELETETEXT) { - sel.MovePositions(false, mh.position, mh.length); - braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length); - braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length); - } - if ((mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) && cs.HiddenLines()) { - // Some lines are hidden so may need shown. - const int lineOfPos = pdoc->LineFromPosition(mh.position); - int endNeedShown = mh.position; - if (mh.modificationType & SC_MOD_BEFOREINSERT) { - if (pdoc->ContainsLineEnd(mh.text, mh.length) && (mh.position != pdoc->LineStart(lineOfPos))) - endNeedShown = pdoc->LineStart(lineOfPos+1); - } else if (mh.modificationType & SC_MOD_BEFOREDELETE) { - // Extend the need shown area over any folded lines - endNeedShown = mh.position + mh.length; - int lineLast = pdoc->LineFromPosition(mh.position+mh.length); - for (int line = lineOfPos; line <= lineLast; line++) { - const int lineMaxSubord = pdoc->GetLastChild(line, -1, -1); - if (lineLast < lineMaxSubord) { - lineLast = lineMaxSubord; - endNeedShown = pdoc->LineEnd(lineLast); - } - } - } - NeedShown(mh.position, endNeedShown - mh.position); - } - if (mh.linesAdded != 0) { - // Update contraction state for inserted and removed lines - // lineOfPos should be calculated in context of state before modification, shouldn't it - int lineOfPos = pdoc->LineFromPosition(mh.position); - if (mh.position > pdoc->LineStart(lineOfPos)) - lineOfPos++; // Affecting subsequent lines - if (mh.linesAdded > 0) { - cs.InsertLines(lineOfPos, mh.linesAdded); - } else { - cs.DeleteLines(lineOfPos, -mh.linesAdded); - } - view.LinesAddedOrRemoved(lineOfPos, mh.linesAdded); - } - if (mh.modificationType & SC_MOD_CHANGEANNOTATION) { - int lineDoc = pdoc->LineFromPosition(mh.position); - if (vs.annotationVisible) { - cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded); - Redraw(); - } - } - CheckModificationForWrap(mh); - if (mh.linesAdded != 0) { - // Avoid scrolling of display if change before current display - if (mh.position < posTopLine && !CanDeferToLastStep(mh)) { - int newTop = Platform::Clamp(topLine + mh.linesAdded, 0, MaxScrollPos()); - if (newTop != topLine) { - SetTopLine(newTop); - SetVerticalScrollPos(); - } - } - - if (paintState == notPainting && !CanDeferToLastStep(mh)) { - QueueIdleWork(WorkNeeded::workStyle, pdoc->Length()); - Redraw(); - } - } else { - if (paintState == notPainting && mh.length && !CanEliminate(mh)) { - QueueIdleWork(WorkNeeded::workStyle, mh.position + mh.length); - InvalidateRange(mh.position, mh.position + mh.length); - } - } - } - - if (mh.linesAdded != 0 && !CanDeferToLastStep(mh)) { - SetScrollBars(); - } - - if ((mh.modificationType & SC_MOD_CHANGEMARKER) || (mh.modificationType & SC_MOD_CHANGEMARGIN)) { - if ((!willRedrawAll) && ((paintState == notPainting) || !PaintContainsMargin())) { - if (mh.modificationType & SC_MOD_CHANGEFOLD) { - // Fold changes can affect the drawing of following lines so redraw whole margin - RedrawSelMargin(marginView.highlightDelimiter.isEnabled ? -1 : mh.line - 1, true); - } else { - RedrawSelMargin(mh.line); - } - } - } - if ((mh.modificationType & SC_MOD_CHANGEFOLD) && (foldAutomatic & SC_AUTOMATICFOLD_CHANGE)) { - FoldChanged(mh.line, mh.foldLevelNow, mh.foldLevelPrev); - } - - // NOW pay the piper WRT "deferred" visual updates - if (IsLastStep(mh)) { - SetScrollBars(); - Redraw(); - } - - // If client wants to see this modification - if (mh.modificationType & modEventMask) { - if ((mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) == 0) { - // Real modification made to text of document. - NotifyChange(); // Send EN_CHANGE - } - - SCNotification scn = {}; - scn.nmhdr.code = SCN_MODIFIED; - scn.position = mh.position; - scn.modificationType = mh.modificationType; - scn.text = mh.text; - scn.length = mh.length; - scn.linesAdded = mh.linesAdded; - scn.line = mh.line; - scn.foldLevelNow = mh.foldLevelNow; - scn.foldLevelPrev = mh.foldLevelPrev; - scn.token = mh.token; - scn.annotationLinesAdded = mh.annotationLinesAdded; - NotifyParent(scn); - } -} - -void Editor::NotifyDeleted(Document *, void *) { - /* Do nothing */ -} - -void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - - // Enumerates all macroable messages - switch (iMessage) { - case SCI_CUT: - case SCI_COPY: - case SCI_PASTE: - case SCI_CLEAR: - case SCI_REPLACESEL: - case SCI_ADDTEXT: - case SCI_INSERTTEXT: - case SCI_APPENDTEXT: - case SCI_CLEARALL: - case SCI_SELECTALL: - case SCI_GOTOLINE: - case SCI_GOTOPOS: - case SCI_SEARCHANCHOR: - case SCI_SEARCHNEXT: - case SCI_SEARCHPREV: - case SCI_LINEDOWN: - case SCI_LINEDOWNEXTEND: - case SCI_PARADOWN: - case SCI_PARADOWNEXTEND: - case SCI_LINEUP: - case SCI_LINEUPEXTEND: - case SCI_PARAUP: - case SCI_PARAUPEXTEND: - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: - case SCI_DOCUMENTSTART: - case SCI_DOCUMENTSTARTEXTEND: - case SCI_DOCUMENTEND: - case SCI_DOCUMENTENDEXTEND: - case SCI_STUTTEREDPAGEUP: - case SCI_STUTTEREDPAGEUPEXTEND: - case SCI_STUTTEREDPAGEDOWN: - case SCI_STUTTEREDPAGEDOWNEXTEND: - case SCI_PAGEUP: - case SCI_PAGEUPEXTEND: - case SCI_PAGEDOWN: - case SCI_PAGEDOWNEXTEND: - case SCI_EDITTOGGLEOVERTYPE: - case SCI_CANCEL: - case SCI_DELETEBACK: - case SCI_TAB: - case SCI_BACKTAB: - case SCI_FORMFEED: - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_DELWORDLEFT: - case SCI_DELWORDRIGHT: - case SCI_DELWORDRIGHTEND: - case SCI_DELLINELEFT: - case SCI_DELLINERIGHT: - case SCI_LINECOPY: - case SCI_LINECUT: - case SCI_LINEDELETE: - case SCI_LINETRANSPOSE: - case SCI_LINEDUPLICATE: - case SCI_LOWERCASE: - case SCI_UPPERCASE: - case SCI_LINESCROLLDOWN: - case SCI_LINESCROLLUP: - case SCI_DELETEBACKNOTLINE: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_SETSELECTIONMODE: - case SCI_LINEDOWNRECTEXTEND: - case SCI_LINEUPRECTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_LINEENDRECTEXTEND: - case SCI_PAGEUPRECTEXTEND: - case SCI_PAGEDOWNRECTEXTEND: - case SCI_SELECTIONDUPLICATE: - case SCI_COPYALLOWLINE: - case SCI_VERTICALCENTRECARET: - case SCI_MOVESELECTEDLINESUP: - case SCI_MOVESELECTEDLINESDOWN: - case SCI_SCROLLTOSTART: - case SCI_SCROLLTOEND: - break; - - // Filter out all others like display changes. Also, newlines are redundant - // with char insert messages. - case SCI_NEWLINE: - default: - // printf("Filtered out %ld of macro recording\n", iMessage); - return; - } - - // Send notification - SCNotification scn = {}; - scn.nmhdr.code = SCN_MACRORECORD; - scn.message = iMessage; - scn.wParam = wParam; - scn.lParam = lParam; - NotifyParent(scn); -} - -// Something has changed that the container should know about -void Editor::ContainerNeedsUpdate(int flags) { - needUpdateUI |= flags; -} - -/** - * Force scroll and keep position relative to top of window. - * - * If stuttered = true and not already at first/last row, move to first/last row of window. - * If stuttered = true and already at first/last row, scroll as normal. - */ -void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) { - int topLineNew; - SelectionPosition newPos; - - int currentLine = pdoc->LineFromPosition(sel.MainCaret()); - int topStutterLine = topLine + caretYSlop; - int bottomStutterLine = - pdoc->LineFromPosition(PositionFromLocation( - Point::FromInts(lastXChosen - xOffset, direction * vs.lineHeight * LinesToScroll()))) - - caretYSlop - 1; - - if (stuttered && (direction < 0 && currentLine > topStutterLine)) { - topLineNew = topLine; - newPos = SPositionFromLocation(Point::FromInts(lastXChosen - xOffset, vs.lineHeight * caretYSlop), - false, false, UserVirtualSpace()); - - } else if (stuttered && (direction > 0 && currentLine < bottomStutterLine)) { - topLineNew = topLine; - newPos = SPositionFromLocation(Point::FromInts(lastXChosen - xOffset, vs.lineHeight * (LinesToScroll() - caretYSlop)), - false, false, UserVirtualSpace()); - - } else { - Point pt = LocationFromPosition(sel.MainCaret()); - - topLineNew = Platform::Clamp( - topLine + direction * LinesToScroll(), 0, MaxScrollPos()); - newPos = SPositionFromLocation( - Point::FromInts(lastXChosen - xOffset, static_cast(pt.y) + direction * (vs.lineHeight * LinesToScroll())), - false, false, UserVirtualSpace()); - } - - if (topLineNew != topLine) { - SetTopLine(topLineNew); - MovePositionTo(newPos, selt); - Redraw(); - SetVerticalScrollPos(); - } else { - MovePositionTo(newPos, selt); - } -} - -void Editor::ChangeCaseOfSelection(int caseMapping) { - UndoGroup ug(pdoc); - for (size_t r=0; r 0) { - std::string sText = RangeText(currentNoVS.Start().Position(), currentNoVS.End().Position()); - - std::string sMapped = CaseMapString(sText, caseMapping); - - if (sMapped != sText) { - size_t firstDifference = 0; - while (sMapped[firstDifference] == sText[firstDifference]) - firstDifference++; - size_t lastDifferenceText = sText.size() - 1; - size_t lastDifferenceMapped = sMapped.size() - 1; - while (sMapped[lastDifferenceMapped] == sText[lastDifferenceText]) { - lastDifferenceText--; - lastDifferenceMapped--; - } - size_t endDifferenceText = sText.size() - 1 - lastDifferenceText; - pdoc->DeleteChars( - static_cast(currentNoVS.Start().Position() + firstDifference), - static_cast(rangeBytes - firstDifference - endDifferenceText)); - const int lengthChange = static_cast(lastDifferenceMapped - firstDifference + 1); - const int lengthInserted = pdoc->InsertString( - static_cast(currentNoVS.Start().Position() + firstDifference), - sMapped.c_str() + firstDifference, - lengthChange); - // Automatic movement changes selection so reset to exactly the same as it was. - int diffSizes = static_cast(sMapped.size() - sText.size()) + lengthInserted - lengthChange; - if (diffSizes != 0) { - if (current.anchor > current.caret) - current.anchor.Add(diffSizes); - else - current.caret.Add(diffSizes); - } - sel.Range(r) = current; - } - } - } -} - -void Editor::LineTranspose() { - int line = pdoc->LineFromPosition(sel.MainCaret()); - if (line > 0) { - UndoGroup ug(pdoc); - - const int startPrevious = pdoc->LineStart(line - 1); - const std::string linePrevious = RangeText(startPrevious, pdoc->LineEnd(line - 1)); - - int startCurrent = pdoc->LineStart(line); - const std::string lineCurrent = RangeText(startCurrent, pdoc->LineEnd(line)); - - pdoc->DeleteChars(startCurrent, static_cast(lineCurrent.length())); - pdoc->DeleteChars(startPrevious, static_cast(linePrevious.length())); - startCurrent -= static_cast(linePrevious.length()); - - startCurrent += pdoc->InsertString(startPrevious, lineCurrent.c_str(), - static_cast(lineCurrent.length())); - pdoc->InsertString(startCurrent, linePrevious.c_str(), - static_cast(linePrevious.length())); - // Move caret to start of current line - MovePositionTo(SelectionPosition(startCurrent)); - } -} - -void Editor::Duplicate(bool forLine) { - if (sel.Empty()) { - forLine = true; - } - UndoGroup ug(pdoc); - const char *eol = ""; - int eolLen = 0; - if (forLine) { - eol = StringFromEOLMode(pdoc->eolMode); - eolLen = istrlen(eol); - } - for (size_t r=0; rLineFromPosition(sel.Range(r).caret.Position()); - start = SelectionPosition(pdoc->LineStart(line)); - end = SelectionPosition(pdoc->LineEnd(line)); - } - std::string text = RangeText(start.Position(), end.Position()); - int lengthInserted = eolLen; - if (forLine) - lengthInserted = pdoc->InsertString(end.Position(), eol, eolLen); - pdoc->InsertString(end.Position() + lengthInserted, text.c_str(), static_cast(text.length())); - } - if (sel.Count() && sel.IsRectangular()) { - SelectionPosition last = sel.Last(); - if (forLine) { - int line = pdoc->LineFromPosition(last.Position()); - last = SelectionPosition(last.Position() + pdoc->LineStart(line+1) - pdoc->LineStart(line)); - } - if (sel.Rectangular().anchor > sel.Rectangular().caret) - sel.Rectangular().anchor = last; - else - sel.Rectangular().caret = last; - SetRectangularRange(); - } -} - -void Editor::CancelModes() { - sel.SetMoveExtends(false); -} - -void Editor::NewLine() { - InvalidateWholeSelection(); - if (sel.IsRectangular() || !additionalSelectionTyping) { - // Remove non-main ranges - sel.DropAdditionalRanges(); - } - - UndoGroup ug(pdoc, !sel.Empty() || (sel.Count() > 1)); - - // Clear each range - if (!sel.Empty()) { - ClearSelection(); - } - - // Insert each line end - size_t countInsertions = 0; - for (size_t r = 0; r < sel.Count(); r++) { - sel.Range(r).ClearVirtualSpace(); - const char *eol = StringFromEOLMode(pdoc->eolMode); - const int positionInsert = sel.Range(r).caret.Position(); - const int insertLength = pdoc->InsertString(positionInsert, eol, istrlen(eol)); - if (insertLength > 0) { - sel.Range(r) = SelectionRange(positionInsert + insertLength); - countInsertions++; - } - } - - // Perform notifications after all the changes as the application may change the - // selections in response to the characters. - for (size_t i = 0; i < countInsertions; i++) { - const char *eol = StringFromEOLMode(pdoc->eolMode); - while (*eol) { - NotifyChar(*eol); - if (recordingMacro) { - char txt[2]; - txt[0] = *eol; - txt[1] = '\0'; - NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast(txt)); - } - eol++; - } - } - - SetLastXChosen(); - SetScrollBars(); - EnsureCaretVisible(); - // Avoid blinking during rapid typing: - ShowCaretAtCurrentPosition(); -} - -SelectionPosition Editor::PositionUpOrDown(SelectionPosition spStart, int direction, int lastX) { - const Point pt = LocationFromPosition(spStart); - int skipLines = 0; - - if (vs.annotationVisible) { - const int lineDoc = pdoc->LineFromPosition(spStart.Position()); - const Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc)); - const int subLine = static_cast(pt.y - ptStartLine.y) / vs.lineHeight; - - if (direction < 0 && subLine == 0) { - const int lineDisplay = cs.DisplayFromDoc(lineDoc); - if (lineDisplay > 0) { - skipLines = pdoc->AnnotationLines(cs.DocFromDisplay(lineDisplay - 1)); - } - } else if (direction > 0 && subLine >= (cs.GetHeight(lineDoc) - 1 - pdoc->AnnotationLines(lineDoc))) { - skipLines = pdoc->AnnotationLines(lineDoc); - } - } - - const int newY = static_cast(pt.y) + (1 + skipLines) * direction * vs.lineHeight; - if (lastX < 0) { - lastX = static_cast(pt.x) + xOffset; - } - SelectionPosition posNew = SPositionFromLocation( - Point::FromInts(lastX - xOffset, newY), false, false, UserVirtualSpace()); - - if (direction < 0) { - // Line wrapping may lead to a location on the same line, so - // seek back if that is the case. - Point ptNew = LocationFromPosition(posNew.Position()); - while ((posNew.Position() > 0) && (pt.y == ptNew.y)) { - posNew.Add(-1); - posNew.SetVirtualSpace(0); - ptNew = LocationFromPosition(posNew.Position()); - } - } else if (direction > 0 && posNew.Position() != pdoc->Length()) { - // There is an equivalent case when moving down which skips - // over a line. - Point ptNew = LocationFromPosition(posNew.Position()); - while ((posNew.Position() > spStart.Position()) && (ptNew.y > newY)) { - posNew.Add(-1); - posNew.SetVirtualSpace(0); - ptNew = LocationFromPosition(posNew.Position()); - } - } - return posNew; -} - -void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) { - SelectionPosition caretToUse = sel.Range(sel.Main()).caret; - if (sel.IsRectangular()) { - if (selt == Selection::noSel) { - caretToUse = (direction > 0) ? sel.Limits().end : sel.Limits().start; - } else { - caretToUse = sel.Rectangular().caret; - } - } - if (selt == Selection::selRectangle) { - const SelectionRange rangeBase = sel.IsRectangular() ? sel.Rectangular() : sel.RangeMain(); - if (!sel.IsRectangular()) { - InvalidateWholeSelection(); - sel.DropAdditionalRanges(); - } - const SelectionPosition posNew = MovePositionSoVisible( - PositionUpOrDown(caretToUse, direction, lastXChosen), direction); - sel.selType = Selection::selRectangle; - sel.Rectangular() = SelectionRange(posNew, rangeBase.anchor); - SetRectangularRange(); - MovedCaret(posNew, caretToUse, true); - } else { - InvalidateWholeSelection(); - if (!additionalSelectionTyping || (sel.IsRectangular())) { - sel.DropAdditionalRanges(); - } - sel.selType = Selection::selStream; - for (size_t r = 0; r < sel.Count(); r++) { - const int lastX = (r == sel.Main()) ? lastXChosen : -1; - const SelectionPosition spCaretNow = sel.Range(r).caret; - const SelectionPosition posNew = MovePositionSoVisible( - PositionUpOrDown(spCaretNow, direction, lastX), direction); - sel.Range(r) = selt == Selection::selStream ? - SelectionRange(posNew, sel.Range(r).anchor) : SelectionRange(posNew); - } - sel.RemoveDuplicates(); - MovedCaret(sel.RangeMain().caret, caretToUse, true); - } -} - -void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) { - int lineDoc, savedPos = sel.MainCaret(); - do { - MovePositionTo(SelectionPosition(direction > 0 ? pdoc->ParaDown(sel.MainCaret()) : pdoc->ParaUp(sel.MainCaret())), selt); - lineDoc = pdoc->LineFromPosition(sel.MainCaret()); - if (direction > 0) { - if (sel.MainCaret() >= pdoc->Length() && !cs.GetVisible(lineDoc)) { - if (selt == Selection::noSel) { - MovePositionTo(SelectionPosition(pdoc->LineEndPosition(savedPos))); - } - break; - } - } - } while (!cs.GetVisible(lineDoc)); -} - -Range Editor::RangeDisplayLine(int lineVisible) { - RefreshStyleData(); - AutoSurface surface(this); - return view.RangeDisplayLine(surface, *this, lineVisible, vs); -} - -int Editor::StartEndDisplayLine(int pos, bool start) { - RefreshStyleData(); - AutoSurface surface(this); - int posRet = view.StartEndDisplayLine(surface, *this, pos, start, vs); - if (posRet == INVALID_POSITION) { - return pos; - } else { - return posRet; - } -} - -namespace { - -unsigned int WithExtends(unsigned int iMessage) { - switch (iMessage) { - case SCI_CHARLEFT: return SCI_CHARLEFTEXTEND; - case SCI_CHARRIGHT: return SCI_CHARRIGHTEXTEND; - - case SCI_WORDLEFT: return SCI_WORDLEFTEXTEND; - case SCI_WORDRIGHT: return SCI_WORDRIGHTEXTEND; - case SCI_WORDLEFTEND: return SCI_WORDLEFTENDEXTEND; - case SCI_WORDRIGHTEND: return SCI_WORDRIGHTENDEXTEND; - case SCI_WORDPARTLEFT: return SCI_WORDPARTLEFTEXTEND; - case SCI_WORDPARTRIGHT: return SCI_WORDPARTRIGHTEXTEND; - - case SCI_HOME: return SCI_HOMEEXTEND; - case SCI_HOMEDISPLAY: return SCI_HOMEDISPLAYEXTEND; - case SCI_HOMEWRAP: return SCI_HOMEWRAPEXTEND; - case SCI_VCHOME: return SCI_VCHOMEEXTEND; - case SCI_VCHOMEDISPLAY: return SCI_VCHOMEDISPLAYEXTEND; - case SCI_VCHOMEWRAP: return SCI_VCHOMEWRAPEXTEND; - - case SCI_LINEEND: return SCI_LINEENDEXTEND; - case SCI_LINEENDDISPLAY: return SCI_LINEENDDISPLAYEXTEND; - case SCI_LINEENDWRAP: return SCI_LINEENDWRAPEXTEND; - - default: return iMessage; - } -} - -int NaturalDirection(unsigned int iMessage) { - switch (iMessage) { - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - // VC_HOME* mostly goes back - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - return -1; - - default: - return 1; - } -} - -bool IsRectExtend(unsigned int iMessage) { - switch (iMessage) { - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_LINEENDRECTEXTEND: - return true; - default: - return false; - } -} - -} - -int Editor::VCHomeDisplayPosition(int position) { - const int homePos = pdoc->VCHomePosition(position); - const int viewLineStart = StartEndDisplayLine(position, true); - if (viewLineStart > homePos) - return viewLineStart; - else - return homePos; -} - -int Editor::VCHomeWrapPosition(int position) { - const int homePos = pdoc->VCHomePosition(position); - const int viewLineStart = StartEndDisplayLine(position, true); - if ((viewLineStart < position) && (viewLineStart > homePos)) - return viewLineStart; - else - return homePos; -} - -int Editor::LineEndWrapPosition(int position) { - const int endPos = StartEndDisplayLine(position, false); - const int realEndPos = pdoc->LineEndPosition(position); - if (endPos > realEndPos // if moved past visible EOLs - || position >= endPos) // if at end of display line already - return realEndPos; - else - return endPos; -} - -int Editor::HorizontalMove(unsigned int iMessage) { - if (sel.MoveExtends()) { - iMessage = WithExtends(iMessage); - } - - if (!multipleSelection && !sel.IsRectangular()) { - // Simplify selection down to 1 - sel.SetSelection(sel.RangeMain()); - } - - // Invalidate each of the current selections - InvalidateWholeSelection(); - - if (IsRectExtend(iMessage)) { - const SelectionRange rangeBase = sel.IsRectangular() ? sel.Rectangular() : sel.RangeMain(); - if (!sel.IsRectangular()) { - sel.DropAdditionalRanges(); - } - // Will change to rectangular if not currently rectangular - SelectionPosition spCaret = rangeBase.caret; - switch (iMessage) { - case SCI_CHARLEFTRECTEXTEND: - if (pdoc->IsLineEndPosition(spCaret.Position()) && spCaret.VirtualSpace()) { - spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); - } else if ((virtualSpaceOptions & SCVS_NOWRAPLINESTART) == 0 || pdoc->GetColumn(spCaret.Position()) > 0) { - spCaret = SelectionPosition(spCaret.Position() - 1); - } - break; - case SCI_CHARRIGHTRECTEXTEND: - if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) && pdoc->IsLineEndPosition(sel.MainCaret())) { - spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); - } else { - spCaret = SelectionPosition(spCaret.Position() + 1); - } - break; - case SCI_HOMERECTEXTEND: - spCaret = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(spCaret.Position()))); - break; - case SCI_VCHOMERECTEXTEND: - spCaret = SelectionPosition(pdoc->VCHomePosition(spCaret.Position())); - break; - case SCI_LINEENDRECTEXTEND: - spCaret = SelectionPosition(pdoc->LineEndPosition(spCaret.Position())); - break; - } - const int directionMove = (spCaret < rangeBase.caret) ? -1 : 1; - spCaret = MovePositionSoVisible(spCaret, directionMove); - sel.selType = Selection::selRectangle; - sel.Rectangular() = SelectionRange(spCaret, rangeBase.anchor); - SetRectangularRange(); - } else if (sel.IsRectangular()) { - // Not a rectangular extension so switch to stream. - const SelectionPosition selAtLimit = - (NaturalDirection(iMessage) > 0) ? sel.Limits().end : sel.Limits().start; - sel.selType = Selection::selStream; - sel.SetSelection(SelectionRange(selAtLimit)); - } else { - if (!additionalSelectionTyping) { - InvalidateWholeSelection(); - sel.DropAdditionalRanges(); - } - for (size_t r = 0; r < sel.Count(); r++) { - const SelectionPosition spCaretNow = sel.Range(r).caret; - SelectionPosition spCaret = spCaretNow; - switch (iMessage) { - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - if (spCaret.VirtualSpace()) { - spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1); - } else if ((virtualSpaceOptions & SCVS_NOWRAPLINESTART) == 0 || pdoc->GetColumn(spCaret.Position()) > 0) { - spCaret = SelectionPosition(spCaret.Position() - 1); - } - break; - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(spCaret.Position())) { - spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1); - } else { - spCaret = SelectionPosition(spCaret.Position() + 1); - } - break; - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - spCaret = SelectionPosition(pdoc->NextWordStart(spCaret.Position(), -1)); - break; - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - spCaret = SelectionPosition(pdoc->NextWordStart(spCaret.Position(), 1)); - break; - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - spCaret = SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), -1)); - break; - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - spCaret = SelectionPosition(pdoc->NextWordEnd(spCaret.Position(), 1)); - break; - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - spCaret = SelectionPosition(pdoc->WordPartLeft(spCaret.Position())); - break; - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - spCaret = SelectionPosition(pdoc->WordPartRight(spCaret.Position())); - break; - case SCI_HOME: - case SCI_HOMEEXTEND: - spCaret = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(spCaret.Position()))); - break; - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - spCaret = SelectionPosition(StartEndDisplayLine(spCaret.Position(), true)); - break; - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - spCaret = MovePositionSoVisible(StartEndDisplayLine(spCaret.Position(), true), -1); - if (spCaretNow <= spCaret) - spCaret = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(spCaret.Position()))); - break; - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - // VCHome alternates between beginning of line and beginning of text so may move back or forwards - spCaret = SelectionPosition(pdoc->VCHomePosition(spCaret.Position())); - break; - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - spCaret = SelectionPosition(VCHomeDisplayPosition(spCaret.Position())); - break; - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - spCaret = SelectionPosition(VCHomeWrapPosition(spCaret.Position())); - break; - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - spCaret = SelectionPosition(pdoc->LineEndPosition(spCaret.Position())); - break; - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - spCaret = SelectionPosition(StartEndDisplayLine(spCaret.Position(), false)); - break; - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: - spCaret = SelectionPosition(LineEndWrapPosition(spCaret.Position())); - break; - - default: - PLATFORM_ASSERT(false); - } - - const int directionMove = (spCaret < spCaretNow) ? -1 : 1; - spCaret = MovePositionSoVisible(spCaret, directionMove); - - // Handle move versus extend, and special behaviour for non-empty left/right - switch (iMessage) { - case SCI_CHARLEFT: - case SCI_CHARRIGHT: - if (sel.Range(r).Empty()) { - sel.Range(r) = SelectionRange(spCaret); - } else { - sel.Range(r) = SelectionRange( - (iMessage == SCI_CHARLEFT) ? sel.Range(r).Start() : sel.Range(r).End()); - } - break; - - case SCI_WORDLEFT: - case SCI_WORDRIGHT: - case SCI_WORDLEFTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTRIGHT: - case SCI_HOME: - case SCI_HOMEDISPLAY: - case SCI_HOMEWRAP: - case SCI_VCHOME: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEWRAP: - case SCI_LINEEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDWRAP: - sel.Range(r) = SelectionRange(spCaret); - break; - - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHTEXTEND: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_HOMEEXTEND: - case SCI_HOMEDISPLAYEXTEND: - case SCI_HOMEWRAPEXTEND: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_VCHOMEWRAPEXTEND: - case SCI_LINEENDEXTEND: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_LINEENDWRAPEXTEND: { - SelectionRange rangeNew = SelectionRange(spCaret, sel.Range(r).anchor); - sel.TrimOtherSelections(r, SelectionRange(rangeNew)); - sel.Range(r) = rangeNew; - } - break; - - default: - PLATFORM_ASSERT(false); - } - } - } - - sel.RemoveDuplicates(); - - MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true); - - // Invalidate the new state of the selection - InvalidateWholeSelection(); - - SetLastXChosen(); - // Need the line moving and so forth from MovePositionTo - return 0; -} - -int Editor::DelWordOrLine(unsigned int iMessage) { - // Virtual space may be realised for SCI_DELWORDRIGHT or SCI_DELWORDRIGHTEND - // which means 2 actions so wrap in an undo group. - - // Rightwards and leftwards deletions differ in treatment of virtual space. - // Clear virtual space for leftwards, realise for rightwards. - const bool leftwards = (iMessage == SCI_DELWORDLEFT) || (iMessage == SCI_DELLINELEFT); - - if (!additionalSelectionTyping) { - InvalidateWholeSelection(); - sel.DropAdditionalRanges(); - } - - UndoGroup ug0(pdoc, (sel.Count() > 1) || !leftwards); - - for (size_t r = 0; r < sel.Count(); r++) { - if (leftwards) { - // Delete to the left so first clear the virtual space. - sel.Range(r).ClearVirtualSpace(); - } else { - // Delete to the right so first realise the virtual space. - sel.Range(r) = SelectionRange( - RealizeVirtualSpace(sel.Range(r).caret)); - } - - Range rangeDelete; - switch (iMessage) { - case SCI_DELWORDLEFT: - rangeDelete = Range( - pdoc->NextWordStart(sel.Range(r).caret.Position(), -1), - sel.Range(r).caret.Position()); - break; - case SCI_DELWORDRIGHT: - rangeDelete = Range( - sel.Range(r).caret.Position(), - pdoc->NextWordStart(sel.Range(r).caret.Position(), 1)); - break; - case SCI_DELWORDRIGHTEND: - rangeDelete = Range( - sel.Range(r).caret.Position(), - pdoc->NextWordEnd(sel.Range(r).caret.Position(), 1)); - break; - case SCI_DELLINELEFT: - rangeDelete = Range( - pdoc->LineStart(pdoc->LineFromPosition(sel.Range(r).caret.Position())), - sel.Range(r).caret.Position()); - break; - case SCI_DELLINERIGHT: - rangeDelete = Range( - sel.Range(r).caret.Position(), - pdoc->LineEnd(pdoc->LineFromPosition(sel.Range(r).caret.Position()))); - break; - } - if (!RangeContainsProtected(rangeDelete.start, rangeDelete.end)) { - pdoc->DeleteChars(rangeDelete.start, rangeDelete.end - rangeDelete.start); - } - } - - // May need something stronger here: can selections overlap at this point? - sel.RemoveDuplicates(); - - MovedCaret(sel.RangeMain().caret, SelectionPosition(INVALID_POSITION), true); - - // Invalidate the new state of the selection - InvalidateWholeSelection(); - - SetLastXChosen(); - return 0; -} - -int Editor::KeyCommand(unsigned int iMessage) { - switch (iMessage) { - case SCI_LINEDOWN: - CursorUpOrDown(1, Selection::noSel); - break; - case SCI_LINEDOWNEXTEND: - CursorUpOrDown(1, Selection::selStream); - break; - case SCI_LINEDOWNRECTEXTEND: - CursorUpOrDown(1, Selection::selRectangle); - break; - case SCI_PARADOWN: - ParaUpOrDown(1, Selection::noSel); - break; - case SCI_PARADOWNEXTEND: - ParaUpOrDown(1, Selection::selStream); - break; - case SCI_LINESCROLLDOWN: - ScrollTo(topLine + 1); - MoveCaretInsideView(false); - break; - case SCI_LINEUP: - CursorUpOrDown(-1, Selection::noSel); - break; - case SCI_LINEUPEXTEND: - CursorUpOrDown(-1, Selection::selStream); - break; - case SCI_LINEUPRECTEXTEND: - CursorUpOrDown(-1, Selection::selRectangle); - break; - case SCI_PARAUP: - ParaUpOrDown(-1, Selection::noSel); - break; - case SCI_PARAUPEXTEND: - ParaUpOrDown(-1, Selection::selStream); - break; - case SCI_LINESCROLLUP: - ScrollTo(topLine - 1); - MoveCaretInsideView(false); - break; - - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - case SCI_LINEENDRECTEXTEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: - return HorizontalMove(iMessage); - - case SCI_DOCUMENTSTART: - MovePositionTo(0); - SetLastXChosen(); - break; - case SCI_DOCUMENTSTARTEXTEND: - MovePositionTo(0, Selection::selStream); - SetLastXChosen(); - break; - case SCI_DOCUMENTEND: - MovePositionTo(pdoc->Length()); - SetLastXChosen(); - break; - case SCI_DOCUMENTENDEXTEND: - MovePositionTo(pdoc->Length(), Selection::selStream); - SetLastXChosen(); - break; - case SCI_STUTTEREDPAGEUP: - PageMove(-1, Selection::noSel, true); - break; - case SCI_STUTTEREDPAGEUPEXTEND: - PageMove(-1, Selection::selStream, true); - break; - case SCI_STUTTEREDPAGEDOWN: - PageMove(1, Selection::noSel, true); - break; - case SCI_STUTTEREDPAGEDOWNEXTEND: - PageMove(1, Selection::selStream, true); - break; - case SCI_PAGEUP: - PageMove(-1); - break; - case SCI_PAGEUPEXTEND: - PageMove(-1, Selection::selStream); - break; - case SCI_PAGEUPRECTEXTEND: - PageMove(-1, Selection::selRectangle); - break; - case SCI_PAGEDOWN: - PageMove(1); - break; - case SCI_PAGEDOWNEXTEND: - PageMove(1, Selection::selStream); - break; - case SCI_PAGEDOWNRECTEXTEND: - PageMove(1, Selection::selRectangle); - break; - case SCI_EDITTOGGLEOVERTYPE: - inOverstrike = !inOverstrike; - ShowCaretAtCurrentPosition(); - ContainerNeedsUpdate(SC_UPDATE_CONTENT); - NotifyUpdateUI(); - break; - case SCI_CANCEL: // Cancel any modes - handled in subclass - // Also unselect text - CancelModes(); - if (sel.Count() > 1) { - // Drop additional selections - InvalidateWholeSelection(); - sel.DropAdditionalRanges(); - } - break; - case SCI_DELETEBACK: - DelCharBack(true); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { - SetLastXChosen(); - } - EnsureCaretVisible(); - break; - case SCI_DELETEBACKNOTLINE: - DelCharBack(false); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { - SetLastXChosen(); - } - EnsureCaretVisible(); - break; - case SCI_TAB: - Indent(true); - if (caretSticky == SC_CARETSTICKY_OFF) { - SetLastXChosen(); - } - EnsureCaretVisible(); - ShowCaretAtCurrentPosition(); // Avoid blinking - break; - case SCI_BACKTAB: - Indent(false); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { - SetLastXChosen(); - } - EnsureCaretVisible(); - ShowCaretAtCurrentPosition(); // Avoid blinking - break; - case SCI_NEWLINE: - NewLine(); - break; - case SCI_FORMFEED: - AddChar('\f'); - break; - case SCI_ZOOMIN: - if (vs.zoomLevel < 20) { - vs.zoomLevel++; - InvalidateStyleRedraw(); - NotifyZoom(); - } - break; - case SCI_ZOOMOUT: - if (vs.zoomLevel > -10) { - vs.zoomLevel--; - InvalidateStyleRedraw(); - NotifyZoom(); - } - break; - - case SCI_DELWORDLEFT: - case SCI_DELWORDRIGHT: - case SCI_DELWORDRIGHTEND: - case SCI_DELLINELEFT: - case SCI_DELLINERIGHT: - return DelWordOrLine(iMessage); - - case SCI_LINECOPY: { - int lineStart = pdoc->LineFromPosition(SelectionStart().Position()); - int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position()); - CopyRangeToClipboard(pdoc->LineStart(lineStart), - pdoc->LineStart(lineEnd + 1)); - } - break; - case SCI_LINECUT: { - int lineStart = pdoc->LineFromPosition(SelectionStart().Position()); - int lineEnd = pdoc->LineFromPosition(SelectionEnd().Position()); - int start = pdoc->LineStart(lineStart); - int end = pdoc->LineStart(lineEnd + 1); - SetSelection(start, end); - Cut(); - SetLastXChosen(); - } - break; - case SCI_LINEDELETE: { - int line = pdoc->LineFromPosition(sel.MainCaret()); - int start = pdoc->LineStart(line); - int end = pdoc->LineStart(line + 1); - pdoc->DeleteChars(start, end - start); - } - break; - case SCI_LINETRANSPOSE: - LineTranspose(); - break; - case SCI_LINEDUPLICATE: - Duplicate(true); - break; - case SCI_SELECTIONDUPLICATE: - Duplicate(false); - break; - case SCI_LOWERCASE: - ChangeCaseOfSelection(cmLower); - break; - case SCI_UPPERCASE: - ChangeCaseOfSelection(cmUpper); - break; - case SCI_SCROLLTOSTART: - ScrollTo(0); - break; - case SCI_SCROLLTOEND: - ScrollTo(MaxScrollPos()); - break; - } - return 0; -} - -int Editor::KeyDefault(int, int) { - return 0; -} - -int Editor::KeyDownWithModifiers(int key, int modifiers, bool *consumed) { - DwellEnd(false); - int msg = kmap.Find(key, modifiers); - if (msg) { - if (consumed) - *consumed = true; - return static_cast(WndProc(msg, 0, 0)); - } else { - if (consumed) - *consumed = false; - return KeyDefault(key, modifiers); - } -} - -int Editor::KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed) { - return KeyDownWithModifiers(key, ModifierFlags(shift, ctrl, alt), consumed); -} - -void Editor::Indent(bool forwards) { - UndoGroup ug(pdoc); - for (size_t r=0; rLineFromPosition(sel.Range(r).anchor.Position()); - int caretPosition = sel.Range(r).caret.Position(); - int lineCurrentPos = pdoc->LineFromPosition(caretPosition); - if (lineOfAnchor == lineCurrentPos) { - if (forwards) { - pdoc->DeleteChars(sel.Range(r).Start().Position(), sel.Range(r).Length()); - caretPosition = sel.Range(r).caret.Position(); - if (pdoc->GetColumn(caretPosition) <= pdoc->GetColumn(pdoc->GetLineIndentPosition(lineCurrentPos)) && - pdoc->tabIndents) { - int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = pdoc->IndentSize(); - const int posSelect = pdoc->SetLineIndentation( - lineCurrentPos, indentation + indentationStep - indentation % indentationStep); - sel.Range(r) = SelectionRange(posSelect); - } else { - if (pdoc->useTabs) { - const int lengthInserted = pdoc->InsertString(caretPosition, "\t", 1); - sel.Range(r) = SelectionRange(caretPosition + lengthInserted); - } else { - int numSpaces = (pdoc->tabInChars) - - (pdoc->GetColumn(caretPosition) % (pdoc->tabInChars)); - if (numSpaces < 1) - numSpaces = pdoc->tabInChars; - const std::string spaceText(numSpaces, ' '); - const int lengthInserted = pdoc->InsertString(caretPosition, spaceText.c_str(), - static_cast(spaceText.length())); - sel.Range(r) = SelectionRange(caretPosition + lengthInserted); - } - } - } else { - if (pdoc->GetColumn(caretPosition) <= pdoc->GetLineIndentation(lineCurrentPos) && - pdoc->tabIndents) { - int indentation = pdoc->GetLineIndentation(lineCurrentPos); - int indentationStep = pdoc->IndentSize(); - const int posSelect = pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep); - sel.Range(r) = SelectionRange(posSelect); - } else { - int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) * - pdoc->tabInChars; - if (newColumn < 0) - newColumn = 0; - int newPos = caretPosition; - while (pdoc->GetColumn(newPos) > newColumn) - newPos--; - sel.Range(r) = SelectionRange(newPos); - } - } - } else { // Multiline - int anchorPosOnLine = sel.Range(r).anchor.Position() - pdoc->LineStart(lineOfAnchor); - int currentPosPosOnLine = caretPosition - pdoc->LineStart(lineCurrentPos); - // Multiple lines selected so indent / dedent - int lineTopSel = Platform::Minimum(lineOfAnchor, lineCurrentPos); - int lineBottomSel = Platform::Maximum(lineOfAnchor, lineCurrentPos); - if (pdoc->LineStart(lineBottomSel) == sel.Range(r).anchor.Position() || pdoc->LineStart(lineBottomSel) == caretPosition) - lineBottomSel--; // If not selecting any characters on a line, do not indent - pdoc->Indent(forwards, lineBottomSel, lineTopSel); - if (lineOfAnchor < lineCurrentPos) { - if (currentPosPosOnLine == 0) - sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor)); - else - sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos + 1), pdoc->LineStart(lineOfAnchor)); - } else { - if (anchorPosOnLine == 0) - sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor)); - else - sel.Range(r) = SelectionRange(pdoc->LineStart(lineCurrentPos), pdoc->LineStart(lineOfAnchor + 1)); - } - } - } - ContainerNeedsUpdate(SC_UPDATE_SELECTION); -} - -class CaseFolderASCII : public CaseFolderTable { -public: - CaseFolderASCII() { - StandardASCII(); - } - ~CaseFolderASCII() { - } -}; - - -CaseFolder *Editor::CaseFolderForEncoding() { - // Simple default that only maps ASCII upper case to lower case. - return new CaseFolderASCII(); -} - -/** - * Search of a text in the document, in the given range. - * @return The position of the found text, -1 if not found. - */ -long Editor::FindText( - uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, - ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. - sptr_t lParam) { ///< @c Sci_TextToFind structure: The text to search for in the given range. - - Sci_TextToFind *ft = reinterpret_cast(lParam); - int lengthFound = istrlen(ft->lpstrText); - if (!pdoc->HasCaseFolder()) - pdoc->SetCaseFolder(CaseFolderForEncoding()); - try { - long pos = pdoc->FindText( - static_cast(ft->chrg.cpMin), - static_cast(ft->chrg.cpMax), - ft->lpstrText, - static_cast(wParam), - &lengthFound); - if (pos != -1) { - ft->chrgText.cpMin = pos; - ft->chrgText.cpMax = pos + lengthFound; - } - return static_cast(pos); - } catch (RegexError &) { - errorStatus = SC_STATUS_WARN_REGEX; - return -1; - } -} - -/** - * Relocatable search support : Searches relative to current selection - * point and sets the selection to the found text range with - * each search. - */ -/** - * Anchor following searches at current selection start: This allows - * multiple incremental interactive searches to be macro recorded - * while still setting the selection to found text so the find/select - * operation is self-contained. - */ -void Editor::SearchAnchor() { - searchAnchor = SelectionStart().Position(); -} - -/** - * Find text from current search anchor: Must call @c SearchAnchor first. - * Used for next text and previous text requests. - * @return The position of the found text, -1 if not found. - */ -long Editor::SearchText( - unsigned int iMessage, ///< Accepts both @c SCI_SEARCHNEXT and @c SCI_SEARCHPREV. - uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, - ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. - sptr_t lParam) { ///< The text to search for. - - const char *txt = reinterpret_cast(lParam); - long pos; - int lengthFound = istrlen(txt); - if (!pdoc->HasCaseFolder()) - pdoc->SetCaseFolder(CaseFolderForEncoding()); - try { - if (iMessage == SCI_SEARCHNEXT) { - pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt, - static_cast(wParam), - &lengthFound); - } else { - pos = pdoc->FindText(searchAnchor, 0, txt, - static_cast(wParam), - &lengthFound); - } - } catch (RegexError &) { - errorStatus = SC_STATUS_WARN_REGEX; - return -1; - } - if (pos != -1) { - SetSelection(static_cast(pos), static_cast(pos + lengthFound)); - } - - return pos; -} - -std::string Editor::CaseMapString(const std::string &s, int caseMapping) { - std::string ret(s); - for (size_t i=0; i= 'a' && ret[i] <= 'z') - ret[i] = static_cast(ret[i] - 'a' + 'A'); - break; - case cmLower: - if (ret[i] >= 'A' && ret[i] <= 'Z') - ret[i] = static_cast(ret[i] - 'A' + 'a'); - break; - } - } - return ret; -} - -/** - * Search for text in the target range of the document. - * @return The position of the found text, -1 if not found. - */ -long Editor::SearchInTarget(const char *text, int length) { - int lengthFound = length; - - if (!pdoc->HasCaseFolder()) - pdoc->SetCaseFolder(CaseFolderForEncoding()); - try { - long pos = pdoc->FindText(targetStart, targetEnd, text, - searchFlags, - &lengthFound); - if (pos != -1) { - targetStart = static_cast(pos); - targetEnd = static_cast(pos + lengthFound); - } - return pos; - } catch (RegexError &) { - errorStatus = SC_STATUS_WARN_REGEX; - return -1; - } -} - -void Editor::GoToLine(int lineNo) { - if (lineNo > pdoc->LinesTotal()) - lineNo = pdoc->LinesTotal(); - if (lineNo < 0) - lineNo = 0; - SetEmptySelection(pdoc->LineStart(lineNo)); - ShowCaretAtCurrentPosition(); - EnsureCaretVisible(); -} - -static bool Close(Point pt1, Point pt2, Point threshold) { - if (std::abs(pt1.x - pt2.x) > threshold.x) - return false; - if (std::abs(pt1.y - pt2.y) > threshold.y) - return false; - return true; -} - -std::string Editor::RangeText(int start, int end) const { - if (start < end) { - int len = end - start; - std::string ret(len, '\0'); - for (int i = 0; i < len; i++) { - ret[i] = pdoc->CharAt(start + i); - } - return ret; - } - return std::string(); -} - -void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) { - if (sel.Empty()) { - if (allowLineCopy) { - int currentLine = pdoc->LineFromPosition(sel.MainCaret()); - int start = pdoc->LineStart(currentLine); - int end = pdoc->LineEnd(currentLine); - - std::string text = RangeText(start, end); - if (pdoc->eolMode != SC_EOL_LF) - text.push_back('\r'); - if (pdoc->eolMode != SC_EOL_CR) - text.push_back('\n'); - ss->Copy(text, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet, false, true); - } - } else { - std::string text; - std::vector rangesInOrder = sel.RangesCopy(); - if (sel.selType == Selection::selRectangle) - std::sort(rangesInOrder.begin(), rangesInOrder.end()); - for (size_t r=0; reolMode != SC_EOL_LF) - text.push_back('\r'); - if (pdoc->eolMode != SC_EOL_CR) - text.push_back('\n'); - } - } - ss->Copy(text, pdoc->dbcsCodePage, - vs.styles[STYLE_DEFAULT].characterSet, sel.IsRectangular(), sel.selType == Selection::selLines); - } -} - -void Editor::CopyRangeToClipboard(int start, int end) { - start = pdoc->ClampPositionIntoDocument(start); - end = pdoc->ClampPositionIntoDocument(end); - SelectionText selectedText; - std::string text = RangeText(start, end); - selectedText.Copy(text, - pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false); - CopyToClipboard(selectedText); -} - -void Editor::CopyText(int length, const char *text) { - SelectionText selectedText; - selectedText.Copy(std::string(text, length), - pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, false); - CopyToClipboard(selectedText); -} - -void Editor::SetDragPosition(SelectionPosition newPos) { - if (newPos.Position() >= 0) { - newPos = MovePositionOutsideChar(newPos, 1); - posDrop = newPos; - } - if (!(posDrag == newPos)) { - caret.on = true; - if (FineTickerAvailable()) { - FineTickerCancel(tickCaret); - if ((caret.active) && (caret.period > 0) && (newPos.Position() < 0)) - FineTickerStart(tickCaret, caret.period, caret.period/10); - } else { - SetTicking(true); - } - InvalidateCaret(); - posDrag = newPos; - InvalidateCaret(); - } -} - -void Editor::DisplayCursor(Window::Cursor c) { - if (cursorMode == SC_CURSORNORMAL) - wMain.SetCursor(c); - else - wMain.SetCursor(static_cast(cursorMode)); -} - -bool Editor::DragThreshold(Point ptStart, Point ptNow) { - int xMove = static_cast(ptStart.x - ptNow.x); - int yMove = static_cast(ptStart.y - ptNow.y); - int distanceSquared = xMove * xMove + yMove * yMove; - return distanceSquared > 16; -} - -void Editor::StartDrag() { - // Always handled by subclasses - //SetMouseCapture(true); - //DisplayCursor(Window::cursorArrow); -} - -void Editor::DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular) { - //Platform::DebugPrintf("DropAt %d %d\n", inDragDrop, position); - if (inDragDrop == ddDragging) - dropWentOutside = false; - - bool positionWasInSelection = PositionInSelection(position.Position()); - - bool positionOnEdgeOfSelection = - (position == SelectionStart()) || (position == SelectionEnd()); - - if ((inDragDrop != ddDragging) || !(positionWasInSelection) || - (positionOnEdgeOfSelection && !moving)) { - - SelectionPosition selStart = SelectionStart(); - SelectionPosition selEnd = SelectionEnd(); - - UndoGroup ug(pdoc); - - SelectionPosition positionAfterDeletion = position; - if ((inDragDrop == ddDragging) && moving) { - // Remove dragged out text - if (rectangular || sel.selType == Selection::selLines) { - for (size_t r=0; r= sel.Range(r).Start()) { - if (position > sel.Range(r).End()) { - positionAfterDeletion.Add(-sel.Range(r).Length()); - } else { - positionAfterDeletion.Add(-SelectionRange(position, sel.Range(r).Start()).Length()); - } - } - } - } else { - if (position > selStart) { - positionAfterDeletion.Add(-SelectionRange(selEnd, selStart).Length()); - } - } - ClearSelection(); - } - position = positionAfterDeletion; - - std::string convertedText = Document::TransformLineEnds(value, lengthValue, pdoc->eolMode); - - if (rectangular) { - PasteRectangular(position, convertedText.c_str(), static_cast(convertedText.length())); - // Should try to select new rectangle but it may not be a rectangle now so just select the drop position - SetEmptySelection(position); - } else { - position = MovePositionOutsideChar(position, sel.MainCaret() - position.Position()); - position = RealizeVirtualSpace(position); - const int lengthInserted = pdoc->InsertString( - position.Position(), convertedText.c_str(), static_cast(convertedText.length())); - if (lengthInserted > 0) { - SelectionPosition posAfterInsertion = position; - posAfterInsertion.Add(lengthInserted); - SetSelection(posAfterInsertion, position); - } - } - } else if (inDragDrop == ddDragging) { - SetEmptySelection(position); - } -} - -void Editor::DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular) { - DropAt(position, value, strlen(value), moving, rectangular); -} - -/** - * @return true if given position is inside the selection, - */ -bool Editor::PositionInSelection(int pos) { - pos = MovePositionOutsideChar(pos, sel.MainCaret() - pos); - for (size_t r=0; r ptPos.x) { - hit = false; - } - } - if (hit) - return true; - } - } - return false; -} - -bool Editor::PointInSelMargin(Point pt) const { - // Really means: "Point in a margin" - if (vs.fixedColumnWidth > 0) { // There is a margin - PRectangle rcSelMargin = GetClientRectangle(); - rcSelMargin.right = static_cast(vs.textStart - vs.leftMarginWidth); - rcSelMargin.left = static_cast(vs.textStart - vs.fixedColumnWidth); - return rcSelMargin.ContainsWholePixel(pt); - } else { - return false; - } -} - -Window::Cursor Editor::GetMarginCursor(Point pt) const { - int x = 0; - for (size_t margin = 0; margin < vs.ms.size(); margin++) { - if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width)) - return static_cast(vs.ms[margin].cursor); - x += vs.ms[margin].width; - } - return Window::cursorReverseArrow; -} - -void Editor::TrimAndSetSelection(int currentPos_, int anchor_) { - sel.TrimSelection(SelectionRange(currentPos_, anchor_)); - SetSelection(currentPos_, anchor_); -} - -void Editor::LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine) { - int selCurrentPos, selAnchorPos; - if (wholeLine) { - int lineCurrent_ = pdoc->LineFromPosition(lineCurrentPos_); - int lineAnchor_ = pdoc->LineFromPosition(lineAnchorPos_); - if (lineAnchorPos_ < lineCurrentPos_) { - selCurrentPos = pdoc->LineStart(lineCurrent_ + 1); - selAnchorPos = pdoc->LineStart(lineAnchor_); - } else if (lineAnchorPos_ > lineCurrentPos_) { - selCurrentPos = pdoc->LineStart(lineCurrent_); - selAnchorPos = pdoc->LineStart(lineAnchor_ + 1); - } else { // Same line, select it - selCurrentPos = pdoc->LineStart(lineAnchor_ + 1); - selAnchorPos = pdoc->LineStart(lineAnchor_); - } - } else { - if (lineAnchorPos_ < lineCurrentPos_) { - selCurrentPos = StartEndDisplayLine(lineCurrentPos_, false) + 1; - selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1); - selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true); - } else if (lineAnchorPos_ > lineCurrentPos_) { - selCurrentPos = StartEndDisplayLine(lineCurrentPos_, true); - selAnchorPos = StartEndDisplayLine(lineAnchorPos_, false) + 1; - selAnchorPos = pdoc->MovePositionOutsideChar(selAnchorPos, 1); - } else { // Same line, select it - selCurrentPos = StartEndDisplayLine(lineAnchorPos_, false) + 1; - selCurrentPos = pdoc->MovePositionOutsideChar(selCurrentPos, 1); - selAnchorPos = StartEndDisplayLine(lineAnchorPos_, true); - } - } - TrimAndSetSelection(selCurrentPos, selAnchorPos); -} - -void Editor::WordSelection(int pos) { - if (pos < wordSelectAnchorStartPos) { - // Extend backward to the word containing pos. - // Skip ExtendWordSelect if the line is empty or if pos is after the last character. - // This ensures that a series of empty lines isn't counted as a single "word". - if (!pdoc->IsLineEndPosition(pos)) - pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1); - TrimAndSetSelection(pos, wordSelectAnchorEndPos); - } else if (pos > wordSelectAnchorEndPos) { - // Extend forward to the word containing the character to the left of pos. - // Skip ExtendWordSelect if the line is empty or if pos is the first position on the line. - // This ensures that a series of empty lines isn't counted as a single "word". - if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos))) - pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1); - TrimAndSetSelection(pos, wordSelectAnchorStartPos); - } else { - // Select only the anchored word - if (pos >= originalAnchorPos) - TrimAndSetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos); - else - TrimAndSetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos); - } -} - -void Editor::DwellEnd(bool mouseMoved) { - if (mouseMoved) - ticksToDwell = dwellDelay; - else - ticksToDwell = SC_TIME_FOREVER; - if (dwelling && (dwellDelay < SC_TIME_FOREVER)) { - dwelling = false; - NotifyDwelling(ptMouseLast, dwelling); - } - if (FineTickerAvailable()) { - FineTickerCancel(tickDwell); - if (mouseMoved && (dwellDelay < SC_TIME_FOREVER)) { - //FineTickerStart(tickDwell, dwellDelay, dwellDelay/10); - } - } -} - -void Editor::MouseLeave() { - SetHotSpotRange(NULL); - if (!HaveMouseCapture()) { - ptMouseLast = Point(-1,-1); - DwellEnd(true); - } -} - -static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) { - return (!rectangular && ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)) - || (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0)); -} - -void Editor::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) { - SetHoverIndicatorPoint(pt); - //Platform::DebugPrintf("ButtonDown %d %d = %d alt=%d %d\n", curTime, lastClickTime, curTime - lastClickTime, alt, inDragDrop); - ptMouseLast = pt; - const bool ctrl = (modifiers & SCI_CTRL) != 0; - const bool shift = (modifiers & SCI_SHIFT) != 0; - const bool alt = (modifiers & SCI_ALT) != 0; - SelectionPosition newPos = SPositionFromLocation(pt, false, false, AllowVirtualSpace(virtualSpaceOptions, alt)); - newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); - SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false); - newCharPos = MovePositionOutsideChar(newCharPos, -1); - inDragDrop = ddNone; - sel.SetMoveExtends(false); - - if (NotifyMarginClick(pt, modifiers)) - return; - - NotifyIndicatorClick(true, newPos.Position(), modifiers); - - bool inSelMargin = PointInSelMargin(pt); - // In margin ctrl+(double)click should always select everything - if (ctrl && inSelMargin) { - SelectAll(); - lastClickTime = curTime; - lastClick = pt; - return; - } - if (shift && !inSelMargin) { - SetSelection(newPos); - } - if (((curTime - lastClickTime) < Platform::DoubleClickTime()) && Close(pt, lastClick, doubleClickCloseThreshold)) { - //Platform::DebugPrintf("Double click %d %d = %d\n", curTime, lastClickTime, curTime - lastClickTime); - SetMouseCapture(true); - if (FineTickerAvailable()) { - FineTickerStart(tickScroll, 100, 10); - } - if (!ctrl || !multipleSelection || (selectionType != selChar && selectionType != selWord)) - SetEmptySelection(newPos.Position()); - bool doubleClick = false; - // Stop mouse button bounce changing selection type - if (!Platform::MouseButtonBounce() || curTime != lastClickTime) { - if (inSelMargin) { - // Inside margin selection type should be either selSubLine or selWholeLine. - if (selectionType == selSubLine) { - // If it is selSubLine, we're inside a *double* click and word wrap is enabled, - // so we switch to selWholeLine in order to select whole line. - selectionType = selWholeLine; - } else if (selectionType != selSubLine && selectionType != selWholeLine) { - // If it is neither, reset selection type to line selection. - selectionType = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; - } - } else { - if (selectionType == selChar) { - selectionType = selWord; - doubleClick = true; - } else if (selectionType == selWord) { - // Since we ended up here, we're inside a *triple* click, which should always select - // whole line regardless of word wrap being enabled or not. - selectionType = selWholeLine; - } else { - selectionType = selChar; - originalAnchorPos = sel.MainCaret(); - } - } - } - - if (selectionType == selWord) { - int charPos = originalAnchorPos; - if (sel.MainCaret() == originalAnchorPos) { - charPos = PositionFromLocation(pt, false, true); - charPos = MovePositionOutsideChar(charPos, -1); - } - - int startWord, endWord; - if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) { - startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1); - endWord = pdoc->ExtendWordSelect(charPos, 1); - } else { - // Selecting backwards, or anchor beyond last character on line. In these cases, - // we select the word containing the character to the *left* of the anchor. - if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) { - startWord = pdoc->ExtendWordSelect(charPos, -1); - endWord = pdoc->ExtendWordSelect(startWord, 1); - } else { - // Anchor at start of line; select nothing to begin with. - startWord = charPos; - endWord = charPos; - } - } - - wordSelectAnchorStartPos = startWord; - wordSelectAnchorEndPos = endWord; - wordSelectInitialCaretPos = sel.MainCaret(); - WordSelection(wordSelectInitialCaretPos); - } else if (selectionType == selSubLine || selectionType == selWholeLine) { - lineAnchorPos = newPos.Position(); - LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine); - //Platform::DebugPrintf("Triple click: %d - %d\n", anchor, currentPos); - } else { - SetEmptySelection(sel.MainCaret()); - } - //Platform::DebugPrintf("Double click: %d - %d\n", anchor, currentPos); - if (doubleClick) { - NotifyDoubleClick(pt, modifiers); - if (PositionIsHotspot(newCharPos.Position())) - NotifyHotSpotDoubleClicked(newCharPos.Position(), modifiers); - } - } else { // Single click - if (inSelMargin) { - if (sel.IsRectangular() || (sel.Count() > 1)) { - InvalidateWholeSelection(); - sel.Clear(); - } - sel.selType = Selection::selStream; - if (!shift) { - // Single click in margin: select whole line or only subline if word wrap is enabled - lineAnchorPos = newPos.Position(); - selectionType = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; - LineSelection(lineAnchorPos, lineAnchorPos, selectionType == selWholeLine); - } else { - // Single shift+click in margin: select from line anchor to clicked line - if (sel.MainAnchor() > sel.MainCaret()) - lineAnchorPos = sel.MainAnchor() - 1; - else - lineAnchorPos = sel.MainAnchor(); - // Reset selection type if there is an empty selection. - // This ensures that we don't end up stuck in previous selection mode, which is no longer valid. - // Otherwise, if there's a non empty selection, reset selection type only if it differs from selSubLine and selWholeLine. - // This ensures that we continue selecting in the same selection mode. - if (sel.Empty() || (selectionType != selSubLine && selectionType != selWholeLine)) - selectionType = (Wrapping() && (marginOptions & SC_MARGINOPTION_SUBLINESELECT)) ? selSubLine : selWholeLine; - LineSelection(newPos.Position(), lineAnchorPos, selectionType == selWholeLine); - } - - SetDragPosition(SelectionPosition(invalidPosition)); - SetMouseCapture(true); - if (FineTickerAvailable()) { - FineTickerStart(tickScroll, 100, 10); - } - } else { - if (PointIsHotspot(pt)) { - NotifyHotSpotClicked(newCharPos.Position(), modifiers); - hotSpotClickPos = newCharPos.Position(); - } - if (!shift) { - if (PointInSelection(pt) && !SelectionEmpty()) - inDragDrop = ddInitial; - else - inDragDrop = ddNone; - } - SetMouseCapture(true); - if (FineTickerAvailable()) { - FineTickerStart(tickScroll, 100, 10); - } - if (inDragDrop != ddInitial) { - SetDragPosition(SelectionPosition(invalidPosition)); - if (!shift) { - if (ctrl && multipleSelection) { - SelectionRange range(newPos); - sel.TentativeSelection(range); - InvalidateSelection(range, true); - } else { - InvalidateSelection(SelectionRange(newPos), true); - if (sel.Count() > 1) - Redraw(); - if ((sel.Count() > 1) || (sel.selType != Selection::selStream)) - sel.Clear(); - sel.selType = alt ? Selection::selRectangle : Selection::selStream; - SetSelection(newPos, newPos); - } - } - SelectionPosition anchorCurrent = newPos; - if (shift) - anchorCurrent = sel.IsRectangular() ? - sel.Rectangular().anchor : sel.RangeMain().anchor; - sel.selType = alt ? Selection::selRectangle : Selection::selStream; - selectionType = selChar; - originalAnchorPos = sel.MainCaret(); - sel.Rectangular() = SelectionRange(newPos, anchorCurrent); - SetRectangularRange(); - } - } - } - lastClickTime = curTime; - lastClick = pt; - lastXChosen = static_cast(pt.x) + xOffset; - ShowCaretAtCurrentPosition(); -} - -void Editor::RightButtonDownWithModifiers(Point pt, unsigned int, int modifiers) { - if (NotifyMarginRightClick(pt, modifiers)) - return; -} - -void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { - return ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt)); -} - -bool Editor::PositionIsHotspot(int position) const { - return vs.styles[pdoc->StyleIndexAt(position)].hotspot; -} - -bool Editor::PointIsHotspot(Point pt) { - int pos = PositionFromLocation(pt, true, true); - if (pos == INVALID_POSITION) - return false; - return PositionIsHotspot(pos); -} - -void Editor::SetHoverIndicatorPosition(int position) { - int hoverIndicatorPosPrev = hoverIndicatorPos; - hoverIndicatorPos = INVALID_POSITION; - if (vs.indicatorsDynamic == 0) - return; - if (position != INVALID_POSITION) { - for (Decoration *deco = pdoc->decorations.root; deco; deco = deco->next) { - if (vs.indicators[deco->indicator].IsDynamic()) { - if (pdoc->decorations.ValueAt(deco->indicator, position)) { - hoverIndicatorPos = position; - } - } - } - } - if (hoverIndicatorPosPrev != hoverIndicatorPos) { - Redraw(); - } -} - -void Editor::SetHoverIndicatorPoint(Point pt) { - if (vs.indicatorsDynamic == 0) { - SetHoverIndicatorPosition(INVALID_POSITION); - } else { - SetHoverIndicatorPosition(PositionFromLocation(pt, true, true)); - } -} - -void Editor::SetHotSpotRange(Point *pt) { - if (pt) { - int pos = PositionFromLocation(*pt, false, true); - - // If we don't limit this to word characters then the - // range can encompass more than the run range and then - // the underline will not be drawn properly. - Range hsNew; - hsNew.start = pdoc->ExtendStyleRange(pos, -1, vs.hotspotSingleLine); - hsNew.end = pdoc->ExtendStyleRange(pos, 1, vs.hotspotSingleLine); - - // Only invalidate the range if the hotspot range has changed... - if (!(hsNew == hotspot)) { - if (hotspot.Valid()) { - InvalidateRange(hotspot.start, hotspot.end); - } - hotspot = hsNew; - InvalidateRange(hotspot.start, hotspot.end); - } - } else { - if (hotspot.Valid()) { - InvalidateRange(hotspot.start, hotspot.end); - } - hotspot = Range(invalidPosition); - } -} - -Range Editor::GetHotSpotRange() const { - return hotspot; -} - -void Editor::ButtonMoveWithModifiers(Point pt, int modifiers) { - if ((ptMouseLast.x != pt.x) || (ptMouseLast.y != pt.y)) { - DwellEnd(true); - } - - SelectionPosition movePos = SPositionFromLocation(pt, false, false, - AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular())); - movePos = MovePositionOutsideChar(movePos, sel.MainCaret() - movePos.Position()); - - if (inDragDrop == ddInitial) { - if (DragThreshold(ptMouseLast, pt)) { - SetMouseCapture(false); - if (FineTickerAvailable()) { - FineTickerCancel(tickScroll); - } - SetDragPosition(movePos); - CopySelectionRange(&drag); - StartDrag(); - } - return; - } - - ptMouseLast = pt; - PRectangle rcClient = GetClientRectangle(); - Point ptOrigin = GetVisibleOriginInMain(); - rcClient.Move(0, -ptOrigin.y); - if (FineTickerAvailable() && (dwellDelay < SC_TIME_FOREVER) && rcClient.Contains(pt)) { - FineTickerStart(tickDwell, dwellDelay, dwellDelay/10); - } - //Platform::DebugPrintf("Move %d %d\n", pt.x, pt.y); - if (HaveMouseCapture()) { - - // Slow down autoscrolling/selection - autoScrollTimer.ticksToWait -= timer.tickSize; - if (autoScrollTimer.ticksToWait > 0) - return; - autoScrollTimer.ticksToWait = autoScrollDelay; - - // Adjust selection - if (posDrag.IsValid()) { - SetDragPosition(movePos); - } else { - if (selectionType == selChar) { - if (sel.selType == Selection::selStream && (modifiers & SCI_ALT) && mouseSelectionRectangularSwitch) { - sel.selType = Selection::selRectangle; - } - if (sel.IsRectangular()) { - sel.Rectangular() = SelectionRange(movePos, sel.Rectangular().anchor); - SetSelection(movePos, sel.RangeMain().anchor); - } else if (sel.Count() > 1) { - InvalidateSelection(sel.RangeMain(), false); - SelectionRange range(movePos, sel.RangeMain().anchor); - sel.TentativeSelection(range); - InvalidateSelection(range, true); - } else { - SetSelection(movePos, sel.RangeMain().anchor); - } - } else if (selectionType == selWord) { - // Continue selecting by word - if (movePos.Position() == wordSelectInitialCaretPos) { // Didn't move - // No need to do anything. Previously this case was lumped - // in with "Moved forward", but that can be harmful in this - // case: a handler for the NotifyDoubleClick re-adjusts - // the selection for a fancier definition of "word" (for - // example, in Perl it is useful to include the leading - // '$', '%' or '@' on variables for word selection). In this - // the ButtonMove() called via Tick() for auto-scrolling - // could result in the fancier word selection adjustment - // being unmade. - } else { - wordSelectInitialCaretPos = -1; - WordSelection(movePos.Position()); - } - } else { - // Continue selecting by line - LineSelection(movePos.Position(), lineAnchorPos, selectionType == selWholeLine); - } - } - - // Autoscroll - int lineMove = DisplayFromPosition(movePos.Position()); - if (pt.y > rcClient.bottom) { - ScrollTo(lineMove - LinesOnScreen() + 1); - Redraw(); - } else if (pt.y < rcClient.top) { - ScrollTo(lineMove); - Redraw(); - } - EnsureCaretVisible(false, false, true); - - if (hotspot.Valid() && !PointIsHotspot(pt)) - SetHotSpotRange(NULL); - - if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,true) != hotSpotClickPos) { - if (inDragDrop == ddNone) { - DisplayCursor(Window::cursorText); - } - hotSpotClickPos = INVALID_POSITION; - } - - } else { - if (vs.fixedColumnWidth > 0) { // There is a margin - if (PointInSelMargin(pt)) { - DisplayCursor(GetMarginCursor(pt)); - SetHotSpotRange(NULL); - return; // No need to test for selection - } - } - // Display regular (drag) cursor over selection - if (PointInSelection(pt) && !SelectionEmpty()) { - DisplayCursor(Window::cursorArrow); - } else { - SetHoverIndicatorPoint(pt); - if (PointIsHotspot(pt)) { - DisplayCursor(Window::cursorHand); - SetHotSpotRange(&pt); - } else { - if (hoverIndicatorPos != invalidPosition) - DisplayCursor(Window::cursorHand); - else - DisplayCursor(Window::cursorText); - SetHotSpotRange(NULL); - } - } - } -} - -void Editor::ButtonMove(Point pt) { - ButtonMoveWithModifiers(pt, 0); -} - -void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) { - //Platform::DebugPrintf("ButtonUp %d %d\n", HaveMouseCapture(), inDragDrop); - SelectionPosition newPos = SPositionFromLocation(pt, false, false, - AllowVirtualSpace(virtualSpaceOptions, sel.IsRectangular())); - if (hoverIndicatorPos != INVALID_POSITION) - InvalidateRange(newPos.Position(), newPos.Position() + 1); - newPos = MovePositionOutsideChar(newPos, sel.MainCaret() - newPos.Position()); - if (inDragDrop == ddInitial) { - inDragDrop = ddNone; - SetEmptySelection(newPos); - selectionType = selChar; - originalAnchorPos = sel.MainCaret(); - } - if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) { - hotSpotClickPos = INVALID_POSITION; - SelectionPosition newCharPos = SPositionFromLocation(pt, false, true, false); - newCharPos = MovePositionOutsideChar(newCharPos, -1); - NotifyHotSpotReleaseClick(newCharPos.Position(), ctrl ? SCI_CTRL : 0); - } - if (HaveMouseCapture()) { - if (PointInSelMargin(pt)) { - DisplayCursor(GetMarginCursor(pt)); - } else { - DisplayCursor(Window::cursorText); - SetHotSpotRange(NULL); - } - ptMouseLast = pt; - SetMouseCapture(false); - if (FineTickerAvailable()) { - FineTickerCancel(tickScroll); - } - NotifyIndicatorClick(false, newPos.Position(), 0); - if (inDragDrop == ddDragging) { - SelectionPosition selStart = SelectionStart(); - SelectionPosition selEnd = SelectionEnd(); - if (selStart < selEnd) { - if (drag.Length()) { - const int length = static_cast(drag.Length()); - if (ctrl) { - const int lengthInserted = pdoc->InsertString( - newPos.Position(), drag.Data(), length); - if (lengthInserted > 0) { - SetSelection(newPos.Position(), newPos.Position() + lengthInserted); - } - } else if (newPos < selStart) { - pdoc->DeleteChars(selStart.Position(), static_cast(drag.Length())); - const int lengthInserted = pdoc->InsertString( - newPos.Position(), drag.Data(), length); - if (lengthInserted > 0) { - SetSelection(newPos.Position(), newPos.Position() + lengthInserted); - } - } else if (newPos > selEnd) { - pdoc->DeleteChars(selStart.Position(), static_cast(drag.Length())); - newPos.Add(-static_cast(drag.Length())); - const int lengthInserted = pdoc->InsertString( - newPos.Position(), drag.Data(), length); - if (lengthInserted > 0) { - SetSelection(newPos.Position(), newPos.Position() + lengthInserted); - } - } else { - SetEmptySelection(newPos.Position()); - } - drag.Clear(); - } - selectionType = selChar; - } - } else { - if (selectionType == selChar) { - if (sel.Count() > 1) { - sel.RangeMain() = - SelectionRange(newPos, sel.Range(sel.Count() - 1).anchor); - InvalidateWholeSelection(); - } else { - SetSelection(newPos, sel.RangeMain().anchor); - } - } - sel.CommitTentative(); - } - SetRectangularRange(); - lastClickTime = curTime; - lastClick = pt; - lastXChosen = static_cast(pt.x) + xOffset; - if (sel.selType == Selection::selStream) { - SetLastXChosen(); - } - inDragDrop = ddNone; - EnsureCaretVisible(false); - } -} - -// Called frequently to perform background UI including -// caret blinking and automatic scrolling. -void Editor::Tick() { - if (HaveMouseCapture()) { - // Auto scroll - ButtonMove(ptMouseLast); - } - if (caret.period > 0) { - timer.ticksToWait -= timer.tickSize; - if (timer.ticksToWait <= 0) { - caret.on = !caret.on; - timer.ticksToWait = caret.period; - if (caret.active) { - InvalidateCaret(); - } - } - } - if (horizontalScrollBarVisible && trackLineWidth && (view.lineWidthMaxSeen > scrollWidth)) { - scrollWidth = view.lineWidthMaxSeen; - SetScrollBars(); - } - if ((dwellDelay < SC_TIME_FOREVER) && - (ticksToDwell > 0) && - (!HaveMouseCapture()) && - (ptMouseLast.y >= 0)) { - ticksToDwell -= timer.tickSize; - if (ticksToDwell <= 0) { - dwelling = true; - NotifyDwelling(ptMouseLast, dwelling); - } - } -} - -bool Editor::Idle() { - bool needWrap = Wrapping() && wrapPending.NeedsWrap(); - - if (needWrap) { - // Wrap lines during idle. - WrapLines(wsIdle); - // No more wrapping - needWrap = wrapPending.NeedsWrap(); - } else if (needIdleStyling) { - IdleStyling(); - } - - // Add more idle things to do here, but make sure idleDone is - // set correctly before the function returns. returning - // false will stop calling this idle function until SetIdle() is - // called again. - - const bool idleDone = !needWrap && !needIdleStyling; // && thatDone && theOtherThingDone... - - return !idleDone; -} - -void Editor::SetTicking(bool) { - // SetTicking is deprecated. In the past it was pure virtual and was overridden in each - // derived platform class but fine grained timers should now be implemented. - // Either way, execution should not arrive here so assert failure. - assert(false); -} - -void Editor::TickFor(TickReason reason) { - switch (reason) { - case tickCaret: - caret.on = !caret.on; - if (caret.active) { - InvalidateCaret(); - } - break; - case tickScroll: - // Auto scroll - ButtonMove(ptMouseLast); - break; - case tickWiden: - SetScrollBars(); - FineTickerCancel(tickWiden); - break; - case tickDwell: - if ((!HaveMouseCapture()) && - (ptMouseLast.y >= 0)) { - dwelling = true; - NotifyDwelling(ptMouseLast, dwelling); - } - FineTickerCancel(tickDwell); - break; - default: - // tickPlatform handled by subclass - break; - } -} - -bool Editor::FineTickerAvailable() { - return false; -} - -// FineTickerStart is be overridden by subclasses that support fine ticking so -// this method should never be called. -bool Editor::FineTickerRunning(TickReason) { - assert(false); - return false; -} - -// FineTickerStart is be overridden by subclasses that support fine ticking so -// this method should never be called. -void Editor::FineTickerStart(TickReason, int, int) { - assert(false); -} - -// FineTickerCancel is be overridden by subclasses that support fine ticking so -// this method should never be called. -void Editor::FineTickerCancel(TickReason) { - assert(false); -} - -void Editor::SetFocusState(bool focusState) { - hasFocus = focusState; - NotifyFocus(hasFocus); - if (!hasFocus) { - CancelModes(); - } - ShowCaretAtCurrentPosition(); -} - -int Editor::PositionAfterArea(PRectangle rcArea) const { - // The start of the document line after the display line after the area - // This often means that the line after a modification is restyled which helps - // detect multiline comment additions and heals single line comments - int lineAfter = TopLineOfMain() + static_cast(rcArea.bottom - 1) / vs.lineHeight + 1; - if (lineAfter < cs.LinesDisplayed()) - return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1); - else - return pdoc->Length(); -} - -// Style to a position within the view. If this causes a change at end of last line then -// affects later lines so style all the viewed text. -void Editor::StyleToPositionInView(Position pos) { - int endWindow = PositionAfterArea(GetClientDrawingRectangle()); - if (pos > endWindow) - pos = endWindow; - const int styleAtEnd = pdoc->StyleIndexAt(pos-1); - pdoc->EnsureStyledTo(pos); - if ((endWindow > pos) && (styleAtEnd != pdoc->StyleIndexAt(pos-1))) { - // Style at end of line changed so is multi-line change like starting a comment - // so require rest of window to be styled. - DiscardOverdraw(); // Prepared bitmaps may be invalid - // DiscardOverdraw may have truncated client drawing area so recalculate endWindow - endWindow = PositionAfterArea(GetClientDrawingRectangle()); - pdoc->EnsureStyledTo(endWindow); - } -} - -int Editor::PositionAfterMaxStyling(int posMax, bool scrolling) const { - if ((idleStyling == SC_IDLESTYLING_NONE) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE)) { - // Both states do not limit styling - return posMax; - } - - // Try to keep time taken by styling reasonable so interaction remains smooth. - // When scrolling, allow less time to ensure responsive - const double secondsAllowed = scrolling ? 0.005 : 0.02; - - const int linesToStyle = Platform::Clamp(static_cast(secondsAllowed / pdoc->durationStyleOneLine), - 10, 0x10000); - const int stylingMaxLine = std::min( - static_cast(pdoc->LineFromPosition(pdoc->GetEndStyled()) + linesToStyle), - pdoc->LinesTotal()); - return std::min(static_cast(pdoc->LineStart(stylingMaxLine)), posMax); -} - -void Editor::StartIdleStyling(bool truncatedLastStyling) { - if ((idleStyling == SC_IDLESTYLING_ALL) || (idleStyling == SC_IDLESTYLING_AFTERVISIBLE)) { - if (pdoc->GetEndStyled() < pdoc->Length()) { - // Style remainder of document in idle time - needIdleStyling = true; - } - } else if (truncatedLastStyling) { - needIdleStyling = true; - } - - if (needIdleStyling) { - SetIdle(true); - } -} - -// Style for an area but bound the amount of styling to remain responsive -void Editor::StyleAreaBounded(PRectangle rcArea, bool scrolling) { - const int posAfterArea = PositionAfterArea(rcArea); - const int posAfterMax = PositionAfterMaxStyling(posAfterArea, scrolling); - if (posAfterMax < posAfterArea) { - // Idle styling may be performed before current visible area - // Style a bit now then style further in idle time - pdoc->StyleToAdjustingLineDuration(posAfterMax); - } else { - // Can style all wanted now. - StyleToPositionInView(posAfterArea); - } - StartIdleStyling(posAfterMax < posAfterArea); -} - -void Editor::IdleStyling() { - const int posAfterArea = PositionAfterArea(GetClientRectangle()); - const int endGoal = (idleStyling >= SC_IDLESTYLING_AFTERVISIBLE) ? - pdoc->Length() : posAfterArea; - const int posAfterMax = PositionAfterMaxStyling(endGoal, false); - pdoc->StyleToAdjustingLineDuration(posAfterMax); - if (pdoc->GetEndStyled() >= endGoal) { - needIdleStyling = false; - } -} - -void Editor::IdleWork() { - // Style the line after the modification as this allows modifications that change just the - // line of the modification to heal instead of propagating to the rest of the window. - if (workNeeded.items & WorkNeeded::workStyle) { - StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(workNeeded.upTo) + 2)); - } - NotifyUpdateUI(); - workNeeded.Reset(); -} - -void Editor::QueueIdleWork(WorkNeeded::workItems items, int upTo) { - workNeeded.Need(items, upTo); -} - -bool Editor::PaintContains(PRectangle rc) { - if (rc.Empty()) { - return true; - } else { - return rcPaint.Contains(rc); - } -} - -bool Editor::PaintContainsMargin() { - if (wMargin.GetID()) { - // With separate margin view, paint of text view - // never contains margin. - return false; - } - PRectangle rcSelMargin = GetClientRectangle(); - rcSelMargin.right = static_cast(vs.textStart); - return PaintContains(rcSelMargin); -} - -void Editor::CheckForChangeOutsidePaint(Range r) { - if (paintState == painting && !paintingAllText) { - //Platform::DebugPrintf("Checking range in paint %d-%d\n", r.start, r.end); - if (!r.Valid()) - return; - - PRectangle rcRange = RectangleFromRange(r, 0); - PRectangle rcText = GetTextRectangle(); - if (rcRange.top < rcText.top) { - rcRange.top = rcText.top; - } - if (rcRange.bottom > rcText.bottom) { - rcRange.bottom = rcText.bottom; - } - - if (!PaintContains(rcRange)) { - AbandonPaint(); - paintAbandonedByStyling = true; - } - } -} - -void Editor::SetBraceHighlight(Position pos0, Position pos1, int matchStyle) { - if ((pos0 != braces[0]) || (pos1 != braces[1]) || (matchStyle != bracesMatchStyle)) { - if ((braces[0] != pos0) || (matchStyle != bracesMatchStyle)) { - CheckForChangeOutsidePaint(Range(braces[0])); - CheckForChangeOutsidePaint(Range(pos0)); - braces[0] = pos0; - } - if ((braces[1] != pos1) || (matchStyle != bracesMatchStyle)) { - CheckForChangeOutsidePaint(Range(braces[1])); - CheckForChangeOutsidePaint(Range(pos1)); - braces[1] = pos1; - } - bracesMatchStyle = matchStyle; - if (paintState == notPainting) { - Redraw(); - } - } -} - -void Editor::SetAnnotationHeights(int start, int end) { - if (vs.annotationVisible) { - RefreshStyleData(); - bool changedHeight = false; - for (int line=start; lineLinesTotal(); line++) { - int linesWrapped = 1; - if (Wrapping()) { - AutoSurface surface(this); - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this)); - if (surface && ll) { - view.LayoutLine(*this, line, surface, vs, ll, wrapWidth); - linesWrapped = ll->lines; - } - } - if (cs.SetHeight(line, pdoc->AnnotationLines(line) + linesWrapped)) - changedHeight = true; - } - if (changedHeight) { - Redraw(); - } - } -} - -void Editor::SetDocPointer(Document *document) { - //Platform::DebugPrintf("** %x setdoc to %x\n", pdoc, document); - pdoc->RemoveWatcher(this, 0); - pdoc->Release(); - if (document == NULL) { - pdoc = new Document(); - } else { - pdoc = document; - } - pdoc->AddRef(); - - // Ensure all positions within document - sel.Clear(); - targetStart = 0; - targetEnd = 0; - - braces[0] = invalidPosition; - braces[1] = invalidPosition; - - vs.ReleaseAllExtendedStyles(); - - SetRepresentations(); - - // Reset the contraction state to fully shown. - cs.Clear(); - cs.InsertLines(0, pdoc->LinesTotal() - 1); - SetAnnotationHeights(0, pdoc->LinesTotal()); - view.llc.Deallocate(); - NeedWrapping(); - - hotspot = Range(invalidPosition); - hoverIndicatorPos = invalidPosition; - - view.ClearAllTabstops(); - - pdoc->AddWatcher(this, 0); - SetScrollBars(); - Redraw(); -} - -void Editor::SetAnnotationVisible(int visible) { - if (vs.annotationVisible != visible) { - bool changedFromOrToHidden = ((vs.annotationVisible != 0) != (visible != 0)); - vs.annotationVisible = visible; - if (changedFromOrToHidden) { - int dir = vs.annotationVisible ? 1 : -1; - for (int line=0; lineLinesTotal(); line++) { - int annotationLines = pdoc->AnnotationLines(line); - if (annotationLines > 0) { - cs.SetHeight(line, cs.GetHeight(line) + annotationLines * dir); - } - } - } - Redraw(); - } -} - -/** - * Recursively expand a fold, making lines visible except where they have an unexpanded parent. - */ -int Editor::ExpandLine(int line) { - int lineMaxSubord = pdoc->GetLastChild(line); - line++; - while (line <= lineMaxSubord) { - cs.SetVisible(line, line, true); - int level = pdoc->GetLevel(line); - if (level & SC_FOLDLEVELHEADERFLAG) { - if (cs.GetExpanded(line)) { - line = ExpandLine(line); - } else { - line = pdoc->GetLastChild(line); - } - } - line++; - } - return lineMaxSubord; -} - -void Editor::SetFoldExpanded(int lineDoc, bool expanded) { - if (cs.SetExpanded(lineDoc, expanded)) { - RedrawSelMargin(); - } -} - -void Editor::FoldLine(int line, int action) { - if (line >= 0) { - if (action == SC_FOLDACTION_TOGGLE) { - if ((pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG) == 0) { - line = pdoc->GetFoldParent(line); - if (line < 0) - return; - } - action = (cs.GetExpanded(line)) ? SC_FOLDACTION_CONTRACT : SC_FOLDACTION_EXPAND; - } - - if (action == SC_FOLDACTION_CONTRACT) { - int lineMaxSubord = pdoc->GetLastChild(line); - if (lineMaxSubord > line) { - cs.SetExpanded(line, 0); - cs.SetVisible(line + 1, lineMaxSubord, false); - - int lineCurrent = pdoc->LineFromPosition(sel.MainCaret()); - if (lineCurrent > line && lineCurrent <= lineMaxSubord) { - // This does not re-expand the fold - EnsureCaretVisible(); - } - } - - } else { - if (!(cs.GetVisible(line))) { - EnsureLineVisible(line, false); - GoToLine(line); - } - cs.SetExpanded(line, 1); - ExpandLine(line); - } - - SetScrollBars(); - Redraw(); - } -} - -void Editor::FoldExpand(int line, int action, int level) { - bool expanding = action == SC_FOLDACTION_EXPAND; - if (action == SC_FOLDACTION_TOGGLE) { - expanding = !cs.GetExpanded(line); - } - // Ensure child lines lexed and fold information extracted before - // flipping the state. - pdoc->GetLastChild(line, LevelNumber(level)); - SetFoldExpanded(line, expanding); - if (expanding && (cs.HiddenLines() == 0)) - // Nothing to do - return; - int lineMaxSubord = pdoc->GetLastChild(line, LevelNumber(level)); - line++; - cs.SetVisible(line, lineMaxSubord, expanding); - while (line <= lineMaxSubord) { - int levelLine = pdoc->GetLevel(line); - if (levelLine & SC_FOLDLEVELHEADERFLAG) { - SetFoldExpanded(line, expanding); - } - line++; - } - SetScrollBars(); - Redraw(); -} - -int Editor::ContractedFoldNext(int lineStart) const { - for (int line = lineStart; lineLinesTotal();) { - if (!cs.GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG)) - return line; - line = cs.ContractedNext(line+1); - if (line < 0) - return -1; - } - - return -1; -} - -/** - * Recurse up from this line to find any folds that prevent this line from being visible - * and unfold them all. - */ -void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) { - - // In case in need of wrapping to ensure DisplayFromDoc works. - if (lineDoc >= wrapPending.start) - WrapLines(wsAll); - - if (!cs.GetVisible(lineDoc)) { - // Back up to find a non-blank line - int lookLine = lineDoc; - int lookLineLevel = pdoc->GetLevel(lookLine); - while ((lookLine > 0) && (lookLineLevel & SC_FOLDLEVELWHITEFLAG)) { - lookLineLevel = pdoc->GetLevel(--lookLine); - } - int lineParent = pdoc->GetFoldParent(lookLine); - if (lineParent < 0) { - // Backed up to a top level line, so try to find parent of initial line - lineParent = pdoc->GetFoldParent(lineDoc); - } - if (lineParent >= 0) { - if (lineDoc != lineParent) - EnsureLineVisible(lineParent, enforcePolicy); - if (!cs.GetExpanded(lineParent)) { - cs.SetExpanded(lineParent, 1); - ExpandLine(lineParent); - } - } - SetScrollBars(); - Redraw(); - } - if (enforcePolicy) { - int lineDisplay = cs.DisplayFromDoc(lineDoc); - if (visiblePolicy & VISIBLE_SLOP) { - if ((topLine > lineDisplay) || ((visiblePolicy & VISIBLE_STRICT) && (topLine + visibleSlop > lineDisplay))) { - SetTopLine(Platform::Clamp(lineDisplay - visibleSlop, 0, MaxScrollPos())); - SetVerticalScrollPos(); - Redraw(); - } else if ((lineDisplay > topLine + LinesOnScreen() - 1) || - ((visiblePolicy & VISIBLE_STRICT) && (lineDisplay > topLine + LinesOnScreen() - 1 - visibleSlop))) { - SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() + 1 + visibleSlop, 0, MaxScrollPos())); - SetVerticalScrollPos(); - Redraw(); - } - } else { - if ((topLine > lineDisplay) || (lineDisplay > topLine + LinesOnScreen() - 1) || (visiblePolicy & VISIBLE_STRICT)) { - SetTopLine(Platform::Clamp(lineDisplay - LinesOnScreen() / 2 + 1, 0, MaxScrollPos())); - SetVerticalScrollPos(); - Redraw(); - } - } - } -} - -void Editor::FoldAll(int action) { - pdoc->EnsureStyledTo(pdoc->Length()); - int maxLine = pdoc->LinesTotal(); - bool expanding = action == SC_FOLDACTION_EXPAND; - if (action == SC_FOLDACTION_TOGGLE) { - // Discover current state - for (int lineSeek = 0; lineSeek < maxLine; lineSeek++) { - if (pdoc->GetLevel(lineSeek) & SC_FOLDLEVELHEADERFLAG) { - expanding = !cs.GetExpanded(lineSeek); - break; - } - } - } - if (expanding) { - cs.SetVisible(0, maxLine-1, true); - for (int line = 0; line < maxLine; line++) { - int levelLine = pdoc->GetLevel(line); - if (levelLine & SC_FOLDLEVELHEADERFLAG) { - SetFoldExpanded(line, true); - } - } - } else { - for (int line = 0; line < maxLine; line++) { - int level = pdoc->GetLevel(line); - if ((level & SC_FOLDLEVELHEADERFLAG) && - (SC_FOLDLEVELBASE == LevelNumber(level))) { - SetFoldExpanded(line, false); - int lineMaxSubord = pdoc->GetLastChild(line, -1); - if (lineMaxSubord > line) { - cs.SetVisible(line + 1, lineMaxSubord, false); - } - } - } - } - SetScrollBars(); - Redraw(); -} - -void Editor::FoldChanged(int line, int levelNow, int levelPrev) { - if (levelNow & SC_FOLDLEVELHEADERFLAG) { - if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) { - // Adding a fold point. - if (cs.SetExpanded(line, true)) { - RedrawSelMargin(); - } - FoldExpand(line, SC_FOLDACTION_EXPAND, levelPrev); - } - } else if (levelPrev & SC_FOLDLEVELHEADERFLAG) { - const int prevLine = line - 1; - const int prevLineLevel = pdoc->GetLevel(prevLine); - - // Combining two blocks where the first block is collapsed (e.g. by deleting the line(s) which separate(s) the two blocks) - if ((LevelNumber(prevLineLevel) == LevelNumber(levelNow)) && !cs.GetVisible(prevLine)) - FoldLine(pdoc->GetFoldParent(prevLine), SC_FOLDACTION_EXPAND); - - if (!cs.GetExpanded(line)) { - // Removing the fold from one that has been contracted so should expand - // otherwise lines are left invisible with no way to make them visible - if (cs.SetExpanded(line, true)) { - RedrawSelMargin(); - } - // Combining two blocks where the second one is collapsed (e.g. by adding characters in the line which separates the two blocks) - FoldExpand(line, SC_FOLDACTION_EXPAND, levelPrev); - } - } - if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && - (LevelNumber(levelPrev) > LevelNumber(levelNow))) { - if (cs.HiddenLines()) { - // See if should still be hidden - int parentLine = pdoc->GetFoldParent(line); - if ((parentLine < 0) || (cs.GetExpanded(parentLine) && cs.GetVisible(parentLine))) { - cs.SetVisible(line, line, true); - SetScrollBars(); - Redraw(); - } - } - } - - // Combining two blocks where the first one is collapsed (e.g. by adding characters in the line which separates the two blocks) - if (!(levelNow & SC_FOLDLEVELWHITEFLAG) && (LevelNumber(levelPrev) < LevelNumber(levelNow))) { - if (cs.HiddenLines()) { - const int parentLine = pdoc->GetFoldParent(line); - if (!cs.GetExpanded(parentLine) && cs.GetExpanded(line)) - FoldLine(parentLine, SC_FOLDACTION_EXPAND); - } - } -} - -void Editor::NeedShown(int pos, int len) { - if (foldAutomatic & SC_AUTOMATICFOLD_SHOW) { - int lineStart = pdoc->LineFromPosition(pos); - int lineEnd = pdoc->LineFromPosition(pos+len); - for (int line = lineStart; line <= lineEnd; line++) { - EnsureLineVisible(line, false); - } - } else { - NotifyNeedShown(pos, len); - } -} - -int Editor::GetTag(char *tagValue, int tagNumber) { - const char *text = 0; - int length = 0; - if ((tagNumber >= 1) && (tagNumber <= 9)) { - char name[3] = "\\?"; - name[1] = static_cast(tagNumber + '0'); - length = 2; - text = pdoc->SubstituteByPosition(name, &length); - } - if (tagValue) { - if (text) - memcpy(tagValue, text, length + 1); - else - *tagValue = '\0'; - } - return length; -} - -int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) { - UndoGroup ug(pdoc); - if (length == -1) - length = istrlen(text); - if (replacePatterns) { - text = pdoc->SubstituteByPosition(text, &length); - if (!text) { - return 0; - } - } - if (targetStart != targetEnd) - pdoc->DeleteChars(targetStart, targetEnd - targetStart); - targetEnd = targetStart; - const int lengthInserted = pdoc->InsertString(targetStart, text, length); - targetEnd = targetStart + lengthInserted; - return length; -} - -bool Editor::IsUnicodeMode() const { - return pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage); -} - -int Editor::CodePage() const { - if (pdoc) - return pdoc->dbcsCodePage; - else - return 0; -} - -int Editor::WrapCount(int line) { - AutoSurface surface(this); - AutoLineLayout ll(view.llc, view.RetrieveLineLayout(line, *this)); - - if (surface && ll) { - view.LayoutLine(*this, line, surface, vs, ll, wrapWidth); - return ll->lines; - } else { - return 1; - } -} - -void Editor::AddStyledText(char *buffer, int appendLength) { - // The buffer consists of alternating character bytes and style bytes - int textLength = appendLength / 2; - std::string text(textLength, '\0'); - int i; - for (i = 0; i < textLength; i++) { - text[i] = buffer[i*2]; - } - const int lengthInserted = pdoc->InsertString(CurrentPosition(), text.c_str(), textLength); - for (i = 0; i < textLength; i++) { - text[i] = buffer[i*2+1]; - } - pdoc->StartStyling(CurrentPosition(), static_cast(0xff)); - pdoc->SetStyles(textLength, text.c_str()); - SetEmptySelection(sel.MainCaret() + lengthInserted); -} - -bool Editor::ValidMargin(uptr_t wParam) const { - return wParam < vs.ms.size(); -} - -static char *CharPtrFromSPtr(sptr_t lParam) { - return reinterpret_cast(lParam); -} - -void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - vs.EnsureStyle(wParam); - switch (iMessage) { - case SCI_STYLESETFORE: - vs.styles[wParam].fore = ColourDesired(static_cast(lParam)); - break; - case SCI_STYLESETBACK: - vs.styles[wParam].back = ColourDesired(static_cast(lParam)); - break; - case SCI_STYLESETBOLD: - vs.styles[wParam].weight = lParam != 0 ? SC_WEIGHT_BOLD : SC_WEIGHT_NORMAL; - break; - case SCI_STYLESETWEIGHT: - vs.styles[wParam].weight = static_cast(lParam); - break; - case SCI_STYLESETITALIC: - vs.styles[wParam].italic = lParam != 0; - break; - case SCI_STYLESETEOLFILLED: - vs.styles[wParam].eolFilled = lParam != 0; - break; - case SCI_STYLESETSIZE: - vs.styles[wParam].size = static_cast(lParam * SC_FONT_SIZE_MULTIPLIER); - break; - case SCI_STYLESETSIZEFRACTIONAL: - vs.styles[wParam].size = static_cast(lParam); - break; - case SCI_STYLESETFONT: - if (lParam != 0) { - vs.SetStyleFontName(static_cast(wParam), CharPtrFromSPtr(lParam)); - } - break; - case SCI_STYLESETUNDERLINE: - vs.styles[wParam].underline = lParam != 0; - break; - case SCI_STYLESETCASE: - vs.styles[wParam].caseForce = static_cast(lParam); - break; - case SCI_STYLESETCHARACTERSET: - vs.styles[wParam].characterSet = static_cast(lParam); - pdoc->SetCaseFolder(NULL); - break; - case SCI_STYLESETVISIBLE: - vs.styles[wParam].visible = lParam != 0; - break; - case SCI_STYLESETCHANGEABLE: - vs.styles[wParam].changeable = lParam != 0; - break; - case SCI_STYLESETHOTSPOT: - vs.styles[wParam].hotspot = lParam != 0; - break; - } - InvalidateStyleRedraw(); -} - -sptr_t Editor::StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - vs.EnsureStyle(wParam); - switch (iMessage) { - case SCI_STYLEGETFORE: - return vs.styles[wParam].fore.AsLong(); - case SCI_STYLEGETBACK: - return vs.styles[wParam].back.AsLong(); - case SCI_STYLEGETBOLD: - return vs.styles[wParam].weight > SC_WEIGHT_NORMAL; - case SCI_STYLEGETWEIGHT: - return vs.styles[wParam].weight; - case SCI_STYLEGETITALIC: - return vs.styles[wParam].italic ? 1 : 0; - case SCI_STYLEGETEOLFILLED: - return vs.styles[wParam].eolFilled ? 1 : 0; - case SCI_STYLEGETSIZE: - return vs.styles[wParam].size / SC_FONT_SIZE_MULTIPLIER; - case SCI_STYLEGETSIZEFRACTIONAL: - return vs.styles[wParam].size; - case SCI_STYLEGETFONT: - return StringResult(lParam, vs.styles[wParam].fontName); - case SCI_STYLEGETUNDERLINE: - return vs.styles[wParam].underline ? 1 : 0; - case SCI_STYLEGETCASE: - return static_cast(vs.styles[wParam].caseForce); - case SCI_STYLEGETCHARACTERSET: - return vs.styles[wParam].characterSet; - case SCI_STYLEGETVISIBLE: - return vs.styles[wParam].visible ? 1 : 0; - case SCI_STYLEGETCHANGEABLE: - return vs.styles[wParam].changeable ? 1 : 0; - case SCI_STYLEGETHOTSPOT: - return vs.styles[wParam].hotspot ? 1 : 0; - } - return 0; -} - -void Editor::SetSelectionNMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - InvalidateRange(sel.Range(wParam).Start().Position(), sel.Range(wParam).End().Position()); - - switch (iMessage) { - case SCI_SETSELECTIONNCARET: - sel.Range(wParam).caret.SetPosition(static_cast(lParam)); - break; - - case SCI_SETSELECTIONNANCHOR: - sel.Range(wParam).anchor.SetPosition(static_cast(lParam)); - break; - - case SCI_SETSELECTIONNCARETVIRTUALSPACE: - sel.Range(wParam).caret.SetVirtualSpace(static_cast(lParam)); - break; - - case SCI_SETSELECTIONNANCHORVIRTUALSPACE: - sel.Range(wParam).anchor.SetVirtualSpace(static_cast(lParam)); - break; - - case SCI_SETSELECTIONNSTART: - sel.Range(wParam).anchor.SetPosition(static_cast(lParam)); - break; - - case SCI_SETSELECTIONNEND: - sel.Range(wParam).caret.SetPosition(static_cast(lParam)); - break; - } - - InvalidateRange(sel.Range(wParam).Start().Position(), sel.Range(wParam).End().Position()); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); -} - -sptr_t Editor::StringResult(sptr_t lParam, const char *val) { - const size_t len = val ? strlen(val) : 0; - if (lParam) { - char *ptr = CharPtrFromSPtr(lParam); - if (val) - memcpy(ptr, val, len+1); - else - *ptr = 0; - } - return len; // Not including NUL -} - -sptr_t Editor::BytesResult(sptr_t lParam, const unsigned char *val, size_t len) { - // No NUL termination: len is number of valid/displayed bytes - if ((lParam) && (len > 0)) { - char *ptr = CharPtrFromSPtr(lParam); - if (val) - memcpy(ptr, val, len); - else - *ptr = 0; - } - return val ? len : 0; -} - -sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - //Platform::DebugPrintf("S start wnd proc %d %d %d\n",iMessage, wParam, lParam); - - // Optional macro recording hook - if (recordingMacro) - NotifyMacroRecord(iMessage, wParam, lParam); - - switch (iMessage) { - - case SCI_GETTEXT: { - if (lParam == 0) - return pdoc->Length() + 1; - if (wParam == 0) - return 0; - char *ptr = CharPtrFromSPtr(lParam); - unsigned int iChar = 0; - for (; iChar < wParam - 1; iChar++) - ptr[iChar] = pdoc->CharAt(iChar); - ptr[iChar] = '\0'; - return iChar; - } - - case SCI_SETTEXT: { - if (lParam == 0) - return 0; - UndoGroup ug(pdoc); - pdoc->DeleteChars(0, pdoc->Length()); - SetEmptySelection(0); - const char *text = CharPtrFromSPtr(lParam); - pdoc->InsertString(0, text, istrlen(text)); - return 1; - } - - case SCI_GETTEXTLENGTH: - return pdoc->Length(); - - case SCI_CUT: - Cut(); - SetLastXChosen(); - break; - - case SCI_COPY: - Copy(); - break; - - case SCI_COPYALLOWLINE: - CopyAllowLine(); - break; - - case SCI_VERTICALCENTRECARET: - VerticalCentreCaret(); - break; - - case SCI_MOVESELECTEDLINESUP: - MoveSelectedLinesUp(); - break; - - case SCI_MOVESELECTEDLINESDOWN: - MoveSelectedLinesDown(); - break; - - case SCI_COPYRANGE: - CopyRangeToClipboard(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_COPYTEXT: - CopyText(static_cast(wParam), CharPtrFromSPtr(lParam)); - break; - - case SCI_PASTE: - Paste(); - if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) { - SetLastXChosen(); - } - EnsureCaretVisible(); - break; - - case SCI_CLEAR: - Clear(); - SetLastXChosen(); - EnsureCaretVisible(); - break; - - case SCI_UNDO: - Undo(); - SetLastXChosen(); - break; - - case SCI_CANUNDO: - return (pdoc->CanUndo() && !pdoc->IsReadOnly()) ? 1 : 0; - - case SCI_EMPTYUNDOBUFFER: - pdoc->DeleteUndoHistory(); - return 0; - - case SCI_GETFIRSTVISIBLELINE: - return topLine; - - case SCI_SETFIRSTVISIBLELINE: - ScrollTo(static_cast(wParam)); - break; - - case SCI_GETLINE: { // Risk of overwriting the end of the buffer - int lineStart = pdoc->LineStart(static_cast(wParam)); - int lineEnd = pdoc->LineStart(static_cast(wParam + 1)); - if (lParam == 0) { - return lineEnd - lineStart; - } - char *ptr = CharPtrFromSPtr(lParam); - int iPlace = 0; - for (int iChar = lineStart; iChar < lineEnd; iChar++) { - ptr[iPlace++] = pdoc->CharAt(iChar); - } - return iPlace; - } - - case SCI_GETLINECOUNT: - if (pdoc->LinesTotal() == 0) - return 1; - else - return pdoc->LinesTotal(); - - case SCI_GETMODIFY: - return !pdoc->IsSavePoint(); - - case SCI_SETSEL: { - int nStart = static_cast(wParam); - int nEnd = static_cast(lParam); - if (nEnd < 0) - nEnd = pdoc->Length(); - if (nStart < 0) - nStart = nEnd; // Remove selection - InvalidateSelection(SelectionRange(nStart, nEnd)); - sel.Clear(); - sel.selType = Selection::selStream; - SetSelection(nEnd, nStart); - EnsureCaretVisible(); - } - break; - - case SCI_GETSELTEXT: { - SelectionText selectedText; - CopySelectionRange(&selectedText); - if (lParam == 0) { - return selectedText.LengthWithTerminator(); - } else { - char *ptr = CharPtrFromSPtr(lParam); - unsigned int iChar = 0; - if (selectedText.Length()) { - for (; iChar < selectedText.LengthWithTerminator(); iChar++) - ptr[iChar] = selectedText.Data()[iChar]; - } else { - ptr[0] = '\0'; - } - return iChar; - } - } - - case SCI_LINEFROMPOSITION: - if (static_cast(wParam) < 0) - return 0; - return pdoc->LineFromPosition(static_cast(wParam)); - - case SCI_POSITIONFROMLINE: - if (static_cast(wParam) < 0) - wParam = pdoc->LineFromPosition(SelectionStart().Position()); - if (wParam == 0) - return 0; // Even if there is no text, there is a first line that starts at 0 - if (static_cast(wParam) > pdoc->LinesTotal()) - return -1; - //if (wParam > pdoc->LineFromPosition(pdoc->Length())) // Useful test, anyway... - // return -1; - return pdoc->LineStart(static_cast(wParam)); - - // Replacement of the old Scintilla interpretation of EM_LINELENGTH - case SCI_LINELENGTH: - if ((static_cast(wParam) < 0) || - (static_cast(wParam) > pdoc->LineFromPosition(pdoc->Length()))) - return 0; - return pdoc->LineStart(static_cast(wParam) + 1) - pdoc->LineStart(static_cast(wParam)); - - case SCI_REPLACESEL: { - if (lParam == 0) - return 0; - UndoGroup ug(pdoc); - ClearSelection(); - char *replacement = CharPtrFromSPtr(lParam); - const int lengthInserted = pdoc->InsertString( - sel.MainCaret(), replacement, istrlen(replacement)); - SetEmptySelection(sel.MainCaret() + lengthInserted); - EnsureCaretVisible(); - } - break; - - case SCI_SETTARGETSTART: - targetStart = static_cast(wParam); - break; - - case SCI_GETTARGETSTART: - return targetStart; - - case SCI_SETTARGETEND: - targetEnd = static_cast(wParam); - break; - - case SCI_GETTARGETEND: - return targetEnd; - - case SCI_SETTARGETRANGE: - targetStart = static_cast(wParam); - targetEnd = static_cast(lParam); - break; - - case SCI_TARGETWHOLEDOCUMENT: - targetStart = 0; - targetEnd = pdoc->Length(); - break; - - case SCI_TARGETFROMSELECTION: - if (sel.MainCaret() < sel.MainAnchor()) { - targetStart = sel.MainCaret(); - targetEnd = sel.MainAnchor(); - } else { - targetStart = sel.MainAnchor(); - targetEnd = sel.MainCaret(); - } - break; - - case SCI_GETTARGETTEXT: { - std::string text = RangeText(targetStart, targetEnd); - return BytesResult(lParam, reinterpret_cast(text.c_str()), text.length()); - } - - case SCI_REPLACETARGET: - PLATFORM_ASSERT(lParam); - return ReplaceTarget(false, CharPtrFromSPtr(lParam), static_cast(wParam)); - - case SCI_REPLACETARGETRE: - PLATFORM_ASSERT(lParam); - return ReplaceTarget(true, CharPtrFromSPtr(lParam), static_cast(wParam)); - - case SCI_SEARCHINTARGET: - PLATFORM_ASSERT(lParam); - return SearchInTarget(CharPtrFromSPtr(lParam), static_cast(wParam)); - - case SCI_SETSEARCHFLAGS: - searchFlags = static_cast(wParam); - break; - - case SCI_GETSEARCHFLAGS: - return searchFlags; - - case SCI_GETTAG: - return GetTag(CharPtrFromSPtr(lParam), static_cast(wParam)); - - case SCI_POSITIONBEFORE: - return pdoc->MovePositionOutsideChar(static_cast(wParam) - 1, -1, true); - - case SCI_POSITIONAFTER: - return pdoc->MovePositionOutsideChar(static_cast(wParam) + 1, 1, true); - - case SCI_POSITIONRELATIVE: - return Platform::Clamp(pdoc->GetRelativePosition(static_cast(wParam), static_cast(lParam)), 0, pdoc->Length()); - - case SCI_LINESCROLL: - ScrollTo(topLine + static_cast(lParam)); - HorizontalScrollTo(xOffset + static_cast(wParam)* static_cast(vs.spaceWidth)); - return 1; - - case SCI_SETXOFFSET: - xOffset = static_cast(wParam); - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); - SetHorizontalScrollPos(); - Redraw(); - break; - - case SCI_GETXOFFSET: - return xOffset; - - case SCI_CHOOSECARETX: - SetLastXChosen(); - break; - - case SCI_SCROLLCARET: - EnsureCaretVisible(); - break; - - case SCI_SETREADONLY: - pdoc->SetReadOnly(wParam != 0); - return 1; - - case SCI_GETREADONLY: - return pdoc->IsReadOnly(); - - case SCI_CANPASTE: - return CanPaste(); - - case SCI_POINTXFROMPOSITION: - if (lParam < 0) { - return 0; - } else { - Point pt = LocationFromPosition(static_cast(lParam)); - // Convert to view-relative - return static_cast(pt.x) - vs.textStart + vs.fixedColumnWidth; - } - - case SCI_POINTYFROMPOSITION: - if (lParam < 0) { - return 0; - } else { - Point pt = LocationFromPosition(static_cast(lParam)); - return static_cast(pt.y); - } - - case SCI_FINDTEXT: - return FindText(wParam, lParam); - - case SCI_GETTEXTRANGE: { - if (lParam == 0) - return 0; - Sci_TextRange *tr = reinterpret_cast(lParam); - int cpMax = static_cast(tr->chrg.cpMax); - if (cpMax == -1) - cpMax = pdoc->Length(); - PLATFORM_ASSERT(cpMax <= pdoc->Length()); - int len = static_cast(cpMax - tr->chrg.cpMin); // No -1 as cpMin and cpMax are referring to inter character positions - pdoc->GetCharRange(tr->lpstrText, static_cast(tr->chrg.cpMin), len); - // Spec says copied text is terminated with a NUL - tr->lpstrText[len] = '\0'; - return len; // Not including NUL - } - - case SCI_HIDESELECTION: - view.hideSelection = wParam != 0; - Redraw(); - break; - - case SCI_FORMATRANGE: - return FormatRange(wParam != 0, reinterpret_cast(lParam)); - - case SCI_GETMARGINLEFT: - return vs.leftMarginWidth; - - case SCI_GETMARGINRIGHT: - return vs.rightMarginWidth; - - case SCI_SETMARGINLEFT: - lastXChosen += static_cast(lParam) - vs.leftMarginWidth; - vs.leftMarginWidth = static_cast(lParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETMARGINRIGHT: - vs.rightMarginWidth = static_cast(lParam); - InvalidateStyleRedraw(); - break; - - // Control specific mesages - - case SCI_ADDTEXT: { - if (lParam == 0) - return 0; - const int lengthInserted = pdoc->InsertString( - CurrentPosition(), CharPtrFromSPtr(lParam), static_cast(wParam)); - SetEmptySelection(sel.MainCaret() + lengthInserted); - return 0; - } - - case SCI_ADDSTYLEDTEXT: - if (lParam) - AddStyledText(CharPtrFromSPtr(lParam), static_cast(wParam)); - return 0; - - case SCI_INSERTTEXT: { - if (lParam == 0) - return 0; - int insertPos = static_cast(wParam); - if (static_cast(wParam) == -1) - insertPos = CurrentPosition(); - int newCurrent = CurrentPosition(); - char *sz = CharPtrFromSPtr(lParam); - const int lengthInserted = pdoc->InsertString(insertPos, sz, istrlen(sz)); - if (newCurrent > insertPos) - newCurrent += lengthInserted; - SetEmptySelection(newCurrent); - return 0; - } - - case SCI_CHANGEINSERTION: - PLATFORM_ASSERT(lParam); - pdoc->ChangeInsertion(CharPtrFromSPtr(lParam), static_cast(wParam)); - return 0; - - case SCI_APPENDTEXT: - pdoc->InsertString(pdoc->Length(), CharPtrFromSPtr(lParam), static_cast(wParam)); - return 0; - - case SCI_CLEARALL: - ClearAll(); - return 0; - - case SCI_DELETERANGE: - pdoc->DeleteChars(static_cast(wParam), static_cast(lParam)); - return 0; - - case SCI_CLEARDOCUMENTSTYLE: - ClearDocumentStyle(); - return 0; - - case SCI_SETUNDOCOLLECTION: - pdoc->SetUndoCollection(wParam != 0); - return 0; - - case SCI_GETUNDOCOLLECTION: - return pdoc->IsCollectingUndo(); - - case SCI_BEGINUNDOACTION: - pdoc->BeginUndoAction(); - return 0; - - case SCI_ENDUNDOACTION: - pdoc->EndUndoAction(); - return 0; - - case SCI_GETCARETPERIOD: - return caret.period; - - case SCI_SETCARETPERIOD: - CaretSetPeriod(static_cast(wParam)); - break; - - case SCI_GETWORDCHARS: - return pdoc->GetCharsOfClass(CharClassify::ccWord, reinterpret_cast(lParam)); - - case SCI_SETWORDCHARS: { - pdoc->SetDefaultCharClasses(false); - if (lParam == 0) - return 0; - pdoc->SetCharClasses(reinterpret_cast(lParam), CharClassify::ccWord); - } - break; - - case SCI_GETWHITESPACECHARS: - return pdoc->GetCharsOfClass(CharClassify::ccSpace, reinterpret_cast(lParam)); - - case SCI_SETWHITESPACECHARS: { - if (lParam == 0) - return 0; - pdoc->SetCharClasses(reinterpret_cast(lParam), CharClassify::ccSpace); - } - break; - - case SCI_GETPUNCTUATIONCHARS: - return pdoc->GetCharsOfClass(CharClassify::ccPunctuation, reinterpret_cast(lParam)); - - case SCI_SETPUNCTUATIONCHARS: { - if (lParam == 0) - return 0; - pdoc->SetCharClasses(reinterpret_cast(lParam), CharClassify::ccPunctuation); - } - break; - - case SCI_SETCHARSDEFAULT: - pdoc->SetDefaultCharClasses(true); - break; - - case SCI_GETLENGTH: - return pdoc->Length(); - - case SCI_ALLOCATE: - pdoc->Allocate(static_cast(wParam)); - break; - - case SCI_GETCHARAT: - return pdoc->CharAt(static_cast(wParam)); - - case SCI_SETCURRENTPOS: - if (sel.IsRectangular()) { - sel.Rectangular().caret.SetPosition(static_cast(wParam)); - SetRectangularRange(); - Redraw(); - } else { - SetSelection(static_cast(wParam), sel.MainAnchor()); - } - break; - - case SCI_GETCURRENTPOS: - return sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret(); - - case SCI_SETANCHOR: - if (sel.IsRectangular()) { - sel.Rectangular().anchor.SetPosition(static_cast(wParam)); - SetRectangularRange(); - Redraw(); - } else { - SetSelection(sel.MainCaret(), static_cast(wParam)); - } - break; - - case SCI_GETANCHOR: - return sel.IsRectangular() ? sel.Rectangular().anchor.Position() : sel.MainAnchor(); - - case SCI_SETSELECTIONSTART: - SetSelection(Platform::Maximum(sel.MainCaret(), static_cast(wParam)), static_cast(wParam)); - break; - - case SCI_GETSELECTIONSTART: - return sel.LimitsForRectangularElseMain().start.Position(); - - case SCI_SETSELECTIONEND: - SetSelection(static_cast(wParam), Platform::Minimum(sel.MainAnchor(), static_cast(wParam))); - break; - - case SCI_GETSELECTIONEND: - return sel.LimitsForRectangularElseMain().end.Position(); - - case SCI_SETEMPTYSELECTION: - SetEmptySelection(static_cast(wParam)); - break; - - case SCI_SETPRINTMAGNIFICATION: - view.printParameters.magnification = static_cast(wParam); - break; - - case SCI_GETPRINTMAGNIFICATION: - return view.printParameters.magnification; - - case SCI_SETPRINTCOLOURMODE: - view.printParameters.colourMode = static_cast(wParam); - break; - - case SCI_GETPRINTCOLOURMODE: - return view.printParameters.colourMode; - - case SCI_SETPRINTWRAPMODE: - view.printParameters.wrapState = (wParam == SC_WRAP_WORD) ? eWrapWord : eWrapNone; - break; - - case SCI_GETPRINTWRAPMODE: - return view.printParameters.wrapState; - - case SCI_GETSTYLEAT: - if (static_cast(wParam) >= pdoc->Length()) - return 0; - else - return pdoc->StyleAt(static_cast(wParam)); - - case SCI_REDO: - Redo(); - break; - - case SCI_SELECTALL: - SelectAll(); - break; - - case SCI_SETSAVEPOINT: - pdoc->SetSavePoint(); - break; - - case SCI_GETSTYLEDTEXT: { - if (lParam == 0) - return 0; - Sci_TextRange *tr = reinterpret_cast(lParam); - int iPlace = 0; - for (long iChar = tr->chrg.cpMin; iChar < tr->chrg.cpMax; iChar++) { - tr->lpstrText[iPlace++] = pdoc->CharAt(static_cast(iChar)); - tr->lpstrText[iPlace++] = pdoc->StyleAt(static_cast(iChar)); - } - tr->lpstrText[iPlace] = '\0'; - tr->lpstrText[iPlace + 1] = '\0'; - return iPlace; - } - - case SCI_CANREDO: - return (pdoc->CanRedo() && !pdoc->IsReadOnly()) ? 1 : 0; - - case SCI_MARKERLINEFROMHANDLE: - return pdoc->LineFromHandle(static_cast(wParam)); - - case SCI_MARKERDELETEHANDLE: - pdoc->DeleteMarkFromHandle(static_cast(wParam)); - break; - - case SCI_GETVIEWWS: - return vs.viewWhitespace; - - case SCI_SETVIEWWS: - vs.viewWhitespace = static_cast(wParam); - Redraw(); - break; - - case SCI_GETTABDRAWMODE: - return vs.tabDrawMode; - - case SCI_SETTABDRAWMODE: - vs.tabDrawMode = static_cast(wParam); - Redraw(); - break; - - case SCI_GETWHITESPACESIZE: - return vs.whitespaceSize; - - case SCI_SETWHITESPACESIZE: - vs.whitespaceSize = static_cast(wParam); - Redraw(); - break; - - case SCI_POSITIONFROMPOINT: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - false, false); - - case SCI_POSITIONFROMPOINTCLOSE: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - true, false); - - case SCI_CHARPOSITIONFROMPOINT: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - false, true); - - case SCI_CHARPOSITIONFROMPOINTCLOSE: - return PositionFromLocation(Point::FromInts(static_cast(wParam) - vs.ExternalMarginWidth(), static_cast(lParam)), - true, true); - - case SCI_GOTOLINE: - GoToLine(static_cast(wParam)); - break; - - case SCI_GOTOPOS: - SetEmptySelection(static_cast(wParam)); - EnsureCaretVisible(); - break; - - case SCI_GETCURLINE: { - int lineCurrentPos = pdoc->LineFromPosition(sel.MainCaret()); - int lineStart = pdoc->LineStart(lineCurrentPos); - unsigned int lineEnd = pdoc->LineStart(lineCurrentPos + 1); - if (lParam == 0) { - return 1 + lineEnd - lineStart; - } - PLATFORM_ASSERT(wParam > 0); - char *ptr = CharPtrFromSPtr(lParam); - unsigned int iPlace = 0; - for (unsigned int iChar = lineStart; iChar < lineEnd && iPlace < wParam - 1; iChar++) { - ptr[iPlace++] = pdoc->CharAt(iChar); - } - ptr[iPlace] = '\0'; - return sel.MainCaret() - lineStart; - } - - case SCI_GETENDSTYLED: - return pdoc->GetEndStyled(); - - case SCI_GETEOLMODE: - return pdoc->eolMode; - - case SCI_SETEOLMODE: - pdoc->eolMode = static_cast(wParam); - break; - - case SCI_SETLINEENDTYPESALLOWED: - if (pdoc->SetLineEndTypesAllowed(static_cast(wParam))) { - cs.Clear(); - cs.InsertLines(0, pdoc->LinesTotal() - 1); - SetAnnotationHeights(0, pdoc->LinesTotal()); - InvalidateStyleRedraw(); - } - break; - - case SCI_GETLINEENDTYPESALLOWED: - return pdoc->GetLineEndTypesAllowed(); - - case SCI_GETLINEENDTYPESACTIVE: - return pdoc->GetLineEndTypesActive(); - - case SCI_STARTSTYLING: - pdoc->StartStyling(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_SETSTYLING: - if (static_cast(wParam) < 0) - errorStatus = SC_STATUS_FAILURE; - else - pdoc->SetStyleFor(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_SETSTYLINGEX: // Specify a complete styling buffer - if (lParam == 0) - return 0; - pdoc->SetStyles(static_cast(wParam), CharPtrFromSPtr(lParam)); - break; - - case SCI_SETBUFFEREDDRAW: - view.bufferedDraw = wParam != 0; - break; - - case SCI_GETBUFFEREDDRAW: - return view.bufferedDraw; - - case SCI_GETTWOPHASEDRAW: - return view.phasesDraw == EditView::phasesTwo; - - case SCI_SETTWOPHASEDRAW: - if (view.SetTwoPhaseDraw(wParam != 0)) - InvalidateStyleRedraw(); - break; - - case SCI_GETPHASESDRAW: - return view.phasesDraw; - - case SCI_SETPHASESDRAW: - if (view.SetPhasesDraw(static_cast(wParam))) - InvalidateStyleRedraw(); - break; - - case SCI_SETFONTQUALITY: - vs.extraFontFlag &= ~SC_EFF_QUALITY_MASK; - vs.extraFontFlag |= (wParam & SC_EFF_QUALITY_MASK); - InvalidateStyleRedraw(); - break; - - case SCI_GETFONTQUALITY: - return (vs.extraFontFlag & SC_EFF_QUALITY_MASK); - - case SCI_SETTABWIDTH: - if (wParam > 0) { - pdoc->tabInChars = static_cast(wParam); - if (pdoc->indentInChars == 0) - pdoc->actualIndentInChars = pdoc->tabInChars; - } - InvalidateStyleRedraw(); - break; - - case SCI_GETTABWIDTH: - return pdoc->tabInChars; - - case SCI_CLEARTABSTOPS: - if (view.ClearTabstops(static_cast(wParam))) { - DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, 0, static_cast(wParam)); - NotifyModified(pdoc, mh, NULL); - } - break; - - case SCI_ADDTABSTOP: - if (view.AddTabstop(static_cast(wParam), static_cast(lParam))) { - DocModification mh(SC_MOD_CHANGETABSTOPS, 0, 0, 0, 0, static_cast(wParam)); - NotifyModified(pdoc, mh, NULL); - } - break; - - case SCI_GETNEXTTABSTOP: - return view.GetNextTabstop(static_cast(wParam), static_cast(lParam)); - - case SCI_SETINDENT: - pdoc->indentInChars = static_cast(wParam); - if (pdoc->indentInChars != 0) - pdoc->actualIndentInChars = pdoc->indentInChars; - else - pdoc->actualIndentInChars = pdoc->tabInChars; - InvalidateStyleRedraw(); - break; - - case SCI_GETINDENT: - return pdoc->indentInChars; - - case SCI_SETUSETABS: - pdoc->useTabs = wParam != 0; - InvalidateStyleRedraw(); - break; - - case SCI_GETUSETABS: - return pdoc->useTabs; - - case SCI_SETLINEINDENTATION: - pdoc->SetLineIndentation(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_GETLINEINDENTATION: - return pdoc->GetLineIndentation(static_cast(wParam)); - - case SCI_GETLINEINDENTPOSITION: - return pdoc->GetLineIndentPosition(static_cast(wParam)); - - case SCI_SETTABINDENTS: - pdoc->tabIndents = wParam != 0; - break; - - case SCI_GETTABINDENTS: - return pdoc->tabIndents; - - case SCI_SETBACKSPACEUNINDENTS: - pdoc->backspaceUnindents = wParam != 0; - break; - - case SCI_GETBACKSPACEUNINDENTS: - return pdoc->backspaceUnindents; - - case SCI_SETMOUSEDWELLTIME: - dwellDelay = static_cast(wParam); - ticksToDwell = dwellDelay; - break; - - case SCI_GETMOUSEDWELLTIME: - return dwellDelay; - - case SCI_WORDSTARTPOSITION: - return pdoc->ExtendWordSelect(static_cast(wParam), -1, lParam != 0); - - case SCI_WORDENDPOSITION: - return pdoc->ExtendWordSelect(static_cast(wParam), 1, lParam != 0); - - case SCI_ISRANGEWORD: - return pdoc->IsWordAt(static_cast(wParam), static_cast(lParam)); - - case SCI_SETIDLESTYLING: - idleStyling = static_cast(wParam); - break; - - case SCI_GETIDLESTYLING: - return idleStyling; - - case SCI_SETWRAPMODE: - if (vs.SetWrapState(static_cast(wParam))) { - xOffset = 0; - ContainerNeedsUpdate(SC_UPDATE_H_SCROLL); - InvalidateStyleRedraw(); - ReconfigureScrollBars(); - } - break; - - case SCI_GETWRAPMODE: - return vs.wrapState; - - case SCI_SETWRAPVISUALFLAGS: - if (vs.SetWrapVisualFlags(static_cast(wParam))) { - InvalidateStyleRedraw(); - ReconfigureScrollBars(); - } - break; - - case SCI_GETWRAPVISUALFLAGS: - return vs.wrapVisualFlags; - - case SCI_SETWRAPVISUALFLAGSLOCATION: - if (vs.SetWrapVisualFlagsLocation(static_cast(wParam))) { - InvalidateStyleRedraw(); - } - break; - - case SCI_GETWRAPVISUALFLAGSLOCATION: - return vs.wrapVisualFlagsLocation; - - case SCI_SETWRAPSTARTINDENT: - if (vs.SetWrapVisualStartIndent(static_cast(wParam))) { - InvalidateStyleRedraw(); - ReconfigureScrollBars(); - } - break; - - case SCI_GETWRAPSTARTINDENT: - return vs.wrapVisualStartIndent; - - case SCI_SETWRAPINDENTMODE: - if (vs.SetWrapIndentMode(static_cast(wParam))) { - InvalidateStyleRedraw(); - ReconfigureScrollBars(); - } - break; - - case SCI_GETWRAPINDENTMODE: - return vs.wrapIndentMode; - - case SCI_SETLAYOUTCACHE: - view.llc.SetLevel(static_cast(wParam)); - break; - - case SCI_GETLAYOUTCACHE: - return view.llc.GetLevel(); - - case SCI_SETPOSITIONCACHE: - view.posCache.SetSize(wParam); - break; - - case SCI_GETPOSITIONCACHE: - return view.posCache.GetSize(); - - case SCI_SETSCROLLWIDTH: - PLATFORM_ASSERT(wParam > 0); - if ((wParam > 0) && (wParam != static_cast(scrollWidth))) { - view.lineWidthMaxSeen = 0; - scrollWidth = static_cast(wParam); - SetScrollBars(); - } - break; - - case SCI_GETSCROLLWIDTH: - return scrollWidth; - - case SCI_SETSCROLLWIDTHTRACKING: - trackLineWidth = wParam != 0; - break; - - case SCI_GETSCROLLWIDTHTRACKING: - return trackLineWidth; - - case SCI_LINESJOIN: - LinesJoin(); - break; - - case SCI_LINESSPLIT: - LinesSplit(static_cast(wParam)); - break; - - case SCI_TEXTWIDTH: - PLATFORM_ASSERT(wParam < vs.styles.size()); - PLATFORM_ASSERT(lParam); - return TextWidth(static_cast(wParam), CharPtrFromSPtr(lParam)); - - case SCI_TEXTHEIGHT: - RefreshStyleData(); - return vs.lineHeight; - - case SCI_SETENDATLASTLINE: - PLATFORM_ASSERT((wParam == 0) || (wParam == 1)); - if (endAtLastLine != (wParam != 0)) { - endAtLastLine = wParam != 0; - SetScrollBars(); - } - break; - - case SCI_GETENDATLASTLINE: - return endAtLastLine; - - case SCI_SETCARETSTICKY: - PLATFORM_ASSERT(wParam <= SC_CARETSTICKY_WHITESPACE); - if (wParam <= SC_CARETSTICKY_WHITESPACE) { - caretSticky = static_cast(wParam); - } - break; - - case SCI_GETCARETSTICKY: - return caretSticky; - - case SCI_TOGGLECARETSTICKY: - caretSticky = !caretSticky; - break; - - case SCI_GETCOLUMN: - return pdoc->GetColumn(static_cast(wParam)); - - case SCI_FINDCOLUMN: - return pdoc->FindColumn(static_cast(wParam), static_cast(lParam)); - - case SCI_SETHSCROLLBAR : - if (horizontalScrollBarVisible != (wParam != 0)) { - horizontalScrollBarVisible = wParam != 0; - SetScrollBars(); - ReconfigureScrollBars(); - } - break; - - case SCI_GETHSCROLLBAR: - return horizontalScrollBarVisible; - - case SCI_SETVSCROLLBAR: - if (verticalScrollBarVisible != (wParam != 0)) { - verticalScrollBarVisible = wParam != 0; - SetScrollBars(); - ReconfigureScrollBars(); - if (verticalScrollBarVisible) - SetVerticalScrollPos(); - } - break; - - case SCI_GETVSCROLLBAR: - return verticalScrollBarVisible; - - case SCI_SETINDENTATIONGUIDES: - vs.viewIndentationGuides = IndentView(wParam); - Redraw(); - break; - - case SCI_GETINDENTATIONGUIDES: - return vs.viewIndentationGuides; - - case SCI_SETHIGHLIGHTGUIDE: - if ((highlightGuideColumn != static_cast(wParam)) || (wParam > 0)) { - highlightGuideColumn = static_cast(wParam); - Redraw(); - } - break; - - case SCI_GETHIGHLIGHTGUIDE: - return highlightGuideColumn; - - case SCI_GETLINEENDPOSITION: - return pdoc->LineEnd(static_cast(wParam)); - - case SCI_SETCODEPAGE: - if (ValidCodePage(static_cast(wParam))) { - if (pdoc->SetDBCSCodePage(static_cast(wParam))) { - cs.Clear(); - cs.InsertLines(0, pdoc->LinesTotal() - 1); - SetAnnotationHeights(0, pdoc->LinesTotal()); - InvalidateStyleRedraw(); - SetRepresentations(); - } - } - break; - - case SCI_GETCODEPAGE: - return pdoc->dbcsCodePage; - - case SCI_SETIMEINTERACTION: - imeInteraction = static_cast(wParam); - break; - - case SCI_GETIMEINTERACTION: - return imeInteraction; - - // Marker definition and setting - case SCI_MARKERDEFINE: - if (wParam <= MARKER_MAX) { - vs.markers[wParam].markType = static_cast(lParam); - vs.CalcLargestMarkerHeight(); - } - InvalidateStyleData(); - RedrawSelMargin(); - break; - - case SCI_MARKERSYMBOLDEFINED: - if (wParam <= MARKER_MAX) - return vs.markers[wParam].markType; - else - return 0; - - case SCI_MARKERSETFORE: - if (wParam <= MARKER_MAX) - vs.markers[wParam].fore = ColourDesired(static_cast(lParam)); - InvalidateStyleData(); - RedrawSelMargin(); - break; - case SCI_MARKERSETBACKSELECTED: - if (wParam <= MARKER_MAX) - vs.markers[wParam].backSelected = ColourDesired(static_cast(lParam)); - InvalidateStyleData(); - RedrawSelMargin(); - break; - case SCI_MARKERENABLEHIGHLIGHT: - marginView.highlightDelimiter.isEnabled = wParam == 1; - RedrawSelMargin(); - break; - case SCI_MARKERSETBACK: - if (wParam <= MARKER_MAX) - vs.markers[wParam].back = ColourDesired(static_cast(lParam)); - InvalidateStyleData(); - RedrawSelMargin(); - break; - case SCI_MARKERSETALPHA: - if (wParam <= MARKER_MAX) - vs.markers[wParam].alpha = static_cast(lParam); - InvalidateStyleRedraw(); - break; - case SCI_MARKERADD: { - int markerID = pdoc->AddMark(static_cast(wParam), static_cast(lParam)); - return markerID; - } - case SCI_MARKERADDSET: - if (lParam != 0) - pdoc->AddMarkSet(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_MARKERDELETE: - pdoc->DeleteMark(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_MARKERDELETEALL: - pdoc->DeleteAllMarks(static_cast(wParam)); - break; - - case SCI_MARKERGET: - return pdoc->GetMark(static_cast(wParam)); - - case SCI_MARKERNEXT: - return pdoc->MarkerNext(static_cast(wParam), static_cast(lParam)); - - case SCI_MARKERPREVIOUS: { - for (int iLine = static_cast(wParam); iLine >= 0; iLine--) { - if ((pdoc->GetMark(iLine) & lParam) != 0) - return iLine; - } - } - return -1; - - case SCI_MARKERDEFINEPIXMAP: - if (wParam <= MARKER_MAX) { - vs.markers[wParam].SetXPM(CharPtrFromSPtr(lParam)); - vs.CalcLargestMarkerHeight(); - } - InvalidateStyleData(); - RedrawSelMargin(); - break; - - case SCI_RGBAIMAGESETWIDTH: - sizeRGBAImage.x = static_cast(wParam); - break; - - case SCI_RGBAIMAGESETHEIGHT: - sizeRGBAImage.y = static_cast(wParam); - break; - - case SCI_RGBAIMAGESETSCALE: - scaleRGBAImage = static_cast(wParam); - break; - - case SCI_MARKERDEFINERGBAIMAGE: - if (wParam <= MARKER_MAX) { - vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0f, reinterpret_cast(lParam)); - vs.CalcLargestMarkerHeight(); - } - InvalidateStyleData(); - RedrawSelMargin(); - break; - - case SCI_SETMARGINTYPEN: - if (ValidMargin(wParam)) { - vs.ms[wParam].style = static_cast(lParam); - InvalidateStyleRedraw(); - } - break; - - case SCI_GETMARGINTYPEN: - if (ValidMargin(wParam)) - return vs.ms[wParam].style; - else - return 0; - - case SCI_SETMARGINWIDTHN: - if (ValidMargin(wParam)) { - // Short-circuit if the width is unchanged, to avoid unnecessary redraw. - if (vs.ms[wParam].width != lParam) { - lastXChosen += static_cast(lParam) - vs.ms[wParam].width; - vs.ms[wParam].width = static_cast(lParam); - InvalidateStyleRedraw(); - } - } - break; - - case SCI_GETMARGINWIDTHN: - if (ValidMargin(wParam)) - return vs.ms[wParam].width; - else - return 0; - - case SCI_SETMARGINMASKN: - if (ValidMargin(wParam)) { - vs.ms[wParam].mask = static_cast(lParam); - InvalidateStyleRedraw(); - } - break; - - case SCI_GETMARGINMASKN: - if (ValidMargin(wParam)) - return vs.ms[wParam].mask; - else - return 0; - - case SCI_SETMARGINSENSITIVEN: - if (ValidMargin(wParam)) { - vs.ms[wParam].sensitive = lParam != 0; - InvalidateStyleRedraw(); - } - break; - - case SCI_GETMARGINSENSITIVEN: - if (ValidMargin(wParam)) - return vs.ms[wParam].sensitive ? 1 : 0; - else - return 0; - - case SCI_SETMARGINCURSORN: - if (ValidMargin(wParam)) - vs.ms[wParam].cursor = static_cast(lParam); - break; - - case SCI_GETMARGINCURSORN: - if (ValidMargin(wParam)) - return vs.ms[wParam].cursor; - else - return 0; - - case SCI_SETMARGINBACKN: - if (ValidMargin(wParam)) { - vs.ms[wParam].back = ColourDesired(static_cast(lParam)); - InvalidateStyleRedraw(); - } - break; - - case SCI_GETMARGINBACKN: - if (ValidMargin(wParam)) - return vs.ms[wParam].back.AsLong(); - else - return 0; - - case SCI_SETMARGINS: - if (wParam < 1000) - vs.ms.resize(wParam); - break; - - case SCI_GETMARGINS: - return vs.ms.size(); - - case SCI_STYLECLEARALL: - vs.ClearStyles(); - InvalidateStyleRedraw(); - break; - - case SCI_STYLESETFORE: - case SCI_STYLESETBACK: - case SCI_STYLESETBOLD: - case SCI_STYLESETWEIGHT: - case SCI_STYLESETITALIC: - case SCI_STYLESETEOLFILLED: - case SCI_STYLESETSIZE: - case SCI_STYLESETSIZEFRACTIONAL: - case SCI_STYLESETFONT: - case SCI_STYLESETUNDERLINE: - case SCI_STYLESETCASE: - case SCI_STYLESETCHARACTERSET: - case SCI_STYLESETVISIBLE: - case SCI_STYLESETCHANGEABLE: - case SCI_STYLESETHOTSPOT: - StyleSetMessage(iMessage, wParam, lParam); - break; - - case SCI_STYLEGETFORE: - case SCI_STYLEGETBACK: - case SCI_STYLEGETBOLD: - case SCI_STYLEGETWEIGHT: - case SCI_STYLEGETITALIC: - case SCI_STYLEGETEOLFILLED: - case SCI_STYLEGETSIZE: - case SCI_STYLEGETSIZEFRACTIONAL: - case SCI_STYLEGETFONT: - case SCI_STYLEGETUNDERLINE: - case SCI_STYLEGETCASE: - case SCI_STYLEGETCHARACTERSET: - case SCI_STYLEGETVISIBLE: - case SCI_STYLEGETCHANGEABLE: - case SCI_STYLEGETHOTSPOT: - return StyleGetMessage(iMessage, wParam, lParam); - - case SCI_STYLERESETDEFAULT: - vs.ResetDefaultStyle(); - InvalidateStyleRedraw(); - break; - case SCI_SETSTYLEBITS: - vs.EnsureStyle(0xff); - break; - - case SCI_GETSTYLEBITS: - return 8; - - case SCI_SETLINESTATE: - return pdoc->SetLineState(static_cast(wParam), static_cast(lParam)); - - case SCI_GETLINESTATE: - return pdoc->GetLineState(static_cast(wParam)); - - case SCI_GETMAXLINESTATE: - return pdoc->GetMaxLineState(); - - case SCI_GETCARETLINEVISIBLE: - return vs.showCaretLineBackground; - case SCI_SETCARETLINEVISIBLE: - vs.showCaretLineBackground = wParam != 0; - InvalidateStyleRedraw(); - break; - case SCI_GETCARETLINEVISIBLEALWAYS: - return vs.alwaysShowCaretLineBackground; - case SCI_SETCARETLINEVISIBLEALWAYS: - vs.alwaysShowCaretLineBackground = wParam != 0; - InvalidateStyleRedraw(); - break; - - case SCI_GETCARETLINEBACK: - return vs.caretLineBackground.AsLong(); - case SCI_SETCARETLINEBACK: - vs.caretLineBackground = static_cast(wParam); - InvalidateStyleRedraw(); - break; - case SCI_GETCARETLINEBACKALPHA: - return vs.caretLineAlpha; - case SCI_SETCARETLINEBACKALPHA: - vs.caretLineAlpha = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - // Folding messages - - case SCI_VISIBLEFROMDOCLINE: - return cs.DisplayFromDoc(static_cast(wParam)); - - case SCI_DOCLINEFROMVISIBLE: - return cs.DocFromDisplay(static_cast(wParam)); - - case SCI_WRAPCOUNT: - return WrapCount(static_cast(wParam)); - - case SCI_SETFOLDLEVEL: { - int prev = pdoc->SetLevel(static_cast(wParam), static_cast(lParam)); - if (prev != static_cast(lParam)) - RedrawSelMargin(); - return prev; - } - - case SCI_GETFOLDLEVEL: - return pdoc->GetLevel(static_cast(wParam)); - - case SCI_GETLASTCHILD: - return pdoc->GetLastChild(static_cast(wParam), static_cast(lParam)); - - case SCI_GETFOLDPARENT: - return pdoc->GetFoldParent(static_cast(wParam)); - - case SCI_SHOWLINES: - cs.SetVisible(static_cast(wParam), static_cast(lParam), true); - SetScrollBars(); - Redraw(); - break; - - case SCI_HIDELINES: - if (wParam > 0) - cs.SetVisible(static_cast(wParam), static_cast(lParam), false); - SetScrollBars(); - Redraw(); - break; - - case SCI_GETLINEVISIBLE: - return cs.GetVisible(static_cast(wParam)); - - case SCI_GETALLLINESVISIBLE: - return cs.HiddenLines() ? 0 : 1; - - case SCI_SETFOLDEXPANDED: - SetFoldExpanded(static_cast(wParam), lParam != 0); - break; - - case SCI_GETFOLDEXPANDED: - return cs.GetExpanded(static_cast(wParam)); - - case SCI_SETAUTOMATICFOLD: - foldAutomatic = static_cast(wParam); - break; - - case SCI_GETAUTOMATICFOLD: - return foldAutomatic; - - case SCI_SETFOLDFLAGS: - foldFlags = static_cast(wParam); - Redraw(); - break; - - case SCI_TOGGLEFOLDSHOWTEXT: - cs.SetFoldDisplayText(static_cast(wParam), CharPtrFromSPtr(lParam)); - FoldLine(static_cast(wParam), SC_FOLDACTION_TOGGLE); - break; - - case SCI_FOLDDISPLAYTEXTSETSTYLE: - foldDisplayTextStyle = static_cast(wParam); - Redraw(); - break; - - case SCI_TOGGLEFOLD: - FoldLine(static_cast(wParam), SC_FOLDACTION_TOGGLE); - break; - - case SCI_FOLDLINE: - FoldLine(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_FOLDCHILDREN: - FoldExpand(static_cast(wParam), static_cast(lParam), pdoc->GetLevel(static_cast(wParam))); - break; - - case SCI_FOLDALL: - FoldAll(static_cast(wParam)); - break; - - case SCI_EXPANDCHILDREN: - FoldExpand(static_cast(wParam), SC_FOLDACTION_EXPAND, static_cast(lParam)); - break; - - case SCI_CONTRACTEDFOLDNEXT: - return ContractedFoldNext(static_cast(wParam)); - - case SCI_ENSUREVISIBLE: - EnsureLineVisible(static_cast(wParam), false); - break; - - case SCI_ENSUREVISIBLEENFORCEPOLICY: - EnsureLineVisible(static_cast(wParam), true); - break; - - case SCI_SCROLLRANGE: - ScrollRange(SelectionRange(static_cast(wParam), static_cast(lParam))); - break; - - case SCI_SEARCHANCHOR: - SearchAnchor(); - break; - - case SCI_SEARCHNEXT: - case SCI_SEARCHPREV: - return SearchText(iMessage, wParam, lParam); - - case SCI_SETXCARETPOLICY: - caretXPolicy = static_cast(wParam); - caretXSlop = static_cast(lParam); - break; - - case SCI_SETYCARETPOLICY: - caretYPolicy = static_cast(wParam); - caretYSlop = static_cast(lParam); - break; - - case SCI_SETVISIBLEPOLICY: - visiblePolicy = static_cast(wParam); - visibleSlop = static_cast(lParam); - break; - - case SCI_LINESONSCREEN: - return LinesOnScreen(); - - case SCI_SETSELFORE: - vs.selColours.fore = ColourOptional(wParam, lParam); - vs.selAdditionalForeground = ColourDesired(static_cast(lParam)); - InvalidateStyleRedraw(); - break; - - case SCI_SETSELBACK: - vs.selColours.back = ColourOptional(wParam, lParam); - vs.selAdditionalBackground = ColourDesired(static_cast(lParam)); - InvalidateStyleRedraw(); - break; - - case SCI_SETSELALPHA: - vs.selAlpha = static_cast(wParam); - vs.selAdditionalAlpha = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETSELALPHA: - return vs.selAlpha; - - case SCI_GETSELEOLFILLED: - return vs.selEOLFilled; - - case SCI_SETSELEOLFILLED: - vs.selEOLFilled = wParam != 0; - InvalidateStyleRedraw(); - break; - - case SCI_SETWHITESPACEFORE: - vs.whitespaceColours.fore = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETWHITESPACEBACK: - vs.whitespaceColours.back = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETCARETFORE: - vs.caretcolour = ColourDesired(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_GETCARETFORE: - return vs.caretcolour.AsLong(); - - case SCI_SETCARETSTYLE: - if (wParam <= CARETSTYLE_BLOCK) - vs.caretStyle = static_cast(wParam); - else - /* Default to the line caret */ - vs.caretStyle = CARETSTYLE_LINE; - InvalidateStyleRedraw(); - break; - - case SCI_GETCARETSTYLE: - return vs.caretStyle; - - case SCI_SETCARETWIDTH: - if (static_cast(wParam) <= 0) - vs.caretWidth = 0; - else if (wParam >= 3) - vs.caretWidth = 3; - else - vs.caretWidth = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETCARETWIDTH: - return vs.caretWidth; - - case SCI_ASSIGNCMDKEY: - kmap.AssignCmdKey(Platform::LowShortFromLong(static_cast(wParam)), - Platform::HighShortFromLong(static_cast(wParam)), static_cast(lParam)); - break; - - case SCI_CLEARCMDKEY: - kmap.AssignCmdKey(Platform::LowShortFromLong(static_cast(wParam)), - Platform::HighShortFromLong(static_cast(wParam)), SCI_NULL); - break; - - case SCI_CLEARALLCMDKEYS: - kmap.Clear(); - break; - - case SCI_INDICSETSTYLE: - if (wParam <= INDIC_MAX) { - vs.indicators[wParam].sacNormal.style = static_cast(lParam); - vs.indicators[wParam].sacHover.style = static_cast(lParam); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETSTYLE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacNormal.style : 0; - - case SCI_INDICSETFORE: - if (wParam <= INDIC_MAX) { - vs.indicators[wParam].sacNormal.fore = ColourDesired(static_cast(lParam)); - vs.indicators[wParam].sacHover.fore = ColourDesired(static_cast(lParam)); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETFORE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacNormal.fore.AsLong() : 0; - - case SCI_INDICSETHOVERSTYLE: - if (wParam <= INDIC_MAX) { - vs.indicators[wParam].sacHover.style = static_cast(lParam); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETHOVERSTYLE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacHover.style : 0; - - case SCI_INDICSETHOVERFORE: - if (wParam <= INDIC_MAX) { - vs.indicators[wParam].sacHover.fore = ColourDesired(static_cast(lParam)); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETHOVERFORE: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].sacHover.fore.AsLong() : 0; - - case SCI_INDICSETFLAGS: - if (wParam <= INDIC_MAX) { - vs.indicators[wParam].SetFlags(static_cast(lParam)); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETFLAGS: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].Flags() : 0; - - case SCI_INDICSETUNDER: - if (wParam <= INDIC_MAX) { - vs.indicators[wParam].under = lParam != 0; - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETUNDER: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0; - - case SCI_INDICSETALPHA: - if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) { - vs.indicators[wParam].fillAlpha = static_cast(lParam); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETALPHA: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0; - - case SCI_INDICSETOUTLINEALPHA: - if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) { - vs.indicators[wParam].outlineAlpha = static_cast(lParam); - InvalidateStyleRedraw(); - } - break; - - case SCI_INDICGETOUTLINEALPHA: - return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0; - - case SCI_SETINDICATORCURRENT: - pdoc->decorations.SetCurrentIndicator(static_cast(wParam)); - break; - case SCI_GETINDICATORCURRENT: - return pdoc->decorations.GetCurrentIndicator(); - case SCI_SETINDICATORVALUE: - pdoc->decorations.SetCurrentValue(static_cast(wParam)); - break; - case SCI_GETINDICATORVALUE: - return pdoc->decorations.GetCurrentValue(); - - case SCI_INDICATORFILLRANGE: - pdoc->DecorationFillRange(static_cast(wParam), pdoc->decorations.GetCurrentValue(), static_cast(lParam)); - break; - - case SCI_INDICATORCLEARRANGE: - pdoc->DecorationFillRange(static_cast(wParam), 0, static_cast(lParam)); - break; - - case SCI_INDICATORALLONFOR: - return pdoc->decorations.AllOnFor(static_cast(wParam)); - - case SCI_INDICATORVALUEAT: - return pdoc->decorations.ValueAt(static_cast(wParam), static_cast(lParam)); - - case SCI_INDICATORSTART: - return pdoc->decorations.Start(static_cast(wParam), static_cast(lParam)); - - case SCI_INDICATOREND: - return pdoc->decorations.End(static_cast(wParam), static_cast(lParam)); - - case SCI_LINEDOWN: - case SCI_LINEDOWNEXTEND: - case SCI_PARADOWN: - case SCI_PARADOWNEXTEND: - case SCI_LINEUP: - case SCI_LINEUPEXTEND: - case SCI_PARAUP: - case SCI_PARAUPEXTEND: - case SCI_CHARLEFT: - case SCI_CHARLEFTEXTEND: - case SCI_CHARRIGHT: - case SCI_CHARRIGHTEXTEND: - case SCI_WORDLEFT: - case SCI_WORDLEFTEXTEND: - case SCI_WORDRIGHT: - case SCI_WORDRIGHTEXTEND: - case SCI_WORDLEFTEND: - case SCI_WORDLEFTENDEXTEND: - case SCI_WORDRIGHTEND: - case SCI_WORDRIGHTENDEXTEND: - case SCI_HOME: - case SCI_HOMEEXTEND: - case SCI_LINEEND: - case SCI_LINEENDEXTEND: - case SCI_HOMEWRAP: - case SCI_HOMEWRAPEXTEND: - case SCI_LINEENDWRAP: - case SCI_LINEENDWRAPEXTEND: - case SCI_DOCUMENTSTART: - case SCI_DOCUMENTSTARTEXTEND: - case SCI_DOCUMENTEND: - case SCI_DOCUMENTENDEXTEND: - case SCI_SCROLLTOSTART: - case SCI_SCROLLTOEND: - - case SCI_STUTTEREDPAGEUP: - case SCI_STUTTEREDPAGEUPEXTEND: - case SCI_STUTTEREDPAGEDOWN: - case SCI_STUTTEREDPAGEDOWNEXTEND: - - case SCI_PAGEUP: - case SCI_PAGEUPEXTEND: - case SCI_PAGEDOWN: - case SCI_PAGEDOWNEXTEND: - case SCI_EDITTOGGLEOVERTYPE: - case SCI_CANCEL: - case SCI_DELETEBACK: - case SCI_TAB: - case SCI_BACKTAB: - case SCI_NEWLINE: - case SCI_FORMFEED: - case SCI_VCHOME: - case SCI_VCHOMEEXTEND: - case SCI_VCHOMEWRAP: - case SCI_VCHOMEWRAPEXTEND: - case SCI_VCHOMEDISPLAY: - case SCI_VCHOMEDISPLAYEXTEND: - case SCI_ZOOMIN: - case SCI_ZOOMOUT: - case SCI_DELWORDLEFT: - case SCI_DELWORDRIGHT: - case SCI_DELWORDRIGHTEND: - case SCI_DELLINELEFT: - case SCI_DELLINERIGHT: - case SCI_LINECOPY: - case SCI_LINECUT: - case SCI_LINEDELETE: - case SCI_LINETRANSPOSE: - case SCI_LINEDUPLICATE: - case SCI_LOWERCASE: - case SCI_UPPERCASE: - case SCI_LINESCROLLDOWN: - case SCI_LINESCROLLUP: - case SCI_WORDPARTLEFT: - case SCI_WORDPARTLEFTEXTEND: - case SCI_WORDPARTRIGHT: - case SCI_WORDPARTRIGHTEXTEND: - case SCI_DELETEBACKNOTLINE: - case SCI_HOMEDISPLAY: - case SCI_HOMEDISPLAYEXTEND: - case SCI_LINEENDDISPLAY: - case SCI_LINEENDDISPLAYEXTEND: - case SCI_LINEDOWNRECTEXTEND: - case SCI_LINEUPRECTEXTEND: - case SCI_CHARLEFTRECTEXTEND: - case SCI_CHARRIGHTRECTEXTEND: - case SCI_HOMERECTEXTEND: - case SCI_VCHOMERECTEXTEND: - case SCI_LINEENDRECTEXTEND: - case SCI_PAGEUPRECTEXTEND: - case SCI_PAGEDOWNRECTEXTEND: - case SCI_SELECTIONDUPLICATE: - return KeyCommand(iMessage); - - case SCI_BRACEHIGHLIGHT: - SetBraceHighlight(static_cast(wParam), static_cast(lParam), STYLE_BRACELIGHT); - break; - - case SCI_BRACEHIGHLIGHTINDICATOR: - if (lParam >= 0 && lParam <= INDIC_MAX) { - vs.braceHighlightIndicatorSet = wParam != 0; - vs.braceHighlightIndicator = static_cast(lParam); - } - break; - - case SCI_BRACEBADLIGHT: - SetBraceHighlight(static_cast(wParam), -1, STYLE_BRACEBAD); - break; - - case SCI_BRACEBADLIGHTINDICATOR: - if (lParam >= 0 && lParam <= INDIC_MAX) { - vs.braceBadLightIndicatorSet = wParam != 0; - vs.braceBadLightIndicator = static_cast(lParam); - } - break; - - case SCI_BRACEMATCH: - // wParam is position of char to find brace for, - // lParam is maximum amount of text to restyle to find it - return pdoc->BraceMatch(static_cast(wParam), static_cast(lParam)); - - case SCI_GETVIEWEOL: - return vs.viewEOL; - - case SCI_SETVIEWEOL: - vs.viewEOL = wParam != 0; - InvalidateStyleRedraw(); - break; - - case SCI_SETZOOM: - vs.zoomLevel = static_cast(wParam); - InvalidateStyleRedraw(); - NotifyZoom(); - break; - - case SCI_GETZOOM: - return vs.zoomLevel; - - case SCI_GETEDGECOLUMN: - return vs.theEdge.column; - - case SCI_SETEDGECOLUMN: - vs.theEdge.column = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETEDGEMODE: - return vs.edgeState; - - case SCI_SETEDGEMODE: - vs.edgeState = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETEDGECOLOUR: - return vs.theEdge.colour.AsLong(); - - case SCI_SETEDGECOLOUR: - vs.theEdge.colour = ColourDesired(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_MULTIEDGEADDLINE: - vs.theMultiEdge.push_back(EdgeProperties(wParam, lParam)); - InvalidateStyleRedraw(); - break; - - case SCI_MULTIEDGECLEARALL: - std::vector().swap(vs.theMultiEdge); // Free vector and memory, C++03 compatible - InvalidateStyleRedraw(); - break; - - case SCI_GETDOCPOINTER: - return reinterpret_cast(pdoc); - - case SCI_SETDOCPOINTER: - CancelModes(); - SetDocPointer(reinterpret_cast(lParam)); - return 0; - - case SCI_CREATEDOCUMENT: { - Document *doc = new Document(); - doc->AddRef(); - return reinterpret_cast(doc); - } - - case SCI_ADDREFDOCUMENT: - (reinterpret_cast(lParam))->AddRef(); - break; - - case SCI_RELEASEDOCUMENT: - (reinterpret_cast(lParam))->Release(); - break; - - case SCI_CREATELOADER: { - Document *doc = new Document(); - doc->AddRef(); - doc->Allocate(static_cast(wParam)); - doc->SetUndoCollection(false); - return reinterpret_cast(static_cast(doc)); - } - - case SCI_SETMODEVENTMASK: - modEventMask = static_cast(wParam); - return 0; - - case SCI_GETMODEVENTMASK: - return modEventMask; - - case SCI_CONVERTEOLS: - pdoc->ConvertLineEnds(static_cast(wParam)); - SetSelection(sel.MainCaret(), sel.MainAnchor()); // Ensure selection inside document - return 0; - - case SCI_SETLENGTHFORENCODE: - lengthForEncode = static_cast(wParam); - return 0; - - case SCI_SELECTIONISRECTANGLE: - return sel.selType == Selection::selRectangle ? 1 : 0; - - case SCI_SETSELECTIONMODE: { - switch (wParam) { - case SC_SEL_STREAM: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream)); - sel.selType = Selection::selStream; - break; - case SC_SEL_RECTANGLE: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selRectangle)); - sel.selType = Selection::selRectangle; - break; - case SC_SEL_LINES: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selLines)); - sel.selType = Selection::selLines; - break; - case SC_SEL_THIN: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selThin)); - sel.selType = Selection::selThin; - break; - default: - sel.SetMoveExtends(!sel.MoveExtends() || (sel.selType != Selection::selStream)); - sel.selType = Selection::selStream; - } - InvalidateWholeSelection(); - break; - } - case SCI_GETSELECTIONMODE: - switch (sel.selType) { - case Selection::selStream: - return SC_SEL_STREAM; - case Selection::selRectangle: - return SC_SEL_RECTANGLE; - case Selection::selLines: - return SC_SEL_LINES; - case Selection::selThin: - return SC_SEL_THIN; - default: // ?! - return SC_SEL_STREAM; - } - case SCI_GETLINESELSTARTPOSITION: - case SCI_GETLINESELENDPOSITION: { - SelectionSegment segmentLine(SelectionPosition(pdoc->LineStart(static_cast(wParam))), - SelectionPosition(pdoc->LineEnd(static_cast(wParam)))); - for (size_t r=0; r(wParam); - break; - - case SCI_GETSTATUS: - return errorStatus; - - case SCI_SETMOUSEDOWNCAPTURES: - mouseDownCaptures = wParam != 0; - break; - - case SCI_GETMOUSEDOWNCAPTURES: - return mouseDownCaptures; - - case SCI_SETMOUSEWHEELCAPTURES: - mouseWheelCaptures = wParam != 0; - break; - - case SCI_GETMOUSEWHEELCAPTURES: - return mouseWheelCaptures; - - case SCI_SETCURSOR: - cursorMode = static_cast(wParam); - DisplayCursor(Window::cursorText); - break; - - case SCI_GETCURSOR: - return cursorMode; - - case SCI_SETCONTROLCHARSYMBOL: - vs.controlCharSymbol = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETCONTROLCHARSYMBOL: - return vs.controlCharSymbol; - - case SCI_SETREPRESENTATION: - reprs.SetRepresentation(reinterpret_cast(wParam), CharPtrFromSPtr(lParam)); - break; - - case SCI_GETREPRESENTATION: { - const Representation *repr = reprs.RepresentationFromCharacter( - reinterpret_cast(wParam), UTF8MaxBytes); - if (repr) { - return StringResult(lParam, repr->stringRep.c_str()); - } - return 0; - } - - case SCI_CLEARREPRESENTATION: - reprs.ClearRepresentation(reinterpret_cast(wParam)); - break; - - case SCI_STARTRECORD: - recordingMacro = true; - return 0; - - case SCI_STOPRECORD: - recordingMacro = false; - return 0; - - case SCI_MOVECARETINSIDEVIEW: - MoveCaretInsideView(); - break; - - case SCI_SETFOLDMARGINCOLOUR: - vs.foldmarginColour = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETFOLDMARGINHICOLOUR: - vs.foldmarginHighlightColour = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); - break; - - case SCI_SETHOTSPOTACTIVEFORE: - vs.hotspotColours.fore = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETHOTSPOTACTIVEFORE: - return vs.hotspotColours.fore.AsLong(); - - case SCI_SETHOTSPOTACTIVEBACK: - vs.hotspotColours.back = ColourOptional(wParam, lParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETHOTSPOTACTIVEBACK: - return vs.hotspotColours.back.AsLong(); - - case SCI_SETHOTSPOTACTIVEUNDERLINE: - vs.hotspotUnderline = wParam != 0; - InvalidateStyleRedraw(); - break; - - case SCI_GETHOTSPOTACTIVEUNDERLINE: - return vs.hotspotUnderline ? 1 : 0; - - case SCI_SETHOTSPOTSINGLELINE: - vs.hotspotSingleLine = wParam != 0; - InvalidateStyleRedraw(); - break; - - case SCI_GETHOTSPOTSINGLELINE: - return vs.hotspotSingleLine ? 1 : 0; - - case SCI_SETPASTECONVERTENDINGS: - convertPastes = wParam != 0; - break; - - case SCI_GETPASTECONVERTENDINGS: - return convertPastes ? 1 : 0; - - case SCI_GETCHARACTERPOINTER: - return reinterpret_cast(pdoc->BufferPointer()); - - case SCI_GETRANGEPOINTER: - return reinterpret_cast(pdoc->RangePointer(static_cast(wParam), static_cast(lParam))); - - case SCI_GETGAPPOSITION: - return pdoc->GapPosition(); - - case SCI_SETEXTRAASCENT: - vs.extraAscent = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETEXTRAASCENT: - return vs.extraAscent; - - case SCI_SETEXTRADESCENT: - vs.extraDescent = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETEXTRADESCENT: - return vs.extraDescent; - - case SCI_MARGINSETSTYLEOFFSET: - vs.marginStyleOffset = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_MARGINGETSTYLEOFFSET: - return vs.marginStyleOffset; - - case SCI_SETMARGINOPTIONS: - marginOptions = static_cast(wParam); - break; - - case SCI_GETMARGINOPTIONS: - return marginOptions; - - case SCI_MARGINSETTEXT: - pdoc->MarginSetText(static_cast(wParam), CharPtrFromSPtr(lParam)); - break; - - case SCI_MARGINGETTEXT: { - const StyledText st = pdoc->MarginStyledText(static_cast(wParam)); - return BytesResult(lParam, reinterpret_cast(st.text), st.length); - } - - case SCI_MARGINSETSTYLE: - pdoc->MarginSetStyle(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_MARGINGETSTYLE: { - const StyledText st = pdoc->MarginStyledText(static_cast(wParam)); - return st.style; - } - - case SCI_MARGINSETSTYLES: - pdoc->MarginSetStyles(static_cast(wParam), reinterpret_cast(lParam)); - break; - - case SCI_MARGINGETSTYLES: { - const StyledText st = pdoc->MarginStyledText(static_cast(wParam)); - return BytesResult(lParam, st.styles, st.length); - } - - case SCI_MARGINTEXTCLEARALL: - pdoc->MarginClearAll(); - break; - - case SCI_ANNOTATIONSETTEXT: - pdoc->AnnotationSetText(static_cast(wParam), CharPtrFromSPtr(lParam)); - break; - - case SCI_ANNOTATIONGETTEXT: { - const StyledText st = pdoc->AnnotationStyledText(static_cast(wParam)); - return BytesResult(lParam, reinterpret_cast(st.text), st.length); - } - - case SCI_ANNOTATIONGETSTYLE: { - const StyledText st = pdoc->AnnotationStyledText(static_cast(wParam)); - return st.style; - } - - case SCI_ANNOTATIONSETSTYLE: - pdoc->AnnotationSetStyle(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_ANNOTATIONSETSTYLES: - pdoc->AnnotationSetStyles(static_cast(wParam), reinterpret_cast(lParam)); - break; - - case SCI_ANNOTATIONGETSTYLES: { - const StyledText st = pdoc->AnnotationStyledText(static_cast(wParam)); - return BytesResult(lParam, st.styles, st.length); - } - - case SCI_ANNOTATIONGETLINES: - return pdoc->AnnotationLines(static_cast(wParam)); - - case SCI_ANNOTATIONCLEARALL: - pdoc->AnnotationClearAll(); - break; - - case SCI_ANNOTATIONSETVISIBLE: - SetAnnotationVisible(static_cast(wParam)); - break; - - case SCI_ANNOTATIONGETVISIBLE: - return vs.annotationVisible; - - case SCI_ANNOTATIONSETSTYLEOFFSET: - vs.annotationStyleOffset = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_ANNOTATIONGETSTYLEOFFSET: - return vs.annotationStyleOffset; - - case SCI_RELEASEALLEXTENDEDSTYLES: - vs.ReleaseAllExtendedStyles(); - break; - - case SCI_ALLOCATEEXTENDEDSTYLES: - return vs.AllocateExtendedStyles(static_cast(wParam)); - - case SCI_ADDUNDOACTION: - pdoc->AddUndoAction(static_cast(wParam), lParam & UNDO_MAY_COALESCE); - break; - - case SCI_SETMOUSESELECTIONRECTANGULARSWITCH: - mouseSelectionRectangularSwitch = wParam != 0; - break; - - case SCI_GETMOUSESELECTIONRECTANGULARSWITCH: - return mouseSelectionRectangularSwitch; - - case SCI_SETMULTIPLESELECTION: - multipleSelection = wParam != 0; - InvalidateCaret(); - break; - - case SCI_GETMULTIPLESELECTION: - return multipleSelection; - - case SCI_SETADDITIONALSELECTIONTYPING: - additionalSelectionTyping = wParam != 0; - InvalidateCaret(); - break; - - case SCI_GETADDITIONALSELECTIONTYPING: - return additionalSelectionTyping; - - case SCI_SETMULTIPASTE: - multiPasteMode = static_cast(wParam); - break; - - case SCI_GETMULTIPASTE: - return multiPasteMode; - - case SCI_SETADDITIONALCARETSBLINK: - view.additionalCaretsBlink = wParam != 0; - InvalidateCaret(); - break; - - case SCI_GETADDITIONALCARETSBLINK: - return view.additionalCaretsBlink; - - case SCI_SETADDITIONALCARETSVISIBLE: - view.additionalCaretsVisible = wParam != 0; - InvalidateCaret(); - break; - - case SCI_GETADDITIONALCARETSVISIBLE: - return view.additionalCaretsVisible; - - case SCI_GETSELECTIONS: - return sel.Count(); - - case SCI_GETSELECTIONEMPTY: - return sel.Empty(); - - case SCI_CLEARSELECTIONS: - sel.Clear(); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); - Redraw(); - break; - - case SCI_SETSELECTION: - sel.SetSelection(SelectionRange(static_cast(wParam), static_cast(lParam))); - Redraw(); - break; - - case SCI_ADDSELECTION: - sel.AddSelection(SelectionRange(static_cast(wParam), static_cast(lParam))); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); - Redraw(); - break; - - case SCI_DROPSELECTIONN: - sel.DropSelection(static_cast(wParam)); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); - Redraw(); - break; - - case SCI_SETMAINSELECTION: - sel.SetMain(static_cast(wParam)); - ContainerNeedsUpdate(SC_UPDATE_SELECTION); - Redraw(); - break; - - case SCI_GETMAINSELECTION: - return sel.Main(); - - case SCI_SETSELECTIONNCARET: - case SCI_SETSELECTIONNANCHOR: - case SCI_SETSELECTIONNCARETVIRTUALSPACE: - case SCI_SETSELECTIONNANCHORVIRTUALSPACE: - case SCI_SETSELECTIONNSTART: - case SCI_SETSELECTIONNEND: - SetSelectionNMessage(iMessage, wParam, lParam); - break; - - case SCI_GETSELECTIONNCARET: - return sel.Range(wParam).caret.Position(); - - case SCI_GETSELECTIONNANCHOR: - return sel.Range(wParam).anchor.Position(); - - case SCI_GETSELECTIONNCARETVIRTUALSPACE: - return sel.Range(wParam).caret.VirtualSpace(); - - case SCI_GETSELECTIONNANCHORVIRTUALSPACE: - return sel.Range(wParam).anchor.VirtualSpace(); - - case SCI_GETSELECTIONNSTART: - return sel.Range(wParam).Start().Position(); - - case SCI_GETSELECTIONNEND: - return sel.Range(wParam).End().Position(); - - case SCI_SETRECTANGULARSELECTIONCARET: - if (!sel.IsRectangular()) - sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().caret.SetPosition(static_cast(wParam)); - SetRectangularRange(); - Redraw(); - break; - - case SCI_GETRECTANGULARSELECTIONCARET: - return sel.Rectangular().caret.Position(); - - case SCI_SETRECTANGULARSELECTIONANCHOR: - if (!sel.IsRectangular()) - sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().anchor.SetPosition(static_cast(wParam)); - SetRectangularRange(); - Redraw(); - break; - - case SCI_GETRECTANGULARSELECTIONANCHOR: - return sel.Rectangular().anchor.Position(); - - case SCI_SETRECTANGULARSELECTIONCARETVIRTUALSPACE: - if (!sel.IsRectangular()) - sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().caret.SetVirtualSpace(static_cast(wParam)); - SetRectangularRange(); - Redraw(); - break; - - case SCI_GETRECTANGULARSELECTIONCARETVIRTUALSPACE: - return sel.Rectangular().caret.VirtualSpace(); - - case SCI_SETRECTANGULARSELECTIONANCHORVIRTUALSPACE: - if (!sel.IsRectangular()) - sel.Clear(); - sel.selType = Selection::selRectangle; - sel.Rectangular().anchor.SetVirtualSpace(static_cast(wParam)); - SetRectangularRange(); - Redraw(); - break; - - case SCI_GETRECTANGULARSELECTIONANCHORVIRTUALSPACE: - return sel.Rectangular().anchor.VirtualSpace(); - - case SCI_SETVIRTUALSPACEOPTIONS: - virtualSpaceOptions = static_cast(wParam); - break; - - case SCI_GETVIRTUALSPACEOPTIONS: - return virtualSpaceOptions; - - case SCI_SETADDITIONALSELFORE: - vs.selAdditionalForeground = ColourDesired(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_SETADDITIONALSELBACK: - vs.selAdditionalBackground = ColourDesired(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_SETADDITIONALSELALPHA: - vs.selAdditionalAlpha = static_cast(wParam); - InvalidateStyleRedraw(); - break; - - case SCI_GETADDITIONALSELALPHA: - return vs.selAdditionalAlpha; - - case SCI_SETADDITIONALCARETFORE: - vs.additionalCaretColour = ColourDesired(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_GETADDITIONALCARETFORE: - return vs.additionalCaretColour.AsLong(); - - case SCI_ROTATESELECTION: - sel.RotateMain(); - InvalidateWholeSelection(); - break; - - case SCI_SWAPMAINANCHORCARET: - InvalidateSelection(sel.RangeMain()); - sel.RangeMain().Swap(); - break; - - case SCI_MULTIPLESELECTADDNEXT: - MultipleSelectAdd(addOne); - break; - - case SCI_MULTIPLESELECTADDEACH: - MultipleSelectAdd(addEach); - break; - - case SCI_CHANGELEXERSTATE: - pdoc->ChangeLexerState(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_SETIDENTIFIER: - SetCtrlID(static_cast(wParam)); - break; - - case SCI_GETIDENTIFIER: - return GetCtrlID(); - - case SCI_SETTECHNOLOGY: - // No action by default - break; - - case SCI_GETTECHNOLOGY: - return technology; - - case SCI_COUNTCHARACTERS: - return pdoc->CountCharacters(static_cast(wParam), static_cast(lParam)); - - default: - return DefWndProc(iMessage, wParam, lParam); - } - //Platform::DebugPrintf("end wnd proc\n"); - return 0l; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/Editor.h b/qrenderdoc/3rdparty/scintilla/src/Editor.h deleted file mode 100644 index 864bac94f..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Editor.h +++ /dev/null @@ -1,642 +0,0 @@ -// Scintilla source code edit control -/** @file Editor.h - ** Defines the main editor class. - **/ -// Copyright 1998-2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef EDITOR_H -#define EDITOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - */ -class Timer { -public: - bool ticking; - int ticksToWait; - enum {tickSize = 100}; - TickerID tickerID; - - Timer(); -}; - -/** - */ -class Idler { -public: - bool state; - IdlerID idlerID; - - Idler(); -}; - -/** - * When platform has a way to generate an event before painting, - * accumulate needed styling range and other work items in - * WorkNeeded to avoid unnecessary work inside paint handler - */ -class WorkNeeded { -public: - enum workItems { - workNone=0, - workStyle=1, - workUpdateUI=2 - }; - enum workItems items; - Position upTo; - - WorkNeeded() : items(workNone), upTo(0) {} - void Reset() { - items = workNone; - upTo = 0; - } - void Need(workItems items_, Position pos) { - if ((items_ & workStyle) && (upTo < pos)) - upTo = pos; - items = static_cast(items | items_); - } -}; - -/** - * Hold a piece of text selected for copying or dragging, along with encoding and selection format information. - */ -class SelectionText { - std::string s; -public: - bool rectangular; - bool lineCopy; - int codePage; - int characterSet; - SelectionText() : rectangular(false), lineCopy(false), codePage(0), characterSet(0) {} - ~SelectionText() { - } - void Clear() { - s.clear(); - rectangular = false; - lineCopy = false; - codePage = 0; - characterSet = 0; - } - void Copy(const std::string &s_, int codePage_, int characterSet_, bool rectangular_, bool lineCopy_) { - s = s_; - codePage = codePage_; - characterSet = characterSet_; - rectangular = rectangular_; - lineCopy = lineCopy_; - FixSelectionForClipboard(); - } - void Copy(const SelectionText &other) { - Copy(other.s, other.codePage, other.characterSet, other.rectangular, other.lineCopy); - } - const char *Data() const { - return s.c_str(); - } - size_t Length() const { - return s.length(); - } - size_t LengthWithTerminator() const { - return s.length() + 1; - } - bool Empty() const { - return s.empty(); - } -private: - void FixSelectionForClipboard() { - // To avoid truncating the contents of the clipboard when pasted where the - // clipboard contains NUL characters, replace NUL characters by spaces. - std::replace(s.begin(), s.end(), '\0', ' '); - } -}; - -struct WrapPending { - // The range of lines that need to be wrapped - enum { lineLarge = 0x7ffffff }; - int start; // When there are wraps pending, will be in document range - int end; // May be lineLarge to indicate all of document after start - WrapPending() { - start = lineLarge; - end = lineLarge; - } - void Reset() { - start = lineLarge; - end = lineLarge; - } - void Wrapped(int line) { - if (start == line) - start++; - } - bool NeedsWrap() const { - return start < end; - } - bool AddRange(int lineStart, int lineEnd) { - const bool neededWrap = NeedsWrap(); - bool changed = false; - if (start > lineStart) { - start = lineStart; - changed = true; - } - if ((end < lineEnd) || !neededWrap) { - end = lineEnd; - changed = true; - } - return changed; - } -}; - -/** - */ -class Editor : public EditModel, public DocWatcher { - // Private so Editor objects can not be copied - explicit Editor(const Editor &); - Editor &operator=(const Editor &); - -protected: // ScintillaBase subclass needs access to much of Editor - - /** On GTK+, Scintilla is a container widget holding two scroll bars - * whereas on Windows there is just one window with both scroll bars turned on. */ - Window wMain; ///< The Scintilla parent window - Window wMargin; ///< May be separate when using a scroll view for wMain - - /** Style resources may be expensive to allocate so are cached between uses. - * When a style attribute is changed, this cache is flushed. */ - bool stylesValid; - ViewStyle vs; - int technology; - Point sizeRGBAImage; - float scaleRGBAImage; - - MarginView marginView; - EditView view; - - int cursorMode; - - bool hasFocus; - bool mouseDownCaptures; - bool mouseWheelCaptures; - - int xCaretMargin; ///< Ensure this many pixels visible on both sides of caret - bool horizontalScrollBarVisible; - int scrollWidth; - bool verticalScrollBarVisible; - bool endAtLastLine; - int caretSticky; - int marginOptions; - bool mouseSelectionRectangularSwitch; - bool multipleSelection; - bool additionalSelectionTyping; - int multiPasteMode; - - int virtualSpaceOptions; - - KeyMap kmap; - - Timer timer; - Timer autoScrollTimer; - enum { autoScrollDelay = 200 }; - - Idler idler; - - Point lastClick; - unsigned int lastClickTime; - Point doubleClickCloseThreshold; - int dwellDelay; - int ticksToDwell; - bool dwelling; - enum { selChar, selWord, selSubLine, selWholeLine } selectionType; - Point ptMouseLast; - enum { ddNone, ddInitial, ddDragging } inDragDrop; - bool dropWentOutside; - SelectionPosition posDrop; - int hotSpotClickPos; - int lastXChosen; - int lineAnchorPos; - int originalAnchorPos; - int wordSelectAnchorStartPos; - int wordSelectAnchorEndPos; - int wordSelectInitialCaretPos; - int targetStart; - int targetEnd; - int searchFlags; - int topLine; - int posTopLine; - int lengthForEncode; - - int needUpdateUI; - - enum { notPainting, painting, paintAbandoned } paintState; - bool paintAbandonedByStyling; - PRectangle rcPaint; - bool paintingAllText; - bool willRedrawAll; - WorkNeeded workNeeded; - int idleStyling; - bool needIdleStyling; - - int modEventMask; - - SelectionText drag; - - int caretXPolicy; - int caretXSlop; ///< Ensure this many pixels visible on both sides of caret - - int caretYPolicy; - int caretYSlop; ///< Ensure this many lines visible on both sides of caret - - int visiblePolicy; - int visibleSlop; - - int searchAnchor; - - bool recordingMacro; - - int foldAutomatic; - - // Wrapping support - WrapPending wrapPending; - - bool convertPastes; - - Editor(); - virtual ~Editor(); - virtual void Initialise() = 0; - virtual void Finalise(); - - void InvalidateStyleData(); - void InvalidateStyleRedraw(); - void RefreshStyleData(); - void SetRepresentations(); - void DropGraphics(bool freeObjects); - void AllocateGraphics(); - - // The top left visible point in main window coordinates. Will be 0,0 except for - // scroll views where it will be equivalent to the current scroll position. - virtual Point GetVisibleOriginInMain() const; - PointDocument DocumentPointFromView(Point ptView) const; // Convert a point from view space to document - int TopLineOfMain() const; // Return the line at Main's y coordinate 0 - virtual PRectangle GetClientRectangle() const; - virtual PRectangle GetClientDrawingRectangle(); - PRectangle GetTextRectangle() const; - - virtual int LinesOnScreen() const; - int LinesToScroll() const; - int MaxScrollPos() const; - SelectionPosition ClampPositionIntoDocument(SelectionPosition sp) const; - Point LocationFromPosition(SelectionPosition pos, PointEnd pe=peDefault); - Point LocationFromPosition(int pos, PointEnd pe=peDefault); - int XFromPosition(int pos); - int XFromPosition(SelectionPosition sp); - SelectionPosition SPositionFromLocation(Point pt, bool canReturnInvalid=false, bool charPosition=false, bool virtualSpace=true); - int PositionFromLocation(Point pt, bool canReturnInvalid = false, bool charPosition = false); - SelectionPosition SPositionFromLineX(int lineDoc, int x); - int PositionFromLineX(int line, int x); - int LineFromLocation(Point pt) const; - void SetTopLine(int topLineNew); - - virtual bool AbandonPaint(); - virtual void RedrawRect(PRectangle rc); - virtual void DiscardOverdraw(); - virtual void Redraw(); - void RedrawSelMargin(int line=-1, bool allAfter=false); - PRectangle RectangleFromRange(Range r, int overlap); - void InvalidateRange(int start, int end); - - bool UserVirtualSpace() const { - return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0); - } - int CurrentPosition() const; - bool SelectionEmpty() const; - SelectionPosition SelectionStart(); - SelectionPosition SelectionEnd(); - void SetRectangularRange(); - void ThinRectangularRange(); - void InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection=false); - void InvalidateWholeSelection(); - void SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_); - void SetSelection(int currentPos_, int anchor_); - void SetSelection(SelectionPosition currentPos_); - void SetSelection(int currentPos_); - void SetEmptySelection(SelectionPosition currentPos_); - void SetEmptySelection(int currentPos_); - enum AddNumber { addOne, addEach }; - void MultipleSelectAdd(AddNumber addNumber); - bool RangeContainsProtected(int start, int end) const; - bool SelectionContainsProtected(); - int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true) const; - SelectionPosition MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd=true) const; - void MovedCaret(SelectionPosition newPos, SelectionPosition previousPos, bool ensureVisible); - void MovePositionTo(SelectionPosition newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); - void MovePositionTo(int newPos, Selection::selTypes selt=Selection::noSel, bool ensureVisible=true); - SelectionPosition MovePositionSoVisible(SelectionPosition pos, int moveDir); - SelectionPosition MovePositionSoVisible(int pos, int moveDir); - Point PointMainCaret(); - void SetLastXChosen(); - - void ScrollTo(int line, bool moveThumb=true); - virtual void ScrollText(int linesToMove); - void HorizontalScrollTo(int xPos); - void VerticalCentreCaret(); - void MoveSelectedLines(int lineDelta); - void MoveSelectedLinesUp(); - void MoveSelectedLinesDown(); - void MoveCaretInsideView(bool ensureVisible=true); - int DisplayFromPosition(int pos); - - struct XYScrollPosition { - int xOffset; - int topLine; - XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {} - bool operator==(const XYScrollPosition &other) const { - return (xOffset == other.xOffset) && (topLine == other.topLine); - } - }; - enum XYScrollOptions { - xysUseMargin=0x1, - xysVertical=0x2, - xysHorizontal=0x4, - xysDefault=xysUseMargin|xysVertical|xysHorizontal}; - XYScrollPosition XYScrollToMakeVisible(const SelectionRange &range, const XYScrollOptions options); - void SetXYScroll(XYScrollPosition newXY); - void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true); - void ScrollRange(SelectionRange range); - void ShowCaretAtCurrentPosition(); - void DropCaret(); - void CaretSetPeriod(int period); - void InvalidateCaret(); - virtual void NotifyCaretMove(); - virtual void UpdateSystemCaret(); - - bool Wrapping() const; - void NeedWrapping(int docLineStart=0, int docLineEnd=WrapPending::lineLarge); - bool WrapOneLine(Surface *surface, int lineToWrap); - enum wrapScope {wsAll, wsVisible, wsIdle}; - bool WrapLines(enum wrapScope ws); - void LinesJoin(); - void LinesSplit(int pixelWidth); - - void PaintSelMargin(Surface *surface, PRectangle &rc); - void RefreshPixMaps(Surface *surfaceWindow); - void Paint(Surface *surfaceWindow, PRectangle rcArea); - long FormatRange(bool draw, Sci_RangeToFormat *pfr); - int TextWidth(int style, const char *text); - - virtual void SetVerticalScrollPos() = 0; - virtual void SetHorizontalScrollPos() = 0; - virtual bool ModifyScrollBars(int nMax, int nPage) = 0; - virtual void ReconfigureScrollBars(); - void SetScrollBars(); - void ChangeSize(); - - void FilterSelections(); - int RealizeVirtualSpace(int position, unsigned int virtualSpace); - SelectionPosition RealizeVirtualSpace(const SelectionPosition &position); - void AddChar(char ch); - virtual void AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS=false); - void ClearBeforeTentativeStart(); - void InsertPaste(const char *text, int len); - enum PasteShape { pasteStream=0, pasteRectangular = 1, pasteLine = 2 }; - void InsertPasteShape(const char *text, int len, PasteShape shape); - void ClearSelection(bool retainMultipleSelections = false); - void ClearAll(); - void ClearDocumentStyle(); - void Cut(); - void PasteRectangular(SelectionPosition pos, const char *ptr, int len); - virtual void Copy() = 0; - virtual void CopyAllowLine(); - virtual bool CanPaste(); - virtual void Paste() = 0; - void Clear(); - void SelectAll(); - void Undo(); - void Redo(); - void DelCharBack(bool allowLineStartDeletion); - virtual void ClaimSelection() = 0; - - static int ModifierFlags(bool shift, bool ctrl, bool alt, bool meta=false, bool super=false); - virtual void NotifyChange() = 0; - virtual void NotifyFocus(bool focus); - virtual void SetCtrlID(int identifier); - virtual int GetCtrlID() { return ctrlID; } - virtual void NotifyParent(SCNotification scn) = 0; - virtual void NotifyStyleToNeeded(int endStyleNeeded); - void NotifyChar(int ch); - void NotifySavePoint(bool isSavePoint); - void NotifyModifyAttempt(); - virtual void NotifyDoubleClick(Point pt, int modifiers); - virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt); - void NotifyHotSpotClicked(int position, int modifiers); - void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt); - void NotifyHotSpotDoubleClicked(int position, int modifiers); - void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt); - void NotifyHotSpotReleaseClick(int position, int modifiers); - void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt); - bool NotifyUpdateUI(); - void NotifyPainted(); - void NotifyIndicatorClick(bool click, int position, int modifiers); - void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt); - bool NotifyMarginClick(Point pt, int modifiers); - bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt); - bool NotifyMarginRightClick(Point pt, int modifiers); - void NotifyNeedShown(int pos, int len); - void NotifyDwelling(Point pt, bool state); - void NotifyZoom(); - - void NotifyModifyAttempt(Document *document, void *userData); - void NotifySavePoint(Document *document, void *userData, bool atSavePoint); - void CheckModificationForWrap(DocModification mh); - void NotifyModified(Document *document, DocModification mh, void *userData); - void NotifyDeleted(Document *document, void *userData); - void NotifyStyleNeeded(Document *doc, void *userData, int endPos); - void NotifyLexerChanged(Document *doc, void *userData); - void NotifyErrorOccurred(Document *doc, void *userData, int status); - void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - - void ContainerNeedsUpdate(int flags); - void PageMove(int direction, Selection::selTypes selt=Selection::noSel, bool stuttered = false); - enum { cmSame, cmUpper, cmLower }; - virtual std::string CaseMapString(const std::string &s, int caseMapping); - void ChangeCaseOfSelection(int caseMapping); - void LineTranspose(); - void Duplicate(bool forLine); - virtual void CancelModes(); - void NewLine(); - SelectionPosition PositionUpOrDown(SelectionPosition spStart, int direction, int lastX); - void CursorUpOrDown(int direction, Selection::selTypes selt); - void ParaUpOrDown(int direction, Selection::selTypes selt); - Range RangeDisplayLine(int lineVisible); - int StartEndDisplayLine(int pos, bool start); - int VCHomeDisplayPosition(int position); - int VCHomeWrapPosition(int position); - int LineEndWrapPosition(int position); - int HorizontalMove(unsigned int iMessage); - int DelWordOrLine(unsigned int iMessage); - virtual int KeyCommand(unsigned int iMessage); - virtual int KeyDefault(int /* key */, int /*modifiers*/); - int KeyDownWithModifiers(int key, int modifiers, bool *consumed); - int KeyDown(int key, bool shift, bool ctrl, bool alt, bool *consumed=0); - - void Indent(bool forwards); - - virtual CaseFolder *CaseFolderForEncoding(); - long FindText(uptr_t wParam, sptr_t lParam); - void SearchAnchor(); - long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - long SearchInTarget(const char *text, int length); - void GoToLine(int lineNo); - - virtual void CopyToClipboard(const SelectionText &selectedText) = 0; - std::string RangeText(int start, int end) const; - void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false); - void CopyRangeToClipboard(int start, int end); - void CopyText(int length, const char *text); - void SetDragPosition(SelectionPosition newPos); - virtual void DisplayCursor(Window::Cursor c); - virtual bool DragThreshold(Point ptStart, Point ptNow); - virtual void StartDrag(); - void DropAt(SelectionPosition position, const char *value, size_t lengthValue, bool moving, bool rectangular); - void DropAt(SelectionPosition position, const char *value, bool moving, bool rectangular); - /** PositionInSelection returns true if position in selection. */ - bool PositionInSelection(int pos); - bool PointInSelection(Point pt); - bool PointInSelMargin(Point pt) const; - Window::Cursor GetMarginCursor(Point pt) const; - void TrimAndSetSelection(int currentPos_, int anchor_); - void LineSelection(int lineCurrentPos_, int lineAnchorPos_, bool wholeLine); - void WordSelection(int pos); - void DwellEnd(bool mouseMoved); - void MouseLeave(); - virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers); - virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers); - virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); - void ButtonMoveWithModifiers(Point pt, int modifiers); - void ButtonMove(Point pt); - void ButtonUp(Point pt, unsigned int curTime, bool ctrl); - - void Tick(); - bool Idle(); - virtual void SetTicking(bool on); - enum TickReason { tickCaret, tickScroll, tickWiden, tickDwell, tickPlatform }; - virtual void TickFor(TickReason reason); - virtual bool FineTickerAvailable(); - virtual bool FineTickerRunning(TickReason reason); - virtual void FineTickerStart(TickReason reason, int millis, int tolerance); - virtual void FineTickerCancel(TickReason reason); - virtual bool SetIdle(bool) { return false; } - virtual void SetMouseCapture(bool on) = 0; - virtual bool HaveMouseCapture() = 0; - void SetFocusState(bool focusState); - - int PositionAfterArea(PRectangle rcArea) const; - void StyleToPositionInView(Position pos); - int PositionAfterMaxStyling(int posMax, bool scrolling) const; - void StartIdleStyling(bool truncatedLastStyling); - void StyleAreaBounded(PRectangle rcArea, bool scrolling); - void IdleStyling(); - virtual void IdleWork(); - virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo=0); - - virtual bool PaintContains(PRectangle rc); - bool PaintContainsMargin(); - void CheckForChangeOutsidePaint(Range r); - void SetBraceHighlight(Position pos0, Position pos1, int matchStyle); - - void SetAnnotationHeights(int start, int end); - virtual void SetDocPointer(Document *document); - - void SetAnnotationVisible(int visible); - - int ExpandLine(int line); - void SetFoldExpanded(int lineDoc, bool expanded); - void FoldLine(int line, int action); - void FoldExpand(int line, int action, int level); - int ContractedFoldNext(int lineStart) const; - void EnsureLineVisible(int lineDoc, bool enforcePolicy); - void FoldChanged(int line, int levelNow, int levelPrev); - void NeedShown(int pos, int len); - void FoldAll(int action); - - int GetTag(char *tagValue, int tagNumber); - int ReplaceTarget(bool replacePatterns, const char *text, int length=-1); - - bool PositionIsHotspot(int position) const; - bool PointIsHotspot(Point pt); - void SetHotSpotRange(Point *pt); - Range GetHotSpotRange() const; - void SetHoverIndicatorPosition(int position); - void SetHoverIndicatorPoint(Point pt); - - int CodePage() const; - virtual bool ValidCodePage(int /* codePage */) const { return true; } - int WrapCount(int line); - void AddStyledText(char *buffer, int appendLength); - - virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0; - bool ValidMargin(uptr_t wParam) const; - void StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - sptr_t StyleGetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - void SetSelectionNMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - - static const char *StringFromEOLMode(int eolMode); - - static sptr_t StringResult(sptr_t lParam, const char *val); - static sptr_t BytesResult(sptr_t lParam, const unsigned char *val, size_t len); - -public: - // Public so the COM thunks can access it. - bool IsUnicodeMode() const; - // Public so scintilla_send_message can use it. - virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); - // Public so scintilla_set_id can use it. - int ctrlID; - // Public so COM methods for drag and drop can set it. - int errorStatus; - friend class AutoSurface; - friend class SelectionLineIterator; -}; - -/** - * A smart pointer class to ensure Surfaces are set up and deleted correctly. - */ -class AutoSurface { -private: - Surface *surf; -public: - AutoSurface(Editor *ed, int technology = -1) : surf(0) { - if (ed->wMain.GetID()) { - surf = Surface::Allocate(technology != -1 ? technology : ed->technology); - if (surf) { - surf->Init(ed->wMain.GetID()); - surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); - surf->SetDBCSMode(ed->CodePage()); - } - } - } - AutoSurface(SurfaceID sid, Editor *ed, int technology = -1) : surf(0) { - if (ed->wMain.GetID()) { - surf = Surface::Allocate(technology != -1 ? technology : ed->technology); - if (surf) { - surf->Init(sid, ed->wMain.GetID()); - surf->SetUnicodeMode(SC_CP_UTF8 == ed->CodePage()); - surf->SetDBCSMode(ed->CodePage()); - } - } - } - ~AutoSurface() { - delete surf; - } - Surface *operator->() const { - return surf; - } - operator Surface *() const { - return surf; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/ExternalLexer.cxx b/qrenderdoc/3rdparty/scintilla/src/ExternalLexer.cxx deleted file mode 100644 index 2f81df7e0..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ExternalLexer.cxx +++ /dev/null @@ -1,192 +0,0 @@ -// Scintilla source code edit control -/** @file ExternalLexer.cxx - ** Support external lexers in DLLs. - **/ -// Copyright 2001 Simon Steele , portions copyright Neil Hodgson. -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include - -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "LexerModule.h" -#include "Catalogue.h" -#include "ExternalLexer.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -LexerManager *LexerManager::theInstance = NULL; - -//------------------------------------------ -// -// ExternalLexerModule -// -//------------------------------------------ - -void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) { - fneFactory = fFactory; - fnFactory = fFactory(index); -} - -//------------------------------------------ -// -// LexerLibrary -// -//------------------------------------------ - -LexerLibrary::LexerLibrary(const char *ModuleName) { - // Initialise some members... - first = NULL; - last = NULL; - - // Load the DLL - lib = DynamicLibrary::Load(ModuleName); - if (lib->IsValid()) { - m_sModuleName = ModuleName; - //Cannot use reinterpret_cast because: ANSI C++ forbids casting between pointers to functions and objects - GetLexerCountFn GetLexerCount = (GetLexerCountFn)(sptr_t)lib->FindFunction("GetLexerCount"); - - if (GetLexerCount) { - ExternalLexerModule *lex; - LexerMinder *lm; - - // Find functions in the DLL - GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName"); - GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory"); - - int nl = GetLexerCount(); - - for (int i = 0; i < nl; i++) { - // Assign a buffer for the lexer name. - char lexname[100] = ""; - GetLexerName(i, lexname, sizeof(lexname)); - lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL); - Catalogue::AddLexerModule(lex); - - // Create a LexerMinder so we don't leak the ExternalLexerModule... - lm = new LexerMinder; - lm->self = lex; - lm->next = NULL; - if (first != NULL) { - last->next = lm; - last = lm; - } else { - first = lm; - last = lm; - } - - // The external lexer needs to know how to call into its DLL to - // do its lexing and folding, we tell it here. - lex->SetExternal(fnFactory, i); - } - } - } - next = NULL; -} - -LexerLibrary::~LexerLibrary() { - Release(); - delete lib; -} - -void LexerLibrary::Release() { - LexerMinder *lm; - LexerMinder *lmNext; - lm = first; - while (NULL != lm) { - lmNext = lm->next; - delete lm->self; - delete lm; - lm = lmNext; - } - - first = NULL; - last = NULL; -} - -//------------------------------------------ -// -// LexerManager -// -//------------------------------------------ - -/// Return the single LexerManager instance... -LexerManager *LexerManager::GetInstance() { - if (!theInstance) - theInstance = new LexerManager; - return theInstance; -} - -/// Delete any LexerManager instance... -void LexerManager::DeleteInstance() { - delete theInstance; - theInstance = NULL; -} - -/// protected constructor - this is a singleton... -LexerManager::LexerManager() { - first = NULL; - last = NULL; -} - -LexerManager::~LexerManager() { - Clear(); -} - -void LexerManager::Load(const char *path) { - LoadLexerLibrary(path); -} - -void LexerManager::LoadLexerLibrary(const char *module) { - for (LexerLibrary *ll = first; ll; ll= ll->next) { - if (strcmp(ll->m_sModuleName.c_str(), module) == 0) - return; - } - LexerLibrary *lib = new LexerLibrary(module); - if (NULL != first) { - last->next = lib; - last = lib; - } else { - first = lib; - last = lib; - } -} - -void LexerManager::Clear() { - if (NULL != first) { - LexerLibrary *cur = first; - LexerLibrary *next; - while (cur) { - next = cur->next; - delete cur; - cur = next; - } - first = NULL; - last = NULL; - } -} - -//------------------------------------------ -// -// LexerManager -// -//------------------------------------------ - -LMMinder::~LMMinder() { - LexerManager::DeleteInstance(); -} - -LMMinder minder; diff --git a/qrenderdoc/3rdparty/scintilla/src/ExternalLexer.h b/qrenderdoc/3rdparty/scintilla/src/ExternalLexer.h deleted file mode 100644 index a85213e31..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ExternalLexer.h +++ /dev/null @@ -1,92 +0,0 @@ -// Scintilla source code edit control -/** @file ExternalLexer.h - ** Support external lexers in DLLs. - **/ -// Copyright 2001 Simon Steele , portions copyright Neil Hodgson. -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef EXTERNALLEXER_H -#define EXTERNALLEXER_H - -#if PLAT_WIN -#define EXT_LEXER_DECL __stdcall -#else -#define EXT_LEXER_DECL -#endif - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -typedef void*(EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index); -typedef int (EXT_LEXER_DECL *GetLexerCountFn)(); -typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength); -typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index); - -/// Sub-class of LexerModule to use an external lexer. -class ExternalLexerModule : public LexerModule { -protected: - GetLexerFactoryFunction fneFactory; - std::string name; -public: - ExternalLexerModule(int language_, LexerFunction fnLexer_, - const char *languageName_=0, LexerFunction fnFolder_=0) : - LexerModule(language_, fnLexer_, 0, fnFolder_), - fneFactory(0), name(languageName_){ - languageName = name.c_str(); - } - virtual void SetExternal(GetLexerFactoryFunction fFactory, int index); -}; - -/// LexerMinder points to an ExternalLexerModule - so we don't leak them. -class LexerMinder { -public: - ExternalLexerModule *self; - LexerMinder *next; -}; - -/// LexerLibrary exists for every External Lexer DLL, contains LexerMinders. -class LexerLibrary { - DynamicLibrary *lib; - LexerMinder *first; - LexerMinder *last; - -public: - explicit LexerLibrary(const char *ModuleName); - ~LexerLibrary(); - void Release(); - - LexerLibrary *next; - std::string m_sModuleName; -}; - -/// LexerManager manages external lexers, contains LexerLibrarys. -class LexerManager { -public: - ~LexerManager(); - - static LexerManager *GetInstance(); - static void DeleteInstance(); - - void Load(const char *path); - void Clear(); - -private: - LexerManager(); - static LexerManager *theInstance; - - void LoadLexerLibrary(const char *module); - LexerLibrary *first; - LexerLibrary *last; -}; - -class LMMinder { -public: - ~LMMinder(); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/FontQuality.h b/qrenderdoc/3rdparty/scintilla/src/FontQuality.h deleted file mode 100644 index a0ae207f8..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/FontQuality.h +++ /dev/null @@ -1,31 +0,0 @@ -// Scintilla source code edit control -/** @file FontQuality.h - ** Definitions to control font anti-aliasing. - ** Redefine constants from Scintilla.h to avoid including Scintilla.h in PlatWin.cxx. - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef FONTQUALITY_H -#define FONTQUALITY_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// These definitions match Scintilla.h -#define SC_EFF_QUALITY_MASK 0xF -#define SC_EFF_QUALITY_DEFAULT 0 -#define SC_EFF_QUALITY_NON_ANTIALIASED 1 -#define SC_EFF_QUALITY_ANTIALIASED 2 -#define SC_EFF_QUALITY_LCD_OPTIMIZED 3 - -// These definitions must match SC_TECHNOLOGY_* in Scintilla.h -#define SCWIN_TECH_GDI 0 -#define SCWIN_TECH_DIRECTWRITE 1 - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Indicator.cxx b/qrenderdoc/3rdparty/scintilla/src/Indicator.cxx deleted file mode 100644 index c23ae4e17..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Indicator.cxx +++ /dev/null @@ -1,194 +0,0 @@ -// Scintilla source code edit control -/** @file Indicator.cxx - ** Defines the style of indicators which are text decorations such as underlining. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Indicator.h" -#include "XPM.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -static PRectangle PixelGridAlign(const PRectangle &rc) { - // Move left and right side to nearest pixel to avoid blurry visuals - return PRectangle::FromInts(int(rc.left + 0.5), int(rc.top), int(rc.right + 0.5), int(rc.bottom)); -} - -void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const { - StyleAndColour sacDraw = sacNormal; - if (Flags() & SC_INDICFLAG_VALUEFORE) { - sacDraw.fore = value & SC_INDICVALUEMASK; - } - if (drawState == drawHover) { - sacDraw = sacHover; - } - surface->PenColour(sacDraw.fore); - int ymid = static_cast(rc.bottom + rc.top) / 2; - if (sacDraw.style == INDIC_SQUIGGLE) { - int x = int(rc.left+0.5); - int xLast = int(rc.right+0.5); - int y = 0; - surface->MoveTo(x, static_cast(rc.top) + y); - while (x < xLast) { - if ((x + 2) > xLast) { - if (xLast > x) - y = 1; - x = xLast; - } else { - x += 2; - y = 2 - y; - } - surface->LineTo(x, static_cast(rc.top) + y); - } - } else if (sacDraw.style == INDIC_SQUIGGLEPIXMAP) { - PRectangle rcSquiggle = PixelGridAlign(rc); - - int width = Platform::Minimum(4000, static_cast(rcSquiggle.Width())); - RGBAImage image(width, 3, 1.0, 0); - enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f }; - for (int x = 0; x < width; x++) { - if (x%2) { - // Two halfway columns have a full pixel in middle flanked by light pixels - image.SetPixel(x, 0, sacDraw.fore, alphaSide); - image.SetPixel(x, 1, sacDraw.fore, alphaFull); - image.SetPixel(x, 2, sacDraw.fore, alphaSide); - } else { - // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in centre - image.SetPixel(x, (x % 4) ? 0 : 2, sacDraw.fore, alphaFull); - image.SetPixel(x, 1, sacDraw.fore, alphaSide2); - } - } - surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels()); - } else if (sacDraw.style == INDIC_SQUIGGLELOW) { - surface->MoveTo(static_cast(rc.left), static_cast(rc.top)); - int x = static_cast(rc.left) + 3; - int y = 0; - while (x < rc.right) { - surface->LineTo(x - 1, static_cast(rc.top) + y); - y = 1 - y; - surface->LineTo(x, static_cast(rc.top) + y); - x += 3; - } - surface->LineTo(static_cast(rc.right), static_cast(rc.top) + y); // Finish the line - } else if (sacDraw.style == INDIC_TT) { - surface->MoveTo(static_cast(rc.left), ymid); - int x = static_cast(rc.left) + 5; - while (x < rc.right) { - surface->LineTo(x, ymid); - surface->MoveTo(x-3, ymid); - surface->LineTo(x-3, ymid+2); - x++; - surface->MoveTo(x, ymid); - x += 5; - } - surface->LineTo(static_cast(rc.right), ymid); // Finish the line - if (x - 3 <= rc.right) { - surface->MoveTo(x-3, ymid); - surface->LineTo(x-3, ymid+2); - } - } else if (sacDraw.style == INDIC_DIAGONAL) { - int x = static_cast(rc.left); - while (x < rc.right) { - surface->MoveTo(x, static_cast(rc.top) + 2); - int endX = x+3; - int endY = static_cast(rc.top) - 1; - if (endX > rc.right) { - endY += endX - static_cast(rc.right); - endX = static_cast(rc.right); - } - surface->LineTo(endX, endY); - x += 4; - } - } else if (sacDraw.style == INDIC_STRIKE) { - surface->MoveTo(static_cast(rc.left), static_cast(rc.top) - 4); - surface->LineTo(static_cast(rc.right), static_cast(rc.top) - 4); - } else if ((sacDraw.style == INDIC_HIDDEN) || (sacDraw.style == INDIC_TEXTFORE)) { - // Draw nothing - } else if (sacDraw.style == INDIC_BOX) { - surface->MoveTo(static_cast(rc.left), ymid + 1); - surface->LineTo(static_cast(rc.right), ymid + 1); - surface->LineTo(static_cast(rc.right), static_cast(rcLine.top) + 1); - surface->LineTo(static_cast(rc.left), static_cast(rcLine.top) + 1); - surface->LineTo(static_cast(rc.left), ymid + 1); - } else if (sacDraw.style == INDIC_ROUNDBOX || - sacDraw.style == INDIC_STRAIGHTBOX || - sacDraw.style == INDIC_FULLBOX) { - PRectangle rcBox = rcLine; - if (sacDraw.style != INDIC_FULLBOX) - rcBox.top = rcLine.top + 1; - rcBox.left = rc.left; - rcBox.right = rc.right; - surface->AlphaRectangle(rcBox, (sacDraw.style == INDIC_ROUNDBOX) ? 1 : 0, - sacDraw.fore, fillAlpha, sacDraw.fore, outlineAlpha, 0); - } else if (sacDraw.style == INDIC_DOTBOX) { - PRectangle rcBox = PixelGridAlign(rc); - rcBox.top = rcLine.top + 1; - rcBox.bottom = rcLine.bottom; - // Cap width at 4000 to avoid large allocations when mistakes made - int width = Platform::Minimum(static_cast(rcBox.Width()), 4000); - RGBAImage image(width, static_cast(rcBox.Height()), 1.0, 0); - // Draw horizontal lines top and bottom - for (int x=0; x(rcBox.Height()); y += static_cast(rcBox.Height()) - 1) { - image.SetPixel(x, y, sacDraw.fore, ((x + y) % 2) ? outlineAlpha : fillAlpha); - } - } - // Draw vertical lines left and right - for (int y = 1; y(rcBox.Height()); y++) { - for (int x=0; xDrawRGBAImage(rcBox, image.GetWidth(), image.GetHeight(), image.Pixels()); - } else if (sacDraw.style == INDIC_DASH) { - int x = static_cast(rc.left); - while (x < rc.right) { - surface->MoveTo(x, ymid); - surface->LineTo(Platform::Minimum(x + 4, static_cast(rc.right)), ymid); - x += 7; - } - } else if (sacDraw.style == INDIC_DOTS) { - int x = static_cast(rc.left); - while (x < static_cast(rc.right)) { - PRectangle rcDot = PRectangle::FromInts(x, ymid, x + 1, ymid + 1); - surface->FillRectangle(rcDot, sacDraw.fore); - x += 2; - } - } else if (sacDraw.style == INDIC_COMPOSITIONTHICK) { - PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom); - surface->FillRectangle(rcComposition, sacDraw.fore); - } else if (sacDraw.style == INDIC_COMPOSITIONTHIN) { - PRectangle rcComposition(rc.left+1, rcLine.bottom-2, rc.right-1, rcLine.bottom-1); - surface->FillRectangle(rcComposition, sacDraw.fore); - } else if (sacDraw.style == INDIC_POINT || sacDraw.style == INDIC_POINTCHARACTER) { - if (rcCharacter.Width() >= 0.1) { - const int pixelHeight = static_cast(rc.Height() - 1.0f); // 1 pixel onto next line if multiphase - const XYPOSITION x = (sacDraw.style == INDIC_POINT) ? (rcCharacter.left) : ((rcCharacter.right + rcCharacter.left) / 2); - const int ix = static_cast(x + 0.5f); - const int iy = static_cast(rc.top + 1.0f); - Point pts[] = { - Point::FromInts(ix - pixelHeight, iy + pixelHeight), // Left - Point::FromInts(ix + pixelHeight, iy + pixelHeight), // Right - Point::FromInts(ix, iy) // Top - }; - surface->Polygon(pts, 3, sacDraw.fore, sacDraw.fore); - } - } else { // Either INDIC_PLAIN or unknown - surface->MoveTo(static_cast(rc.left), ymid); - surface->LineTo(static_cast(rc.right), ymid); - } -} - -void Indicator::SetFlags(int attributes_) { - attributes = attributes_; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/Indicator.h b/qrenderdoc/3rdparty/scintilla/src/Indicator.h deleted file mode 100644 index 9b887df9d..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Indicator.h +++ /dev/null @@ -1,60 +0,0 @@ -// Scintilla source code edit control -/** @file Indicator.h - ** Defines the style of indicators which are text decorations such as underlining. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef INDICATOR_H -#define INDICATOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -struct StyleAndColour { - int style; - ColourDesired fore; - StyleAndColour() : style(INDIC_PLAIN), fore(0, 0, 0) { - } - StyleAndColour(int style_, ColourDesired fore_ = ColourDesired(0, 0, 0)) : style(style_), fore(fore_) { - } - bool operator==(const StyleAndColour &other) const { - return (style == other.style) && (fore == other.fore); - } -}; - -/** - */ -class Indicator { -public: - enum DrawState { drawNormal, drawHover }; - StyleAndColour sacNormal; - StyleAndColour sacHover; - bool under; - int fillAlpha; - int outlineAlpha; - int attributes; - Indicator() : under(false), fillAlpha(30), outlineAlpha(50), attributes(0) { - } - Indicator(int style_, ColourDesired fore_=ColourDesired(0,0,0), bool under_=false, int fillAlpha_=30, int outlineAlpha_=50) : - sacNormal(style_, fore_), sacHover(style_, fore_), under(under_), fillAlpha(fillAlpha_), outlineAlpha(outlineAlpha_), attributes(0) { - } - void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine, const PRectangle &rcCharacter, DrawState drawState, int value) const; - bool IsDynamic() const { - return !(sacNormal == sacHover); - } - bool OverridesTextFore() const { - return sacNormal.style == INDIC_TEXTFORE || sacHover.style == INDIC_TEXTFORE; - } - int Flags() const { - return attributes; - } - void SetFlags(int attributes_); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/KeyMap.cxx b/qrenderdoc/3rdparty/scintilla/src/KeyMap.cxx deleted file mode 100644 index a6b1cf6c4..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/KeyMap.cxx +++ /dev/null @@ -1,161 +0,0 @@ -// Scintilla source code edit control -/** @file KeyMap.cxx - ** Defines a mapping between keystrokes and commands. - **/ -// Copyright 1998-2003 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" - -#include "KeyMap.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -KeyMap::KeyMap() { - for (int i = 0; MapDefault[i].key; i++) { - AssignCmdKey(MapDefault[i].key, - MapDefault[i].modifiers, - MapDefault[i].msg); - } -} - -KeyMap::~KeyMap() { - Clear(); -} - -void KeyMap::Clear() { - kmap.clear(); -} - -void KeyMap::AssignCmdKey(int key, int modifiers, unsigned int msg) { - kmap[KeyModifiers(key, modifiers)] = msg; -} - -unsigned int KeyMap::Find(int key, int modifiers) const { - std::map::const_iterator it = kmap.find(KeyModifiers(key, modifiers)); - return (it == kmap.end()) ? 0 : it->second; -} - -#if PLAT_GTK_MACOSX -#define OS_X_KEYS 1 -#else -#define OS_X_KEYS 0 -#endif - -// Define a modifier that is exactly Ctrl key on all platforms -// Most uses of Ctrl map to Cmd on OS X but some can't so use SCI_[S]CTRL_META -#if OS_X_KEYS -#define SCI_CTRL_META SCI_META -#define SCI_SCTRL_META (SCI_META | SCI_SHIFT) -#else -#define SCI_CTRL_META SCI_CTRL -#define SCI_SCTRL_META (SCI_CTRL | SCI_SHIFT) -#endif - -const KeyToCommand KeyMap::MapDefault[] = { - -#if OS_X_KEYS - {SCK_DOWN, SCI_CTRL, SCI_DOCUMENTEND}, - {SCK_DOWN, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, - {SCK_UP, SCI_CTRL, SCI_DOCUMENTSTART}, - {SCK_UP, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, - {SCK_LEFT, SCI_CTRL, SCI_VCHOME}, - {SCK_LEFT, SCI_CSHIFT, SCI_VCHOMEEXTEND}, - {SCK_RIGHT, SCI_CTRL, SCI_LINEEND}, - {SCK_RIGHT, SCI_CSHIFT, SCI_LINEENDEXTEND}, -#endif - - {SCK_DOWN, SCI_NORM, SCI_LINEDOWN}, - {SCK_DOWN, SCI_SHIFT, SCI_LINEDOWNEXTEND}, - {SCK_DOWN, SCI_CTRL_META, SCI_LINESCROLLDOWN}, - {SCK_DOWN, SCI_ASHIFT, SCI_LINEDOWNRECTEXTEND}, - {SCK_UP, SCI_NORM, SCI_LINEUP}, - {SCK_UP, SCI_SHIFT, SCI_LINEUPEXTEND}, - {SCK_UP, SCI_CTRL_META, SCI_LINESCROLLUP}, - {SCK_UP, SCI_ASHIFT, SCI_LINEUPRECTEXTEND}, - {'[', SCI_CTRL, SCI_PARAUP}, - {'[', SCI_CSHIFT, SCI_PARAUPEXTEND}, - {']', SCI_CTRL, SCI_PARADOWN}, - {']', SCI_CSHIFT, SCI_PARADOWNEXTEND}, - {SCK_LEFT, SCI_NORM, SCI_CHARLEFT}, - {SCK_LEFT, SCI_SHIFT, SCI_CHARLEFTEXTEND}, - {SCK_LEFT, SCI_CTRL_META, SCI_WORDLEFT}, - {SCK_LEFT, SCI_SCTRL_META, SCI_WORDLEFTEXTEND}, - {SCK_LEFT, SCI_ASHIFT, SCI_CHARLEFTRECTEXTEND}, - {SCK_RIGHT, SCI_NORM, SCI_CHARRIGHT}, - {SCK_RIGHT, SCI_SHIFT, SCI_CHARRIGHTEXTEND}, - {SCK_RIGHT, SCI_CTRL_META, SCI_WORDRIGHT}, - {SCK_RIGHT, SCI_SCTRL_META, SCI_WORDRIGHTEXTEND}, - {SCK_RIGHT, SCI_ASHIFT, SCI_CHARRIGHTRECTEXTEND}, - {'/', SCI_CTRL, SCI_WORDPARTLEFT}, - {'/', SCI_CSHIFT, SCI_WORDPARTLEFTEXTEND}, - {'\\', SCI_CTRL, SCI_WORDPARTRIGHT}, - {'\\', SCI_CSHIFT, SCI_WORDPARTRIGHTEXTEND}, - {SCK_HOME, SCI_NORM, SCI_VCHOME}, - {SCK_HOME, SCI_SHIFT, SCI_VCHOMEEXTEND}, - {SCK_HOME, SCI_CTRL, SCI_DOCUMENTSTART}, - {SCK_HOME, SCI_CSHIFT, SCI_DOCUMENTSTARTEXTEND}, - {SCK_HOME, SCI_ALT, SCI_HOMEDISPLAY}, - {SCK_HOME, SCI_ASHIFT, SCI_VCHOMERECTEXTEND}, - {SCK_END, SCI_NORM, SCI_LINEEND}, - {SCK_END, SCI_SHIFT, SCI_LINEENDEXTEND}, - {SCK_END, SCI_CTRL, SCI_DOCUMENTEND}, - {SCK_END, SCI_CSHIFT, SCI_DOCUMENTENDEXTEND}, - {SCK_END, SCI_ALT, SCI_LINEENDDISPLAY}, - {SCK_END, SCI_ASHIFT, SCI_LINEENDRECTEXTEND}, - {SCK_PRIOR, SCI_NORM, SCI_PAGEUP}, - {SCK_PRIOR, SCI_SHIFT, SCI_PAGEUPEXTEND}, - {SCK_PRIOR, SCI_ASHIFT, SCI_PAGEUPRECTEXTEND}, - {SCK_NEXT, SCI_NORM, SCI_PAGEDOWN}, - {SCK_NEXT, SCI_SHIFT, SCI_PAGEDOWNEXTEND}, - {SCK_NEXT, SCI_ASHIFT, SCI_PAGEDOWNRECTEXTEND}, - {SCK_DELETE, SCI_NORM, SCI_CLEAR}, - {SCK_DELETE, SCI_SHIFT, SCI_CUT}, - {SCK_DELETE, SCI_CTRL, SCI_DELWORDRIGHT}, - {SCK_DELETE, SCI_CSHIFT, SCI_DELLINERIGHT}, - {SCK_INSERT, SCI_NORM, SCI_EDITTOGGLEOVERTYPE}, - {SCK_INSERT, SCI_SHIFT, SCI_PASTE}, - {SCK_INSERT, SCI_CTRL, SCI_COPY}, - {SCK_ESCAPE, SCI_NORM, SCI_CANCEL}, - {SCK_BACK, SCI_NORM, SCI_DELETEBACK}, - {SCK_BACK, SCI_SHIFT, SCI_DELETEBACK}, - {SCK_BACK, SCI_CTRL, SCI_DELWORDLEFT}, - {SCK_BACK, SCI_ALT, SCI_UNDO}, - {SCK_BACK, SCI_CSHIFT, SCI_DELLINELEFT}, - {'Z', SCI_CTRL, SCI_UNDO}, -#if OS_X_KEYS - {'Z', SCI_CSHIFT, SCI_REDO}, -#else - {'Y', SCI_CTRL, SCI_REDO}, -#endif - {'X', SCI_CTRL, SCI_CUT}, - {'C', SCI_CTRL, SCI_COPY}, - {'V', SCI_CTRL, SCI_PASTE}, - {'A', SCI_CTRL, SCI_SELECTALL}, - {SCK_TAB, SCI_NORM, SCI_TAB}, - {SCK_TAB, SCI_SHIFT, SCI_BACKTAB}, - {SCK_RETURN, SCI_NORM, SCI_NEWLINE}, - {SCK_RETURN, SCI_SHIFT, SCI_NEWLINE}, - {SCK_ADD, SCI_CTRL, SCI_ZOOMIN}, - {SCK_SUBTRACT, SCI_CTRL, SCI_ZOOMOUT}, - {SCK_DIVIDE, SCI_CTRL, SCI_SETZOOM}, - {'L', SCI_CTRL, SCI_LINECUT}, - {'L', SCI_CSHIFT, SCI_LINEDELETE}, - {'T', SCI_CSHIFT, SCI_LINECOPY}, - {'T', SCI_CTRL, SCI_LINETRANSPOSE}, - {'D', SCI_CTRL, SCI_SELECTIONDUPLICATE}, - {'U', SCI_CTRL, SCI_LOWERCASE}, - {'U', SCI_CSHIFT, SCI_UPPERCASE}, - {0,0,0}, -}; - diff --git a/qrenderdoc/3rdparty/scintilla/src/KeyMap.h b/qrenderdoc/3rdparty/scintilla/src/KeyMap.h deleted file mode 100644 index 7c4f80720..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/KeyMap.h +++ /dev/null @@ -1,67 +0,0 @@ -// Scintilla source code edit control -/** @file KeyMap.h - ** Defines a mapping between keystrokes and commands. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef KEYMAP_H -#define KEYMAP_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#define SCI_NORM 0 -#define SCI_SHIFT SCMOD_SHIFT -#define SCI_CTRL SCMOD_CTRL -#define SCI_ALT SCMOD_ALT -#define SCI_META SCMOD_META -#define SCI_SUPER SCMOD_SUPER -#define SCI_CSHIFT (SCI_CTRL | SCI_SHIFT) -#define SCI_ASHIFT (SCI_ALT | SCI_SHIFT) - -/** - */ -class KeyModifiers { -public: - int key; - int modifiers; - KeyModifiers(int key_, int modifiers_) : key(key_), modifiers(modifiers_) { - } - bool operator<(const KeyModifiers &other) const { - if (key == other.key) - return modifiers < other.modifiers; - else - return key < other.key; - } -}; - -/** - */ -class KeyToCommand { -public: - int key; - int modifiers; - unsigned int msg; -}; - -/** - */ -class KeyMap { - std::map kmap; - static const KeyToCommand MapDefault[]; - -public: - KeyMap(); - ~KeyMap(); - void Clear(); - void AssignCmdKey(int key, int modifiers, unsigned int msg); - unsigned int Find(int key, int modifiers) const; // 0 returned on failure -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/LineMarker.cxx b/qrenderdoc/3rdparty/scintilla/src/LineMarker.cxx deleted file mode 100644 index 6239d1c9d..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/LineMarker.cxx +++ /dev/null @@ -1,399 +0,0 @@ -// Scintilla source code edit control -/** @file LineMarker.cxx - ** Defines the look of a line marker in the margin. - **/ -// Copyright 1998-2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include - -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" - -#include "StringCopy.h" -#include "XPM.h" -#include "LineMarker.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -void LineMarker::SetXPM(const char *textForm) { - delete pxpm; - pxpm = new XPM(textForm); - markType = SC_MARK_PIXMAP; -} - -void LineMarker::SetXPM(const char *const *linesForm) { - delete pxpm; - pxpm = new XPM(linesForm); - markType = SC_MARK_PIXMAP; -} - -void LineMarker::SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage) { - delete image; - image = new RGBAImage(static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), scale, pixelsRGBAImage); - markType = SC_MARK_RGBAIMAGE; -} - -static void DrawBox(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { - PRectangle rc = PRectangle::FromInts( - centreX - armSize, - centreY - armSize, - centreX + armSize + 1, - centreY + armSize + 1); - surface->RectangleDraw(rc, back, fore); -} - -static void DrawCircle(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore, ColourDesired back) { - PRectangle rcCircle = PRectangle::FromInts( - centreX - armSize, - centreY - armSize, - centreX + armSize + 1, - centreY + armSize + 1); - surface->Ellipse(rcCircle, back, fore); -} - -static void DrawPlus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { - PRectangle rcV = PRectangle::FromInts(centreX, centreY - armSize + 2, centreX + 1, centreY + armSize - 2 + 1); - surface->FillRectangle(rcV, fore); - PRectangle rcH = PRectangle::FromInts(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY + 1); - surface->FillRectangle(rcH, fore); -} - -static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, ColourDesired fore) { - PRectangle rcH = PRectangle::FromInts(centreX - armSize + 2, centreY, centreX + armSize - 2 + 1, centreY + 1); - surface->FillRectangle(rcH, fore); -} - -void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold, int marginStyle) const { - if (customDraw != NULL) { - customDraw(surface, rcWhole, fontForCharacter, tFold, marginStyle, this); - return; - } - - ColourDesired colourHead = back; - ColourDesired colourBody = back; - ColourDesired colourTail = back; - - switch (tFold) { - case LineMarker::head : - case LineMarker::headWithTail : - colourHead = backSelected; - colourTail = backSelected; - break; - case LineMarker::body : - colourHead = backSelected; - colourBody = backSelected; - break; - case LineMarker::tail : - colourBody = backSelected; - colourTail = backSelected; - break; - default : - // LineMarker::undefined - break; - } - - if ((markType == SC_MARK_PIXMAP) && (pxpm)) { - pxpm->Draw(surface, rcWhole); - return; - } - if ((markType == SC_MARK_RGBAIMAGE) && (image)) { - // Make rectangle just large enough to fit image centred on centre of rcWhole - PRectangle rcImage; - rcImage.top = ((rcWhole.top + rcWhole.bottom) - image->GetScaledHeight()) / 2; - rcImage.bottom = rcImage.top + image->GetScaledHeight(); - rcImage.left = ((rcWhole.left + rcWhole.right) - image->GetScaledWidth()) / 2; - rcImage.right = rcImage.left + image->GetScaledWidth(); - surface->DrawRGBAImage(rcImage, image->GetWidth(), image->GetHeight(), image->Pixels()); - return; - } - // Restrict most shapes a bit - PRectangle rc = rcWhole; - rc.top++; - rc.bottom--; - int minDim = Platform::Minimum(static_cast(rc.Width()), static_cast(rc.Height())); - minDim--; // Ensure does not go beyond edge - int centreX = static_cast(floor((rc.right + rc.left) / 2.0)); - int centreY = static_cast(floor((rc.bottom + rc.top) / 2.0)); - int dimOn2 = minDim / 2; - int dimOn4 = minDim / 4; - int blobSize = dimOn2-1; - int armSize = dimOn2-2; - if (marginStyle == SC_MARGIN_NUMBER || marginStyle == SC_MARGIN_TEXT || marginStyle == SC_MARGIN_RTEXT) { - // On textual margins move marker to the left to try to avoid overlapping the text - centreX = static_cast(rc.left) + dimOn2 + 1; - } - if (markType == SC_MARK_ROUNDRECT) { - PRectangle rcRounded = rc; - rcRounded.left = rc.left + 1; - rcRounded.right = rc.right - 1; - surface->RoundedRectangle(rcRounded, fore, back); - } else if (markType == SC_MARK_CIRCLE) { - PRectangle rcCircle = PRectangle::FromInts( - centreX - dimOn2, - centreY - dimOn2, - centreX + dimOn2, - centreY + dimOn2); - surface->Ellipse(rcCircle, fore, back); - } else if (markType == SC_MARK_ARROW) { - Point pts[] = { - Point::FromInts(centreX - dimOn4, centreY - dimOn2), - Point::FromInts(centreX - dimOn4, centreY + dimOn2), - Point::FromInts(centreX + dimOn2 - dimOn4, centreY), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_ARROWDOWN) { - Point pts[] = { - Point::FromInts(centreX - dimOn2, centreY - dimOn4), - Point::FromInts(centreX + dimOn2, centreY - dimOn4), - Point::FromInts(centreX, centreY + dimOn2 - dimOn4), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_PLUS) { - Point pts[] = { - Point::FromInts(centreX - armSize, centreY - 1), - Point::FromInts(centreX - 1, centreY - 1), - Point::FromInts(centreX - 1, centreY - armSize), - Point::FromInts(centreX + 1, centreY - armSize), - Point::FromInts(centreX + 1, centreY - 1), - Point::FromInts(centreX + armSize, centreY -1), - Point::FromInts(centreX + armSize, centreY +1), - Point::FromInts(centreX + 1, centreY + 1), - Point::FromInts(centreX + 1, centreY + armSize), - Point::FromInts(centreX - 1, centreY + armSize), - Point::FromInts(centreX - 1, centreY + 1), - Point::FromInts(centreX - armSize, centreY + 1), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_MINUS) { - Point pts[] = { - Point::FromInts(centreX - armSize, centreY - 1), - Point::FromInts(centreX + armSize, centreY -1), - Point::FromInts(centreX + armSize, centreY +1), - Point::FromInts(centreX - armSize, centreY + 1), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - - } else if (markType == SC_MARK_SMALLRECT) { - PRectangle rcSmall; - rcSmall.left = rc.left + 1; - rcSmall.top = rc.top + 2; - rcSmall.right = rc.right - 1; - rcSmall.bottom = rc.bottom - 2; - surface->RectangleDraw(rcSmall, fore, back); - - } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND || - markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) { - // An invisible marker so don't draw anything - - } else if (markType == SC_MARK_VLINE) { - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - } else if (markType == SC_MARK_LCORNER) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY); - surface->LineTo(static_cast(rc.right) - 1, centreY); - - } else if (markType == SC_MARK_TCORNER) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, centreY); - surface->LineTo(static_cast(rc.right) - 1, centreY); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY + 1); - - surface->PenColour(colourHead); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - } else if (markType == SC_MARK_LCORNERCURVE) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY-3); - surface->LineTo(centreX+3, centreY); - surface->LineTo(static_cast(rc.right) - 1, centreY); - - } else if (markType == SC_MARK_TCORNERCURVE) { - surface->PenColour(colourTail); - surface->MoveTo(centreX, centreY-3); - surface->LineTo(centreX+3, centreY); - surface->LineTo(static_cast(rc.right) - 1, centreY); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY-2); - - surface->PenColour(colourHead); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - } else if (markType == SC_MARK_BOXPLUS) { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_BOXPLUSCONNECTED) { - if (tFold == LineMarker::headWithTail) - surface->PenColour(colourTail); - else - surface->PenColour(colourBody); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY - blobSize); - - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - if (tFold == LineMarker::body) { - surface->PenColour(colourTail); - surface->MoveTo(centreX + 1, centreY + blobSize); - surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - - surface->MoveTo(centreX + blobSize, centreY + blobSize); - surface->LineTo(centreX + blobSize, centreY - blobSize); - - surface->MoveTo(centreX + 1, centreY - blobSize); - surface->LineTo(centreX + blobSize + 1, centreY - blobSize); - } - } else if (markType == SC_MARK_BOXMINUS) { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - } else if (markType == SC_MARK_BOXMINUSCONNECTED) { - DrawBox(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY - blobSize); - - if (tFold == LineMarker::body) { - surface->PenColour(colourTail); - surface->MoveTo(centreX + 1, centreY + blobSize); - surface->LineTo(centreX + blobSize + 1, centreY + blobSize); - - surface->MoveTo(centreX + blobSize, centreY + blobSize); - surface->LineTo(centreX + blobSize, centreY - blobSize); - - surface->MoveTo(centreX + 1, centreY - blobSize); - surface->LineTo(centreX + blobSize + 1, centreY - blobSize); - } - } else if (markType == SC_MARK_CIRCLEPLUS) { - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) { - if (tFold == LineMarker::headWithTail) - surface->PenColour(colourTail); - else - surface->PenColour(colourBody); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY - blobSize); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawPlus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_CIRCLEMINUS) { - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) { - surface->PenColour(colourHead); - surface->MoveTo(centreX, centreY + blobSize); - surface->LineTo(centreX, static_cast(rcWhole.bottom)); - - surface->PenColour(colourBody); - surface->MoveTo(centreX, static_cast(rcWhole.top)); - surface->LineTo(centreX, centreY - blobSize); - - DrawCircle(surface, centreX, centreY, blobSize, fore, colourHead); - DrawMinus(surface, centreX, centreY, blobSize, colourTail); - - } else if (markType >= SC_MARK_CHARACTER) { - char character[1]; - character[0] = static_cast(markType - SC_MARK_CHARACTER); - XYPOSITION width = surface->WidthText(fontForCharacter, character, 1); - rc.left += (rc.Width() - width) / 2; - rc.right = rc.left + width; - surface->DrawTextClipped(rc, fontForCharacter, rc.bottom - 2, - character, 1, fore, back); - - } else if (markType == SC_MARK_DOTDOTDOT) { - XYPOSITION right = static_cast(centreX - 6); - for (int b=0; b<3; b++) { - PRectangle rcBlob(right, rc.bottom - 4, right + 2, rc.bottom-2); - surface->FillRectangle(rcBlob, fore); - right += 5.0f; - } - } else if (markType == SC_MARK_ARROWS) { - surface->PenColour(fore); - int right = centreX - 2; - const int armLength = dimOn2 - 1; - for (int b = 0; b<3; b++) { - surface->MoveTo(right, centreY); - surface->LineTo(right - armLength, centreY - armLength); - surface->MoveTo(right, centreY); - surface->LineTo(right - armLength, centreY + armLength); - right += 4; - } - } else if (markType == SC_MARK_SHORTARROW) { - Point pts[] = { - Point::FromInts(centreX, centreY + dimOn2), - Point::FromInts(centreX + dimOn2, centreY), - Point::FromInts(centreX, centreY - dimOn2), - Point::FromInts(centreX, centreY - dimOn4), - Point::FromInts(centreX - dimOn4, centreY - dimOn4), - Point::FromInts(centreX - dimOn4, centreY + dimOn4), - Point::FromInts(centreX, centreY + dimOn4), - Point::FromInts(centreX, centreY + dimOn2), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - } else if (markType == SC_MARK_LEFTRECT) { - PRectangle rcLeft = rcWhole; - rcLeft.right = rcLeft.left + 4; - surface->FillRectangle(rcLeft, back); - } else if (markType == SC_MARK_BOOKMARK) { - int halfHeight = minDim / 3; - Point pts[] = { - Point::FromInts(static_cast(rc.left), centreY-halfHeight), - Point::FromInts(static_cast(rc.right) - 3, centreY - halfHeight), - Point::FromInts(static_cast(rc.right) - 3 - halfHeight, centreY), - Point::FromInts(static_cast(rc.right) - 3, centreY + halfHeight), - Point::FromInts(static_cast(rc.left), centreY + halfHeight), - }; - surface->Polygon(pts, ELEMENTS(pts), fore, back); - } else { // SC_MARK_FULLRECT - surface->FillRectangle(rcWhole, back); - } -} diff --git a/qrenderdoc/3rdparty/scintilla/src/LineMarker.h b/qrenderdoc/3rdparty/scintilla/src/LineMarker.h deleted file mode 100644 index 6a5fe7492..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/LineMarker.h +++ /dev/null @@ -1,86 +0,0 @@ -// Scintilla source code edit control -/** @file LineMarker.h - ** Defines the look of a line marker in the margin . - **/ -// Copyright 1998-2011 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef LINEMARKER_H -#define LINEMARKER_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -typedef void (*DrawLineMarkerFn)(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, int tFold, int marginStyle, const void *lineMarker); - -/** - */ -class LineMarker { -public: - enum typeOfFold { undefined, head, body, tail, headWithTail }; - - int markType; - ColourDesired fore; - ColourDesired back; - ColourDesired backSelected; - int alpha; - XPM *pxpm; - RGBAImage *image; - /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native - * Draw function for drawing line markers. Allow those platforms to override - * it instead of creating a new method(s) in the Surface class that existing - * platforms must implement as empty. */ - DrawLineMarkerFn customDraw; - LineMarker() { - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0,0,0); - back = ColourDesired(0xff,0xff,0xff); - backSelected = ColourDesired(0xff,0x00,0x00); - alpha = SC_ALPHA_NOALPHA; - pxpm = NULL; - image = NULL; - customDraw = NULL; - } - LineMarker(const LineMarker &) { - // Defined to avoid pxpm being blindly copied, not as a complete copy constructor - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0,0,0); - back = ColourDesired(0xff,0xff,0xff); - backSelected = ColourDesired(0xff,0x00,0x00); - alpha = SC_ALPHA_NOALPHA; - pxpm = NULL; - image = NULL; - customDraw = NULL; - } - ~LineMarker() { - delete pxpm; - delete image; - } - LineMarker &operator=(const LineMarker &other) { - // Defined to avoid pxpm being blindly copied, not as a complete assignment operator - if (this != &other) { - markType = SC_MARK_CIRCLE; - fore = ColourDesired(0,0,0); - back = ColourDesired(0xff,0xff,0xff); - backSelected = ColourDesired(0xff,0x00,0x00); - alpha = SC_ALPHA_NOALPHA; - delete pxpm; - pxpm = NULL; - delete image; - image = NULL; - customDraw = NULL; - } - return *this; - } - void SetXPM(const char *textForm); - void SetXPM(const char *const *linesForm); - void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage); - void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold, int marginStyle) const; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/MarginView.cxx b/qrenderdoc/3rdparty/scintilla/src/MarginView.cxx deleted file mode 100644 index 3ec70f01e..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/MarginView.cxx +++ /dev/null @@ -1,474 +0,0 @@ -// Scintilla source code edit control -/** @file MarginView.cxx - ** Defines the appearance of the editor margin. - **/ -// Copyright 1998-2014 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "StringCopy.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "UniConversion.h" -#include "Selection.h" -#include "PositionCache.h" -#include "EditModel.h" -#include "MarginView.h" -#include "EditView.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -void DrawWrapMarker(Surface *surface, PRectangle rcPlace, - bool isEndMarker, ColourDesired wrapColour) { - surface->PenColour(wrapColour); - - enum { xa = 1 }; // gap before start - int w = static_cast(rcPlace.right - rcPlace.left) - xa - 1; - - bool xStraight = isEndMarker; // x-mirrored symbol for start marker - - int x0 = static_cast(xStraight ? rcPlace.left : rcPlace.right - 1); - int y0 = static_cast(rcPlace.top); - - int dy = static_cast(rcPlace.bottom - rcPlace.top) / 5; - int y = static_cast(rcPlace.bottom - rcPlace.top) / 2 + dy; - - struct Relative { - Surface *surface; - int xBase; - int xDir; - int yBase; - int yDir; - void MoveTo(int xRelative, int yRelative) { - surface->MoveTo(xBase + xDir * xRelative, yBase + yDir * yRelative); - } - void LineTo(int xRelative, int yRelative) { - surface->LineTo(xBase + xDir * xRelative, yBase + yDir * yRelative); - } - }; - Relative rel = { surface, x0, xStraight ? 1 : -1, y0, 1 }; - - // arrow head - rel.MoveTo(xa, y); - rel.LineTo(xa + 2 * w / 3, y - dy); - rel.MoveTo(xa, y); - rel.LineTo(xa + 2 * w / 3, y + dy); - - // arrow body - rel.MoveTo(xa, y); - rel.LineTo(xa + w, y); - rel.LineTo(xa + w, y - 2 * dy); - rel.LineTo(xa - 1, // on windows lineto is exclusive endpoint, perhaps GTK not... - y - 2 * dy); -} - -MarginView::MarginView() { - pixmapSelMargin = 0; - pixmapSelPattern = 0; - pixmapSelPatternOffset1 = 0; - wrapMarkerPaddingRight = 3; - customDrawWrapMarker = NULL; -} - -void MarginView::DropGraphics(bool freeObjects) { - if (freeObjects) { - delete pixmapSelMargin; - pixmapSelMargin = 0; - delete pixmapSelPattern; - pixmapSelPattern = 0; - delete pixmapSelPatternOffset1; - pixmapSelPatternOffset1 = 0; - } else { - if (pixmapSelMargin) - pixmapSelMargin->Release(); - if (pixmapSelPattern) - pixmapSelPattern->Release(); - if (pixmapSelPatternOffset1) - pixmapSelPatternOffset1->Release(); - } -} - -void MarginView::AllocateGraphics(const ViewStyle &vsDraw) { - if (!pixmapSelMargin) - pixmapSelMargin = Surface::Allocate(vsDraw.technology); - if (!pixmapSelPattern) - pixmapSelPattern = Surface::Allocate(vsDraw.technology); - if (!pixmapSelPatternOffset1) - pixmapSelPatternOffset1 = Surface::Allocate(vsDraw.technology); -} - -void MarginView::RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw) { - if (!pixmapSelPattern->Initialised()) { - const int patternSize = 8; - pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow, wid); - pixmapSelPatternOffset1->InitPixMap(patternSize, patternSize, surfaceWindow, wid); - // This complex procedure is to reproduce the checkerboard dithered pattern used by windows - // for scroll bars and Visual Studio for its selection margin. The colour of this pattern is half - // way between the chrome colour and the chrome highlight colour making a nice transition - // between the window chrome and the content area. And it works in low colour depths. - PRectangle rcPattern = PRectangle::FromInts(0, 0, patternSize, patternSize); - - // Initialize default colours based on the chrome colour scheme. Typically the highlight is white. - ColourDesired colourFMFill = vsDraw.selbar; - ColourDesired colourFMStripes = vsDraw.selbarlight; - - if (!(vsDraw.selbarlight == ColourDesired(0xff, 0xff, 0xff))) { - // User has chosen an unusual chrome colour scheme so just use the highlight edge colour. - // (Typically, the highlight colour is white.) - colourFMFill = vsDraw.selbarlight; - } - - if (vsDraw.foldmarginColour.isSet) { - // override default fold margin colour - colourFMFill = vsDraw.foldmarginColour; - } - if (vsDraw.foldmarginHighlightColour.isSet) { - // override default fold margin highlight colour - colourFMStripes = vsDraw.foldmarginHighlightColour; - } - - pixmapSelPattern->FillRectangle(rcPattern, colourFMFill); - pixmapSelPatternOffset1->FillRectangle(rcPattern, colourFMStripes); - for (int y = 0; y < patternSize; y++) { - for (int x = y % 2; x < patternSize; x += 2) { - PRectangle rcPixel = PRectangle::FromInts(x, y, x + 1, y + 1); - pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes); - pixmapSelPatternOffset1->FillRectangle(rcPixel, colourFMFill); - } - } - } -} - -static int SubstituteMarkerIfEmpty(int markerCheck, int markerDefault, const ViewStyle &vs) { - if (vs.markers[markerCheck].markType == SC_MARK_EMPTY) - return markerDefault; - return markerCheck; -} - -void MarginView::PaintMargin(Surface *surface, int topLine, PRectangle rc, PRectangle rcMargin, - const EditModel &model, const ViewStyle &vs) { - - PRectangle rcSelMargin = rcMargin; - rcSelMargin.right = rcMargin.left; - if (rcSelMargin.bottom < rc.bottom) - rcSelMargin.bottom = rc.bottom; - - Point ptOrigin = model.GetVisibleOriginInMain(); - FontAlias fontLineNumber = vs.styles[STYLE_LINENUMBER].font; - for (size_t margin = 0; margin < vs.ms.size(); margin++) { - if (vs.ms[margin].width > 0) { - - rcSelMargin.left = rcSelMargin.right; - rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width; - - if (vs.ms[margin].style != SC_MARGIN_NUMBER) { - if (vs.ms[margin].mask & SC_MASK_FOLDERS) { - // Required because of special way brush is created for selection margin - // Ensure patterns line up when scrolling with separate margin view - // by choosing correctly aligned variant. - bool invertPhase = static_cast(ptOrigin.y) & 1; - surface->FillRectangle(rcSelMargin, - invertPhase ? *pixmapSelPattern : *pixmapSelPatternOffset1); - } else { - ColourDesired colour; - switch (vs.ms[margin].style) { - case SC_MARGIN_BACK: - colour = vs.styles[STYLE_DEFAULT].back; - break; - case SC_MARGIN_FORE: - colour = vs.styles[STYLE_DEFAULT].fore; - break; - case SC_MARGIN_COLOUR: - colour = vs.ms[margin].back; - break; - default: - colour = vs.styles[STYLE_LINENUMBER].back; - break; - } - surface->FillRectangle(rcSelMargin, colour); - } - } else { - surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back); - } - - const int lineStartPaint = static_cast(rcMargin.top + ptOrigin.y) / vs.lineHeight; - int visibleLine = model.TopLineOfMain() + lineStartPaint; - int yposScreen = lineStartPaint * vs.lineHeight - static_cast(ptOrigin.y); - // Work out whether the top line is whitespace located after a - // lessening of fold level which implies a 'fold tail' but which should not - // be displayed until the last of a sequence of whitespace. - bool needWhiteClosure = false; - if (vs.ms[margin].mask & SC_MASK_FOLDERS) { - int level = model.pdoc->GetLevel(model.cs.DocFromDisplay(visibleLine)); - if (level & SC_FOLDLEVELWHITEFLAG) { - int lineBack = model.cs.DocFromDisplay(visibleLine); - int levelPrev = level; - while ((lineBack > 0) && (levelPrev & SC_FOLDLEVELWHITEFLAG)) { - lineBack--; - levelPrev = model.pdoc->GetLevel(lineBack); - } - if (!(levelPrev & SC_FOLDLEVELHEADERFLAG)) { - if (LevelNumber(level) < LevelNumber(levelPrev)) - needWhiteClosure = true; - } - } - if (highlightDelimiter.isEnabled) { - int lastLine = model.cs.DocFromDisplay(topLine + model.LinesOnScreen()) + 1; - model.pdoc->GetHighlightDelimiters(highlightDelimiter, model.pdoc->LineFromPosition(model.sel.MainCaret()), lastLine); - } - } - - // Old code does not know about new markers needed to distinguish all cases - const int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID, - SC_MARKNUM_FOLDEROPEN, vs); - const int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND, - SC_MARKNUM_FOLDER, vs); - - while ((visibleLine < model.cs.LinesDisplayed()) && yposScreen < rc.bottom) { - - PLATFORM_ASSERT(visibleLine < model.cs.LinesDisplayed()); - const int lineDoc = model.cs.DocFromDisplay(visibleLine); - PLATFORM_ASSERT(model.cs.GetVisible(lineDoc)); - const int firstVisibleLine = model.cs.DisplayFromDoc(lineDoc); - const int lastVisibleLine = model.cs.DisplayLastFromDoc(lineDoc); - const bool firstSubLine = visibleLine == firstVisibleLine; - const bool lastSubLine = visibleLine == lastVisibleLine; - - int marks = model.pdoc->GetMark(lineDoc); - if (!firstSubLine) - marks = 0; - - bool headWithTail = false; - - if (vs.ms[margin].mask & SC_MASK_FOLDERS) { - // Decide which fold indicator should be displayed - const int level = model.pdoc->GetLevel(lineDoc); - const int levelNext = model.pdoc->GetLevel(lineDoc + 1); - const int levelNum = LevelNumber(level); - const int levelNextNum = LevelNumber(levelNext); - if (level & SC_FOLDLEVELHEADERFLAG) { - if (firstSubLine) { - if (levelNum < levelNextNum) { - if (model.cs.GetExpanded(lineDoc)) { - if (levelNum == SC_FOLDLEVELBASE) - marks |= 1 << SC_MARKNUM_FOLDEROPEN; - else - marks |= 1 << folderOpenMid; - } else { - if (levelNum == SC_FOLDLEVELBASE) - marks |= 1 << SC_MARKNUM_FOLDER; - else - marks |= 1 << folderEnd; - } - } else if (levelNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } - } else { - if (levelNum < levelNextNum) { - if (model.cs.GetExpanded(lineDoc)) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } else if (levelNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } - } else if (levelNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } - } - needWhiteClosure = false; - const int firstFollowupLine = model.cs.DocFromDisplay(model.cs.DisplayFromDoc(lineDoc + 1)); - const int firstFollowupLineLevel = model.pdoc->GetLevel(firstFollowupLine); - const int secondFollowupLineLevelNum = LevelNumber(model.pdoc->GetLevel(firstFollowupLine + 1)); - if (!model.cs.GetExpanded(lineDoc)) { - if ((firstFollowupLineLevel & SC_FOLDLEVELWHITEFLAG) && - (levelNum > secondFollowupLineLevelNum)) - needWhiteClosure = true; - - if (highlightDelimiter.IsFoldBlockHighlighted(firstFollowupLine)) - headWithTail = true; - } - } else if (level & SC_FOLDLEVELWHITEFLAG) { - if (needWhiteClosure) { - if (levelNext & SC_FOLDLEVELWHITEFLAG) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } else if (levelNextNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; - needWhiteClosure = false; - } else { - marks |= 1 << SC_MARKNUM_FOLDERTAIL; - needWhiteClosure = false; - } - } else if (levelNum > SC_FOLDLEVELBASE) { - if (levelNextNum < levelNum) { - if (levelNextNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; - } else { - marks |= 1 << SC_MARKNUM_FOLDERTAIL; - } - } else { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } - } - } else if (levelNum > SC_FOLDLEVELBASE) { - if (levelNextNum < levelNum) { - needWhiteClosure = false; - if (levelNext & SC_FOLDLEVELWHITEFLAG) { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - needWhiteClosure = true; - } else if (lastSubLine) { - if (levelNextNum > SC_FOLDLEVELBASE) { - marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL; - } else { - marks |= 1 << SC_MARKNUM_FOLDERTAIL; - } - } else { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } - } else { - marks |= 1 << SC_MARKNUM_FOLDERSUB; - } - } - } - - marks &= vs.ms[margin].mask; - - PRectangle rcMarker = rcSelMargin; - rcMarker.top = static_cast(yposScreen); - rcMarker.bottom = static_cast(yposScreen + vs.lineHeight); - if (vs.ms[margin].style == SC_MARGIN_NUMBER) { - if (firstSubLine) { - char number[100] = ""; - if (lineDoc >= 0) - sprintf(number, "%d", lineDoc + 1); - if (model.foldFlags & (SC_FOLDFLAG_LEVELNUMBERS | SC_FOLDFLAG_LINESTATE)) { - if (model.foldFlags & SC_FOLDFLAG_LEVELNUMBERS) { - int lev = model.pdoc->GetLevel(lineDoc); - sprintf(number, "%c%c %03X %03X", - (lev & SC_FOLDLEVELHEADERFLAG) ? 'H' : '_', - (lev & SC_FOLDLEVELWHITEFLAG) ? 'W' : '_', - LevelNumber(lev), - lev >> 16 - ); - } else { - int state = model.pdoc->GetLineState(lineDoc); - sprintf(number, "%0X", state); - } - } - PRectangle rcNumber = rcMarker; - // Right justify - XYPOSITION width = surface->WidthText(fontLineNumber, number, static_cast(strlen(number))); - XYPOSITION xpos = rcNumber.right - width - vs.marginNumberPadding; - rcNumber.left = xpos; - DrawTextNoClipPhase(surface, rcNumber, vs.styles[STYLE_LINENUMBER], - rcNumber.top + vs.maxAscent, number, static_cast(strlen(number)), drawAll); - } else if (vs.wrapVisualFlags & SC_WRAPVISUALFLAG_MARGIN) { - PRectangle rcWrapMarker = rcMarker; - rcWrapMarker.right -= wrapMarkerPaddingRight; - rcWrapMarker.left = rcWrapMarker.right - vs.styles[STYLE_LINENUMBER].aveCharWidth; - if (customDrawWrapMarker == NULL) { - DrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); - } else { - customDrawWrapMarker(surface, rcWrapMarker, false, vs.styles[STYLE_LINENUMBER].fore); - } - } - } else if (vs.ms[margin].style == SC_MARGIN_TEXT || vs.ms[margin].style == SC_MARGIN_RTEXT) { - const StyledText stMargin = model.pdoc->MarginStyledText(lineDoc); - if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) { - if (firstSubLine) { - surface->FillRectangle(rcMarker, - vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back); - if (vs.ms[margin].style == SC_MARGIN_RTEXT) { - int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin); - rcMarker.left = rcMarker.right - width - 3; - } - DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, - stMargin, 0, stMargin.length, drawAll); - } else { - // if we're displaying annotation lines, color the margin to match the associated document line - const int annotationLines = model.pdoc->AnnotationLines(lineDoc); - if (annotationLines && (visibleLine > lastVisibleLine - annotationLines)) { - surface->FillRectangle(rcMarker, vs.styles[stMargin.StyleAt(0) + vs.marginStyleOffset].back); - } - } - } - } - - if (marks) { - for (int markBit = 0; (markBit < 32) && marks; markBit++) { - if (marks & 1) { - LineMarker::typeOfFold tFold = LineMarker::undefined; - if ((vs.ms[margin].mask & SC_MASK_FOLDERS) && highlightDelimiter.IsFoldBlockHighlighted(lineDoc)) { - if (highlightDelimiter.IsBodyOfFoldBlock(lineDoc)) { - tFold = LineMarker::body; - } else if (highlightDelimiter.IsHeadOfFoldBlock(lineDoc)) { - if (firstSubLine) { - tFold = headWithTail ? LineMarker::headWithTail : LineMarker::head; - } else { - if (model.cs.GetExpanded(lineDoc) || headWithTail) { - tFold = LineMarker::body; - } else { - tFold = LineMarker::undefined; - } - } - } else if (highlightDelimiter.IsTailOfFoldBlock(lineDoc)) { - tFold = LineMarker::tail; - } - } - vs.markers[markBit].Draw(surface, rcMarker, fontLineNumber, tFold, vs.ms[margin].style); - } - marks >>= 1; - } - } - - visibleLine++; - yposScreen += vs.lineHeight; - } - } - } - - PRectangle rcBlankMargin = rcMargin; - rcBlankMargin.left = rcSelMargin.right; - surface->FillRectangle(rcBlankMargin, vs.styles[STYLE_DEFAULT].back); -} - -#ifdef SCI_NAMESPACE -} -#endif - diff --git a/qrenderdoc/3rdparty/scintilla/src/MarginView.h b/qrenderdoc/3rdparty/scintilla/src/MarginView.h deleted file mode 100644 index ff5564676..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/MarginView.h +++ /dev/null @@ -1,50 +0,0 @@ -// Scintilla source code edit control -/** @file MarginView.h - ** Defines the appearance of the editor margin. - **/ -// Copyright 1998-2014 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef MARGINVIEW_H -#define MARGINVIEW_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -void DrawWrapMarker(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); - -typedef void (*DrawWrapMarkerFn)(Surface *surface, PRectangle rcPlace, bool isEndMarker, ColourDesired wrapColour); - -/** -* MarginView draws the margins. -*/ -class MarginView { -public: - Surface *pixmapSelMargin; - Surface *pixmapSelPattern; - Surface *pixmapSelPatternOffset1; - // Highlight current folding block - HighlightDelimiter highlightDelimiter; - - int wrapMarkerPaddingRight; // right-most pixel padding of wrap markers - /** Some platforms, notably PLAT_CURSES, do not support Scintilla's native - * DrawWrapMarker function for drawing wrap markers. Allow those platforms to - * override it instead of creating a new method in the Surface class that - * existing platforms must implement as empty. */ - DrawWrapMarkerFn customDrawWrapMarker; - - MarginView(); - - void DropGraphics(bool freeObjects); - void AllocateGraphics(const ViewStyle &vsDraw); - void RefreshPixMaps(Surface *surfaceWindow, WindowID wid, const ViewStyle &vsDraw); - void PaintMargin(Surface *surface, int topLine, PRectangle rc, PRectangle rcMargin, - const EditModel &model, const ViewStyle &vs); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Partitioning.h b/qrenderdoc/3rdparty/scintilla/src/Partitioning.h deleted file mode 100644 index 688b38d7d..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Partitioning.h +++ /dev/null @@ -1,198 +0,0 @@ -// Scintilla source code edit control -/** @file Partitioning.h - ** Data structure used to partition an interval. Used for holding line start/end positions. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef PARTITIONING_H -#define PARTITIONING_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/// A split vector of integers with a method for adding a value to all elements -/// in a range. -/// Used by the Partitioning class. - -class SplitVectorWithRangeAdd : public SplitVector { -public: - explicit SplitVectorWithRangeAdd(int growSize_) { - SetGrowSize(growSize_); - ReAllocate(growSize_); - } - ~SplitVectorWithRangeAdd() { - } - void RangeAddDelta(int start, int end, int delta) { - // end is 1 past end, so end-start is number of elements to change - int i = 0; - int rangeLength = end - start; - int range1Length = rangeLength; - int part1Left = part1Length - start; - if (range1Length > part1Left) - range1Length = part1Left; - while (i < range1Length) { - body[start++] += delta; - i++; - } - start += gapLength; - while (i < rangeLength) { - body[start++] += delta; - i++; - } - } -}; - -/// Divide an interval into multiple partitions. -/// Useful for breaking a document down into sections such as lines. -/// A 0 length interval has a single 0 length partition, numbered 0 -/// If interval not 0 length then each partition non-zero length -/// When needed, positions after the interval are considered part of the last partition -/// but the end of the last partition can be found with PositionFromPartition(last+1). - -class Partitioning { -private: - // To avoid calculating all the partition positions whenever any text is inserted - // there may be a step somewhere in the list. - int stepPartition; - int stepLength; - SplitVectorWithRangeAdd *body; - - // Move step forward - void ApplyStep(int partitionUpTo) { - if (stepLength != 0) { - body->RangeAddDelta(stepPartition+1, partitionUpTo + 1, stepLength); - } - stepPartition = partitionUpTo; - if (stepPartition >= body->Length()-1) { - stepPartition = body->Length()-1; - stepLength = 0; - } - } - - // Move step backward - void BackStep(int partitionDownTo) { - if (stepLength != 0) { - body->RangeAddDelta(partitionDownTo+1, stepPartition+1, -stepLength); - } - stepPartition = partitionDownTo; - } - - void Allocate(int growSize) { - body = new SplitVectorWithRangeAdd(growSize); - stepPartition = 0; - stepLength = 0; - body->Insert(0, 0); // This value stays 0 for ever - body->Insert(1, 0); // This is the end of the first partition and will be the start of the second - } - -public: - explicit Partitioning(int growSize) { - Allocate(growSize); - } - - ~Partitioning() { - delete body; - body = 0; - } - - int Partitions() const { - return body->Length()-1; - } - - void InsertPartition(int partition, int pos) { - if (stepPartition < partition) { - ApplyStep(partition); - } - body->Insert(partition, pos); - stepPartition++; - } - - void SetPartitionStartPosition(int partition, int pos) { - ApplyStep(partition+1); - if ((partition < 0) || (partition > body->Length())) { - return; - } - body->SetValueAt(partition, pos); - } - - void InsertText(int partitionInsert, int delta) { - // Point all the partitions after the insertion point further along in the buffer - if (stepLength != 0) { - if (partitionInsert >= stepPartition) { - // Fill in up to the new insertion point - ApplyStep(partitionInsert); - stepLength += delta; - } else if (partitionInsert >= (stepPartition - body->Length() / 10)) { - // Close to step but before so move step back - BackStep(partitionInsert); - stepLength += delta; - } else { - ApplyStep(body->Length()-1); - stepPartition = partitionInsert; - stepLength = delta; - } - } else { - stepPartition = partitionInsert; - stepLength = delta; - } - } - - void RemovePartition(int partition) { - if (partition > stepPartition) { - ApplyStep(partition); - stepPartition--; - } else { - stepPartition--; - } - body->Delete(partition); - } - - int PositionFromPartition(int partition) const { - PLATFORM_ASSERT(partition >= 0); - PLATFORM_ASSERT(partition < body->Length()); - if ((partition < 0) || (partition >= body->Length())) { - return 0; - } - int pos = body->ValueAt(partition); - if (partition > stepPartition) - pos += stepLength; - return pos; - } - - /// Return value in range [0 .. Partitions() - 1] even for arguments outside interval - int PartitionFromPosition(int pos) const { - if (body->Length() <= 1) - return 0; - if (pos >= (PositionFromPartition(body->Length()-1))) - return body->Length() - 1 - 1; - int lower = 0; - int upper = body->Length()-1; - do { - int middle = (upper + lower + 1) / 2; // Round high - int posMiddle = body->ValueAt(middle); - if (middle > stepPartition) - posMiddle += stepLength; - if (pos < posMiddle) { - upper = middle - 1; - } else { - lower = middle; - } - } while (lower < upper); - return lower; - } - - void DeleteAll() { - int growSize = body->GetGrowSize(); - delete body; - Allocate(growSize); - } -}; - - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/PerLine.cxx b/qrenderdoc/3rdparty/scintilla/src/PerLine.cxx deleted file mode 100644 index 6a3dd33dd..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/PerLine.cxx +++ /dev/null @@ -1,558 +0,0 @@ -// Scintilla source code edit control -/** @file PerLine.cxx - ** Manages data associated with each line of the document - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "CellBuffer.h" -#include "PerLine.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -MarkerHandleSet::MarkerHandleSet() { - root = 0; -} - -MarkerHandleSet::~MarkerHandleSet() { - MarkerHandleNumber *mhn = root; - while (mhn) { - MarkerHandleNumber *mhnToFree = mhn; - mhn = mhn->next; - delete mhnToFree; - } - root = 0; -} - -int MarkerHandleSet::Length() const { - int c = 0; - MarkerHandleNumber *mhn = root; - while (mhn) { - c++; - mhn = mhn->next; - } - return c; -} - -int MarkerHandleSet::MarkValue() const { - unsigned int m = 0; - MarkerHandleNumber *mhn = root; - while (mhn) { - m |= (1 << mhn->number); - mhn = mhn->next; - } - return m; -} - -bool MarkerHandleSet::Contains(int handle) const { - MarkerHandleNumber *mhn = root; - while (mhn) { - if (mhn->handle == handle) { - return true; - } - mhn = mhn->next; - } - return false; -} - -bool MarkerHandleSet::InsertHandle(int handle, int markerNum) { - MarkerHandleNumber *mhn = new MarkerHandleNumber; - mhn->handle = handle; - mhn->number = markerNum; - mhn->next = root; - root = mhn; - return true; -} - -void MarkerHandleSet::RemoveHandle(int handle) { - MarkerHandleNumber **pmhn = &root; - while (*pmhn) { - MarkerHandleNumber *mhn = *pmhn; - if (mhn->handle == handle) { - *pmhn = mhn->next; - delete mhn; - return; - } - pmhn = &((*pmhn)->next); - } -} - -bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) { - bool performedDeletion = false; - MarkerHandleNumber **pmhn = &root; - while (*pmhn) { - MarkerHandleNumber *mhn = *pmhn; - if (mhn->number == markerNum) { - *pmhn = mhn->next; - delete mhn; - performedDeletion = true; - if (!all) - break; - } else { - pmhn = &((*pmhn)->next); - } - } - return performedDeletion; -} - -void MarkerHandleSet::CombineWith(MarkerHandleSet *other) { - MarkerHandleNumber **pmhn = &other->root; - while (*pmhn) { - pmhn = &((*pmhn)->next); - } - *pmhn = root; - root = other->root; - other->root = 0; -} - -LineMarkers::~LineMarkers() { - Init(); -} - -void LineMarkers::Init() { - for (int line = 0; line < markers.Length(); line++) { - delete markers[line]; - markers[line] = 0; - } - markers.DeleteAll(); -} - -void LineMarkers::InsertLine(int line) { - if (markers.Length()) { - markers.Insert(line, 0); - } -} - -void LineMarkers::RemoveLine(int line) { - // Retain the markers from the deleted line by oring them into the previous line - if (markers.Length()) { - if (line > 0) { - MergeMarkers(line - 1); - } - markers.Delete(line); - } -} - -int LineMarkers::LineFromHandle(int markerHandle) { - if (markers.Length()) { - for (int line = 0; line < markers.Length(); line++) { - if (markers[line]) { - if (markers[line]->Contains(markerHandle)) { - return line; - } - } - } - } - return -1; -} - -void LineMarkers::MergeMarkers(int pos) { - if (markers[pos + 1] != NULL) { - if (markers[pos] == NULL) - markers[pos] = new MarkerHandleSet; - markers[pos]->CombineWith(markers[pos + 1]); - delete markers[pos + 1]; - markers[pos + 1] = NULL; - } -} - -int LineMarkers::MarkValue(int line) { - if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) - return markers[line]->MarkValue(); - else - return 0; -} - -int LineMarkers::MarkerNext(int lineStart, int mask) const { - if (lineStart < 0) - lineStart = 0; - int length = markers.Length(); - for (int iLine = lineStart; iLine < length; iLine++) { - MarkerHandleSet *onLine = markers[iLine]; - if (onLine && ((onLine->MarkValue() & mask) != 0)) - //if ((pdoc->GetMark(iLine) & lParam) != 0) - return iLine; - } - return -1; -} - -int LineMarkers::AddMark(int line, int markerNum, int lines) { - handleCurrent++; - if (!markers.Length()) { - // No existing markers so allocate one element per line - markers.InsertValue(0, lines, 0); - } - if (line >= markers.Length()) { - return -1; - } - if (!markers[line]) { - // Need new structure to hold marker handle - markers[line] = new MarkerHandleSet(); - } - markers[line]->InsertHandle(handleCurrent, markerNum); - - return handleCurrent; -} - -bool LineMarkers::DeleteMark(int line, int markerNum, bool all) { - bool someChanges = false; - if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) { - if (markerNum == -1) { - someChanges = true; - delete markers[line]; - markers[line] = NULL; - } else { - someChanges = markers[line]->RemoveNumber(markerNum, all); - if (markers[line]->Length() == 0) { - delete markers[line]; - markers[line] = NULL; - } - } - } - return someChanges; -} - -void LineMarkers::DeleteMarkFromHandle(int markerHandle) { - int line = LineFromHandle(markerHandle); - if (line >= 0) { - markers[line]->RemoveHandle(markerHandle); - if (markers[line]->Length() == 0) { - delete markers[line]; - markers[line] = NULL; - } - } -} - -LineLevels::~LineLevels() { -} - -void LineLevels::Init() { - levels.DeleteAll(); -} - -void LineLevels::InsertLine(int line) { - if (levels.Length()) { - int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE; - levels.InsertValue(line, 1, level); - } -} - -void LineLevels::RemoveLine(int line) { - if (levels.Length()) { - // Move up following lines but merge header flag from this line - // to line before to avoid a temporary disappearence causing expansion. - int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG; - levels.Delete(line); - if (line == levels.Length()-1) // Last line loses the header flag - levels[line-1] &= ~SC_FOLDLEVELHEADERFLAG; - else if (line > 0) - levels[line-1] |= firstHeader; - } -} - -void LineLevels::ExpandLevels(int sizeNew) { - levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE); -} - -void LineLevels::ClearLevels() { - levels.DeleteAll(); -} - -int LineLevels::SetLevel(int line, int level, int lines) { - int prev = 0; - if ((line >= 0) && (line < lines)) { - if (!levels.Length()) { - ExpandLevels(lines + 1); - } - prev = levels[line]; - if (prev != level) { - levels[line] = level; - } - } - return prev; -} - -int LineLevels::GetLevel(int line) const { - if (levels.Length() && (line >= 0) && (line < levels.Length())) { - return levels[line]; - } else { - return SC_FOLDLEVELBASE; - } -} - -LineState::~LineState() { -} - -void LineState::Init() { - lineStates.DeleteAll(); -} - -void LineState::InsertLine(int line) { - if (lineStates.Length()) { - lineStates.EnsureLength(line); - int val = (line < lineStates.Length()) ? lineStates[line] : 0; - lineStates.Insert(line, val); - } -} - -void LineState::RemoveLine(int line) { - if (lineStates.Length() > line) { - lineStates.Delete(line); - } -} - -int LineState::SetLineState(int line, int state) { - lineStates.EnsureLength(line + 1); - int stateOld = lineStates[line]; - lineStates[line] = state; - return stateOld; -} - -int LineState::GetLineState(int line) { - if (line < 0) - return 0; - lineStates.EnsureLength(line + 1); - return lineStates[line]; -} - -int LineState::GetMaxLineState() const { - return lineStates.Length(); -} - -static int NumberLines(const char *text) { - if (text) { - int newLines = 0; - while (*text) { - if (*text == '\n') - newLines++; - text++; - } - return newLines+1; - } else { - return 0; - } -} - -// Each allocated LineAnnotation is a char array which starts with an AnnotationHeader -// and then has text and optional styles. - -static const int IndividualStyles = 0x100; - -struct AnnotationHeader { - short style; // Style IndividualStyles implies array of styles - short lines; - int length; -}; - -LineAnnotation::~LineAnnotation() { - ClearAll(); -} - -void LineAnnotation::Init() { - ClearAll(); -} - -void LineAnnotation::InsertLine(int line) { - if (annotations.Length()) { - annotations.EnsureLength(line); - annotations.Insert(line, 0); - } -} - -void LineAnnotation::RemoveLine(int line) { - if (annotations.Length() && (line > 0) && (line <= annotations.Length())) { - delete []annotations[line-1]; - annotations.Delete(line-1); - } -} - -bool LineAnnotation::MultipleStyles(int line) const { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) - return reinterpret_cast(annotations[line])->style == IndividualStyles; - else - return 0; -} - -int LineAnnotation::Style(int line) const { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) - return reinterpret_cast(annotations[line])->style; - else - return 0; -} - -const char *LineAnnotation::Text(int line) const { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) - return annotations[line]+sizeof(AnnotationHeader); - else - return 0; -} - -const unsigned char *LineAnnotation::Styles(int line) const { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line] && MultipleStyles(line)) - return reinterpret_cast(annotations[line] + sizeof(AnnotationHeader) + Length(line)); - else - return 0; -} - -static char *AllocateAnnotation(int length, int style) { - size_t len = sizeof(AnnotationHeader) + length + ((style == IndividualStyles) ? length : 0); - char *ret = new char[len](); - return ret; -} - -void LineAnnotation::SetText(int line, const char *text) { - if (text && (line >= 0)) { - annotations.EnsureLength(line+1); - int style = Style(line); - if (annotations[line]) { - delete []annotations[line]; - } - annotations[line] = AllocateAnnotation(static_cast(strlen(text)), style); - AnnotationHeader *pah = reinterpret_cast(annotations[line]); - pah->style = static_cast(style); - pah->length = static_cast(strlen(text)); - pah->lines = static_cast(NumberLines(text)); - memcpy(annotations[line]+sizeof(AnnotationHeader), text, pah->length); - } else { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) { - delete []annotations[line]; - annotations[line] = 0; - } - } -} - -void LineAnnotation::ClearAll() { - for (int line = 0; line < annotations.Length(); line++) { - delete []annotations[line]; - annotations[line] = 0; - } - annotations.DeleteAll(); -} - -void LineAnnotation::SetStyle(int line, int style) { - annotations.EnsureLength(line+1); - if (!annotations[line]) { - annotations[line] = AllocateAnnotation(0, style); - } - reinterpret_cast(annotations[line])->style = static_cast(style); -} - -void LineAnnotation::SetStyles(int line, const unsigned char *styles) { - if (line >= 0) { - annotations.EnsureLength(line+1); - if (!annotations[line]) { - annotations[line] = AllocateAnnotation(0, IndividualStyles); - } else { - AnnotationHeader *pahSource = reinterpret_cast(annotations[line]); - if (pahSource->style != IndividualStyles) { - char *allocation = AllocateAnnotation(pahSource->length, IndividualStyles); - AnnotationHeader *pahAlloc = reinterpret_cast(allocation); - pahAlloc->length = pahSource->length; - pahAlloc->lines = pahSource->lines; - memcpy(allocation + sizeof(AnnotationHeader), annotations[line] + sizeof(AnnotationHeader), pahSource->length); - delete []annotations[line]; - annotations[line] = allocation; - } - } - AnnotationHeader *pah = reinterpret_cast(annotations[line]); - pah->style = IndividualStyles; - memcpy(annotations[line] + sizeof(AnnotationHeader) + pah->length, styles, pah->length); - } -} - -int LineAnnotation::Length(int line) const { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) - return reinterpret_cast(annotations[line])->length; - else - return 0; -} - -int LineAnnotation::Lines(int line) const { - if (annotations.Length() && (line >= 0) && (line < annotations.Length()) && annotations[line]) - return reinterpret_cast(annotations[line])->lines; - else - return 0; -} - -LineTabstops::~LineTabstops() { - Init(); -} - -void LineTabstops::Init() { - for (int line = 0; line < tabstops.Length(); line++) { - delete tabstops[line]; - } - tabstops.DeleteAll(); -} - -void LineTabstops::InsertLine(int line) { - if (tabstops.Length()) { - tabstops.EnsureLength(line); - tabstops.Insert(line, 0); - } -} - -void LineTabstops::RemoveLine(int line) { - if (tabstops.Length() > line) { - delete tabstops[line]; - tabstops.Delete(line); - } -} - -bool LineTabstops::ClearTabstops(int line) { - if (line < tabstops.Length()) { - TabstopList *tl = tabstops[line]; - if (tl) { - tl->clear(); - return true; - } - } - return false; -} - -bool LineTabstops::AddTabstop(int line, int x) { - tabstops.EnsureLength(line + 1); - if (!tabstops[line]) { - tabstops[line] = new TabstopList(); - } - - TabstopList *tl = tabstops[line]; - if (tl) { - // tabstop positions are kept in order - insert in the right place - std::vector::iterator it = std::lower_bound(tl->begin(), tl->end(), x); - // don't insert duplicates - if (it == tl->end() || *it != x) { - tl->insert(it, x); - return true; - } - } - return false; -} - -int LineTabstops::GetNextTabstop(int line, int x) const { - if (line < tabstops.Length()) { - TabstopList *tl = tabstops[line]; - if (tl) { - for (size_t i = 0; i < tl->size(); i++) { - if ((*tl)[i] > x) { - return (*tl)[i]; - } - } - } - } - return 0; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/PerLine.h b/qrenderdoc/3rdparty/scintilla/src/PerLine.h deleted file mode 100644 index 4bf1c88fd..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/PerLine.h +++ /dev/null @@ -1,136 +0,0 @@ -// Scintilla source code edit control -/** @file PerLine.h - ** Manages data associated with each line of the document - **/ -// Copyright 1998-2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef PERLINE_H -#define PERLINE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - * This holds the marker identifier and the marker type to display. - * MarkerHandleNumbers are members of lists. - */ -struct MarkerHandleNumber { - int handle; - int number; - MarkerHandleNumber *next; -}; - -/** - * A marker handle set contains any number of MarkerHandleNumbers. - */ -class MarkerHandleSet { - MarkerHandleNumber *root; - -public: - MarkerHandleSet(); - ~MarkerHandleSet(); - int Length() const; - int MarkValue() const; ///< Bit set of marker numbers. - bool Contains(int handle) const; - bool InsertHandle(int handle, int markerNum); - void RemoveHandle(int handle); - bool RemoveNumber(int markerNum, bool all); - void CombineWith(MarkerHandleSet *other); -}; - -class LineMarkers : public PerLine { - SplitVector markers; - /// Handles are allocated sequentially and should never have to be reused as 32 bit ints are very big. - int handleCurrent; -public: - LineMarkers() : handleCurrent(0) { - } - virtual ~LineMarkers(); - virtual void Init(); - virtual void InsertLine(int line); - virtual void RemoveLine(int line); - - int MarkValue(int line); - int MarkerNext(int lineStart, int mask) const; - int AddMark(int line, int marker, int lines); - void MergeMarkers(int pos); - bool DeleteMark(int line, int markerNum, bool all); - void DeleteMarkFromHandle(int markerHandle); - int LineFromHandle(int markerHandle); -}; - -class LineLevels : public PerLine { - SplitVector levels; -public: - virtual ~LineLevels(); - virtual void Init(); - virtual void InsertLine(int line); - virtual void RemoveLine(int line); - - void ExpandLevels(int sizeNew=-1); - void ClearLevels(); - int SetLevel(int line, int level, int lines); - int GetLevel(int line) const; -}; - -class LineState : public PerLine { - SplitVector lineStates; -public: - LineState() { - } - virtual ~LineState(); - virtual void Init(); - virtual void InsertLine(int line); - virtual void RemoveLine(int line); - - int SetLineState(int line, int state); - int GetLineState(int line); - int GetMaxLineState() const; -}; - -class LineAnnotation : public PerLine { - SplitVector annotations; -public: - LineAnnotation() { - } - virtual ~LineAnnotation(); - virtual void Init(); - virtual void InsertLine(int line); - virtual void RemoveLine(int line); - - bool MultipleStyles(int line) const; - int Style(int line) const; - const char *Text(int line) const; - const unsigned char *Styles(int line) const; - void SetText(int line, const char *text); - void ClearAll(); - void SetStyle(int line, int style); - void SetStyles(int line, const unsigned char *styles); - int Length(int line) const; - int Lines(int line) const; -}; - -typedef std::vector TabstopList; - -class LineTabstops : public PerLine { - SplitVector tabstops; -public: - LineTabstops() { - } - virtual ~LineTabstops(); - virtual void Init(); - virtual void InsertLine(int line); - virtual void RemoveLine(int line); - - bool ClearTabstops(int line); - bool AddTabstop(int line, int x); - int GetNextTabstop(int line, int x) const; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Position.h b/qrenderdoc/3rdparty/scintilla/src/Position.h deleted file mode 100644 index 120b92f62..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Position.h +++ /dev/null @@ -1,29 +0,0 @@ -// Scintilla source code edit control -/** @file Position.h - ** Defines global type name Position in the Sci internal namespace. - **/ -// Copyright 2015 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef POSITION_H -#define POSITION_H - -/** - * A Position is a position within a document between two characters or at the beginning or end. - * Sometimes used as a character index where it identifies the character after the position. - */ - -namespace Sci { - -typedef int Position; - -// A later version (4.x) of this file may: -//#if defined(SCI_LARGE_FILE_SUPPORT) -//typedef std::ptrdiff_t Position; -// or may allow runtime choice between different position sizes. - -const Position invalidPosition = -1; - -} - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/PositionCache.cxx b/qrenderdoc/3rdparty/scintilla/src/PositionCache.cxx deleted file mode 100644 index 45731601a..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/PositionCache.cxx +++ /dev/null @@ -1,710 +0,0 @@ -// Scintilla source code edit control -/** @file PositionCache.cxx - ** Classes for caching layout information. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "UniConversion.h" -#include "Selection.h" -#include "PositionCache.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -LineLayout::LineLayout(int maxLineLength_) : - lineStarts(0), - lenLineStarts(0), - lineNumber(-1), - inCache(false), - maxLineLength(-1), - numCharsInLine(0), - numCharsBeforeEOL(0), - validity(llInvalid), - xHighlightGuide(0), - highlightColumn(0), - containsCaret(false), - edgeColumn(0), - chars(0), - styles(0), - positions(0), - hotspot(0,0), - widthLine(wrapWidthInfinite), - lines(1), - wrapIndent(0) { - bracePreviousStyles[0] = 0; - bracePreviousStyles[1] = 0; - Resize(maxLineLength_); -} - -LineLayout::~LineLayout() { - Free(); -} - -void LineLayout::Resize(int maxLineLength_) { - if (maxLineLength_ > maxLineLength) { - Free(); - chars = new char[maxLineLength_ + 1]; - styles = new unsigned char[maxLineLength_ + 1]; - // Extra position allocated as sometimes the Windows - // GetTextExtentExPoint API writes an extra element. - positions = new XYPOSITION[maxLineLength_ + 1 + 1]; - maxLineLength = maxLineLength_; - } -} - -void LineLayout::Free() { - delete []chars; - chars = 0; - delete []styles; - styles = 0; - delete []positions; - positions = 0; - delete []lineStarts; - lineStarts = 0; -} - -void LineLayout::Invalidate(validLevel validity_) { - if (validity > validity_) - validity = validity_; -} - -int LineLayout::LineStart(int line) const { - if (line <= 0) { - return 0; - } else if ((line >= lines) || !lineStarts) { - return numCharsInLine; - } else { - return lineStarts[line]; - } -} - -int LineLayout::LineLastVisible(int line) const { - if (line < 0) { - return 0; - } else if ((line >= lines-1) || !lineStarts) { - return numCharsBeforeEOL; - } else { - return lineStarts[line+1]; - } -} - -Range LineLayout::SubLineRange(int subLine) const { - return Range(LineStart(subLine), LineLastVisible(subLine)); -} - -bool LineLayout::InLine(int offset, int line) const { - return ((offset >= LineStart(line)) && (offset < LineStart(line + 1))) || - ((offset == numCharsInLine) && (line == (lines-1))); -} - -void LineLayout::SetLineStart(int line, int start) { - if ((line >= lenLineStarts) && (line != 0)) { - int newMaxLines = line + 20; - int *newLineStarts = new int[newMaxLines]; - for (int i = 0; i < newMaxLines; i++) { - if (i < lenLineStarts) - newLineStarts[i] = lineStarts[i]; - else - newLineStarts[i] = 0; - } - delete []lineStarts; - lineStarts = newLineStarts; - lenLineStarts = newMaxLines; - } - lineStarts[line] = start; -} - -void LineLayout::SetBracesHighlight(Range rangeLine, const Position braces[], - char bracesMatchStyle, int xHighlight, bool ignoreStyle) { - if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) { - int braceOffset = braces[0] - rangeLine.start; - if (braceOffset < numCharsInLine) { - bracePreviousStyles[0] = styles[braceOffset]; - styles[braceOffset] = bracesMatchStyle; - } - } - if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) { - int braceOffset = braces[1] - rangeLine.start; - if (braceOffset < numCharsInLine) { - bracePreviousStyles[1] = styles[braceOffset]; - styles[braceOffset] = bracesMatchStyle; - } - } - if ((braces[0] >= rangeLine.start && braces[1] <= rangeLine.end) || - (braces[1] >= rangeLine.start && braces[0] <= rangeLine.end)) { - xHighlightGuide = xHighlight; - } -} - -void LineLayout::RestoreBracesHighlight(Range rangeLine, const Position braces[], bool ignoreStyle) { - if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) { - int braceOffset = braces[0] - rangeLine.start; - if (braceOffset < numCharsInLine) { - styles[braceOffset] = bracePreviousStyles[0]; - } - } - if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) { - int braceOffset = braces[1] - rangeLine.start; - if (braceOffset < numCharsInLine) { - styles[braceOffset] = bracePreviousStyles[1]; - } - } - xHighlightGuide = 0; -} - -int LineLayout::FindBefore(XYPOSITION x, int lower, int upper) const { - do { - int middle = (upper + lower + 1) / 2; // Round high - XYPOSITION posMiddle = positions[middle]; - if (x < posMiddle) { - upper = middle - 1; - } else { - lower = middle; - } - } while (lower < upper); - return lower; -} - - -int LineLayout::FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const { - int pos = FindBefore(x, range.start, range.end); - while (pos < range.end) { - if (charPosition) { - if (x < (positions[pos + 1])) { - return pos; - } - } else { - if (x < ((positions[pos] + positions[pos + 1]) / 2)) { - return pos; - } - } - pos++; - } - return range.end; -} - -Point LineLayout::PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const { - Point pt; - // In case of very long line put x at arbitrary large position - if (posInLine > maxLineLength) { - pt.x = positions[maxLineLength] - positions[LineStart(lines)]; - } - - for (int subLine = 0; subLine < lines; subLine++) { - const Range rangeSubLine = SubLineRange(subLine); - if (posInLine >= rangeSubLine.start) { - pt.y = static_cast(subLine*lineHeight); - if (posInLine <= rangeSubLine.end) { - pt.x = positions[posInLine] - positions[rangeSubLine.start]; - if (rangeSubLine.start != 0) // Wrapped lines may be indented - pt.x += wrapIndent; - if (pe & peSubLineEnd) // Return end of first subline not start of next - break; - } else if ((pe & peLineEnd) && (subLine == (lines-1))) { - pt.x = positions[numCharsInLine] - positions[rangeSubLine.start]; - if (rangeSubLine.start != 0) // Wrapped lines may be indented - pt.x += wrapIndent; - } - } else { - break; - } - } - return pt; -} - -int LineLayout::EndLineStyle() const { - return styles[numCharsBeforeEOL > 0 ? numCharsBeforeEOL-1 : 0]; -} - -LineLayoutCache::LineLayoutCache() : - level(0), - allInvalidated(false), styleClock(-1), useCount(0) { - Allocate(0); -} - -LineLayoutCache::~LineLayoutCache() { - Deallocate(); -} - -void LineLayoutCache::Allocate(size_t length_) { - PLATFORM_ASSERT(cache.empty()); - allInvalidated = false; - cache.resize(length_); -} - -void LineLayoutCache::AllocateForLevel(int linesOnScreen, int linesInDoc) { - PLATFORM_ASSERT(useCount == 0); - size_t lengthForLevel = 0; - if (level == llcCaret) { - lengthForLevel = 1; - } else if (level == llcPage) { - lengthForLevel = linesOnScreen + 1; - } else if (level == llcDocument) { - lengthForLevel = linesInDoc; - } - if (lengthForLevel > cache.size()) { - Deallocate(); - Allocate(lengthForLevel); - } else { - if (lengthForLevel < cache.size()) { - for (size_t i = lengthForLevel; i < cache.size(); i++) { - delete cache[i]; - cache[i] = 0; - } - } - cache.resize(lengthForLevel); - } - PLATFORM_ASSERT(cache.size() == lengthForLevel); -} - -void LineLayoutCache::Deallocate() { - PLATFORM_ASSERT(useCount == 0); - for (size_t i = 0; i < cache.size(); i++) - delete cache[i]; - cache.clear(); -} - -void LineLayoutCache::Invalidate(LineLayout::validLevel validity_) { - if (!cache.empty() && !allInvalidated) { - for (size_t i = 0; i < cache.size(); i++) { - if (cache[i]) { - cache[i]->Invalidate(validity_); - } - } - if (validity_ == LineLayout::llInvalid) { - allInvalidated = true; - } - } -} - -void LineLayoutCache::SetLevel(int level_) { - allInvalidated = false; - if ((level_ != -1) && (level != level_)) { - level = level_; - Deallocate(); - } -} - -LineLayout *LineLayoutCache::Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, - int linesOnScreen, int linesInDoc) { - AllocateForLevel(linesOnScreen, linesInDoc); - if (styleClock != styleClock_) { - Invalidate(LineLayout::llCheckTextAndStyle); - styleClock = styleClock_; - } - allInvalidated = false; - int pos = -1; - LineLayout *ret = 0; - if (level == llcCaret) { - pos = 0; - } else if (level == llcPage) { - if (lineNumber == lineCaret) { - pos = 0; - } else if (cache.size() > 1) { - pos = 1 + (lineNumber % (cache.size() - 1)); - } - } else if (level == llcDocument) { - pos = lineNumber; - } - if (pos >= 0) { - PLATFORM_ASSERT(useCount == 0); - if (!cache.empty() && (pos < static_cast(cache.size()))) { - if (cache[pos]) { - if ((cache[pos]->lineNumber != lineNumber) || - (cache[pos]->maxLineLength < maxChars)) { - delete cache[pos]; - cache[pos] = 0; - } - } - if (!cache[pos]) { - cache[pos] = new LineLayout(maxChars); - } - cache[pos]->lineNumber = lineNumber; - cache[pos]->inCache = true; - ret = cache[pos]; - useCount++; - } - } - - if (!ret) { - ret = new LineLayout(maxChars); - ret->lineNumber = lineNumber; - } - - return ret; -} - -void LineLayoutCache::Dispose(LineLayout *ll) { - allInvalidated = false; - if (ll) { - if (!ll->inCache) { - delete ll; - } else { - useCount--; - } - } -} - -// Simply pack the (maximum 4) character bytes into an int -static inline int KeyFromString(const char *charBytes, size_t len) { - PLATFORM_ASSERT(len <= 4); - int k=0; - for (size_t i=0; i(charBytes[i]); - } - return k; -} - -SpecialRepresentations::SpecialRepresentations() { - std::fill(startByteHasReprs, startByteHasReprs+0x100, 0); -} - -void SpecialRepresentations::SetRepresentation(const char *charBytes, const char *value) { - MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, UTF8MaxBytes)); - if (it == mapReprs.end()) { - // New entry so increment for first byte - startByteHasReprs[static_cast(charBytes[0])]++; - } - mapReprs[KeyFromString(charBytes, UTF8MaxBytes)] = Representation(value); -} - -void SpecialRepresentations::ClearRepresentation(const char *charBytes) { - MapRepresentation::iterator it = mapReprs.find(KeyFromString(charBytes, UTF8MaxBytes)); - if (it != mapReprs.end()) { - mapReprs.erase(it); - startByteHasReprs[static_cast(charBytes[0])]--; - } -} - -const Representation *SpecialRepresentations::RepresentationFromCharacter(const char *charBytes, size_t len) const { - PLATFORM_ASSERT(len <= 4); - if (!startByteHasReprs[static_cast(charBytes[0])]) - return 0; - MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len)); - if (it != mapReprs.end()) { - return &(it->second); - } - return 0; -} - -bool SpecialRepresentations::Contains(const char *charBytes, size_t len) const { - PLATFORM_ASSERT(len <= 4); - if (!startByteHasReprs[static_cast(charBytes[0])]) - return false; - MapRepresentation::const_iterator it = mapReprs.find(KeyFromString(charBytes, len)); - return it != mapReprs.end(); -} - -void SpecialRepresentations::Clear() { - mapReprs.clear(); - std::fill(startByteHasReprs, startByteHasReprs+0x100, 0); -} - -void BreakFinder::Insert(int val) { - if (val > nextBreak) { - const std::vector::iterator it = std::lower_bound(selAndEdge.begin(), selAndEdge.end(), val); - if (it == selAndEdge.end()) { - selAndEdge.push_back(val); - } else if (*it != val) { - selAndEdge.insert(it, 1, val); - } - } -} - -BreakFinder::BreakFinder(const LineLayout *ll_, const Selection *psel, Range lineRange_, int posLineStart_, - int xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw) : - ll(ll_), - lineRange(lineRange_), - posLineStart(posLineStart_), - nextBreak(lineRange_.start), - saeCurrentPos(0), - saeNext(0), - subBreak(-1), - pdoc(pdoc_), - encodingFamily(pdoc_->CodePageFamily()), - preprs(preprs_) { - - // Search for first visible break - // First find the first visible character - if (xStart > 0.0f) - nextBreak = ll->FindBefore(static_cast(xStart), lineRange.start, lineRange.end); - // Now back to a style break - while ((nextBreak > lineRange.start) && (ll->styles[nextBreak] == ll->styles[nextBreak - 1])) { - nextBreak--; - } - - if (breakForSelection) { - SelectionPosition posStart(posLineStart); - SelectionPosition posEnd(posLineStart + lineRange.end); - SelectionSegment segmentLine(posStart, posEnd); - for (size_t r=0; rCount(); r++) { - SelectionSegment portion = psel->Range(r).Intersect(segmentLine); - if (!(portion.start == portion.end)) { - if (portion.start.IsValid()) - Insert(portion.start.Position() - posLineStart); - if (portion.end.IsValid()) - Insert(portion.end.Position() - posLineStart); - } - } - } - if (pvsDraw && pvsDraw->indicatorsSetFore > 0) { - for (Decoration *deco = pdoc->decorations.root; deco; deco = deco->next) { - if (pvsDraw->indicators[deco->indicator].OverridesTextFore()) { - int startPos = deco->rs.EndRun(posLineStart); - while (startPos < (posLineStart + lineRange.end)) { - Insert(startPos - posLineStart); - startPos = deco->rs.EndRun(startPos); - } - } - } - } - Insert(ll->edgeColumn); - Insert(lineRange.end); - saeNext = (!selAndEdge.empty()) ? selAndEdge[0] : -1; -} - -BreakFinder::~BreakFinder() { -} - -TextSegment BreakFinder::Next() { - if (subBreak == -1) { - int prev = nextBreak; - while (nextBreak < lineRange.end) { - int charWidth = 1; - if (encodingFamily == efUnicode) - charWidth = UTF8DrawBytes(reinterpret_cast(ll->chars) + nextBreak, lineRange.end - nextBreak); - else if (encodingFamily == efDBCS) - charWidth = pdoc->IsDBCSLeadByte(ll->chars[nextBreak]) ? 2 : 1; - const Representation *repr = preprs->RepresentationFromCharacter(ll->chars + nextBreak, charWidth); - if (((nextBreak > 0) && (ll->styles[nextBreak] != ll->styles[nextBreak - 1])) || - repr || - (nextBreak == saeNext)) { - while ((nextBreak >= saeNext) && (saeNext < lineRange.end)) { - saeCurrentPos++; - saeNext = (saeCurrentPos < selAndEdge.size()) ? selAndEdge[saeCurrentPos] : lineRange.end; - } - if ((nextBreak > prev) || repr) { - // Have a segment to report - if (nextBreak == prev) { - nextBreak += charWidth; - } else { - repr = 0; // Optimize -> should remember repr - } - if ((nextBreak - prev) < lengthStartSubdivision) { - return TextSegment(prev, nextBreak - prev, repr); - } else { - break; - } - } - } - nextBreak += charWidth; - } - if ((nextBreak - prev) < lengthStartSubdivision) { - return TextSegment(prev, nextBreak - prev); - } - subBreak = prev; - } - // Splitting up a long run from prev to nextBreak in lots of approximately lengthEachSubdivision. - // For very long runs add extra breaks after spaces or if no spaces before low punctuation. - int startSegment = subBreak; - if ((nextBreak - subBreak) <= lengthEachSubdivision) { - subBreak = -1; - return TextSegment(startSegment, nextBreak - startSegment); - } else { - subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision); - if (subBreak >= nextBreak) { - subBreak = -1; - return TextSegment(startSegment, nextBreak - startSegment); - } else { - return TextSegment(startSegment, subBreak - startSegment); - } - } -} - -bool BreakFinder::More() const { - return (subBreak >= 0) || (nextBreak < lineRange.end); -} - -PositionCacheEntry::PositionCacheEntry() : - styleNumber(0), len(0), clock(0), positions(0) { -} - -void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_, - unsigned int len_, XYPOSITION *positions_, unsigned int clock_) { - Clear(); - styleNumber = styleNumber_; - len = len_; - clock = clock_; - if (s_ && positions_) { - positions = new XYPOSITION[len + (len / 4) + 1]; - for (unsigned int i=0; i(reinterpret_cast(positions + len)), s_, len); - } -} - -PositionCacheEntry::~PositionCacheEntry() { - Clear(); -} - -void PositionCacheEntry::Clear() { - delete []positions; - positions = 0; - styleNumber = 0; - len = 0; - clock = 0; -} - -bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_, - unsigned int len_, XYPOSITION *positions_) const { - if ((styleNumber == styleNumber_) && (len == len_) && - (memcmp(reinterpret_cast(reinterpret_cast(positions + len)), s_, len)== 0)) { - for (unsigned int i=0; i other.clock; -} - -void PositionCacheEntry::ResetClock() { - if (clock > 0) { - clock = 1; - } -} - -PositionCache::PositionCache() { - clock = 1; - pces.resize(0x400); - allClear = true; -} - -PositionCache::~PositionCache() { - Clear(); -} - -void PositionCache::Clear() { - if (!allClear) { - for (size_t i=0; i BreakFinder::lengthStartSubdivision) { - // Break up into segments - unsigned int startSegment = 0; - XYPOSITION xStartSegment = 0; - while (startSegment < len) { - unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision); - FontAlias fontStyle = vstyle.styles[styleNumber].font; - surface->MeasureWidths(fontStyle, s + startSegment, lenSegment, positions + startSegment); - for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) { - positions[startSegment + inSeg] += xStartSegment; - } - xStartSegment = positions[startSegment + lenSegment - 1]; - startSegment += lenSegment; - } - } else { - FontAlias fontStyle = vstyle.styles[styleNumber].font; - surface->MeasureWidths(fontStyle, s, len, positions); - } - if (probe < pces.size()) { - // Store into cache - clock++; - if (clock > 60000) { - // Since there are only 16 bits for the clock, wrap it round and - // reset all cache entries so none get stuck with a high clock. - for (size_t i=0; i -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef POSITIONCACHE_H -#define POSITIONCACHE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -static inline bool IsEOLChar(char ch) { - return (ch == '\r') || (ch == '\n'); -} - -/** -* A point in document space. -* Uses double for sufficient resolution in large (>20,000,000 line) documents. -*/ -class PointDocument { -public: - double x; - double y; - - explicit PointDocument(double x_ = 0, double y_ = 0) : x(x_), y(y_) { - } - - // Conversion from Point. - explicit PointDocument(Point pt) : x(pt.x), y(pt.y) { - } -}; - -// There are two points for some positions and this enumeration -// can choose between the end of the first line or subline -// and the start of the next line or subline. -enum PointEnd { - peDefault = 0x0, - peLineEnd = 0x1, - peSubLineEnd = 0x2 -}; - -/** - */ -class LineLayout { -private: - friend class LineLayoutCache; - int *lineStarts; - int lenLineStarts; - /// Drawing is only performed for @a maxLineLength characters on each line. - int lineNumber; - bool inCache; -public: - enum { wrapWidthInfinite = 0x7ffffff }; - - int maxLineLength; - int numCharsInLine; - int numCharsBeforeEOL; - enum validLevel { llInvalid, llCheckTextAndStyle, llPositions, llLines } validity; - int xHighlightGuide; - bool highlightColumn; - bool containsCaret; - int edgeColumn; - char *chars; - unsigned char *styles; - XYPOSITION *positions; - char bracePreviousStyles[2]; - - // Hotspot support - Range hotspot; - - // Wrapped line support - int widthLine; - int lines; - XYPOSITION wrapIndent; // In pixels - - explicit LineLayout(int maxLineLength_); - virtual ~LineLayout(); - void Resize(int maxLineLength_); - void Free(); - void Invalidate(validLevel validity_); - int LineStart(int line) const; - int LineLastVisible(int line) const; - Range SubLineRange(int line) const; - bool InLine(int offset, int line) const; - void SetLineStart(int line, int start); - void SetBracesHighlight(Range rangeLine, const Position braces[], - char bracesMatchStyle, int xHighlight, bool ignoreStyle); - void RestoreBracesHighlight(Range rangeLine, const Position braces[], bool ignoreStyle); - int FindBefore(XYPOSITION x, int lower, int upper) const; - int FindPositionFromX(XYPOSITION x, Range range, bool charPosition) const; - Point PointFromPosition(int posInLine, int lineHeight, PointEnd pe) const; - int EndLineStyle() const; -}; - -/** - */ -class LineLayoutCache { - int level; - std::vectorcache; - bool allInvalidated; - int styleClock; - int useCount; - void Allocate(size_t length_); - void AllocateForLevel(int linesOnScreen, int linesInDoc); -public: - LineLayoutCache(); - virtual ~LineLayoutCache(); - void Deallocate(); - enum { - llcNone=SC_CACHE_NONE, - llcCaret=SC_CACHE_CARET, - llcPage=SC_CACHE_PAGE, - llcDocument=SC_CACHE_DOCUMENT - }; - void Invalidate(LineLayout::validLevel validity_); - void SetLevel(int level_); - int GetLevel() const { return level; } - LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_, - int linesOnScreen, int linesInDoc); - void Dispose(LineLayout *ll); -}; - -class PositionCacheEntry { - unsigned int styleNumber:8; - unsigned int len:8; - unsigned int clock:16; - XYPOSITION *positions; -public: - PositionCacheEntry(); - ~PositionCacheEntry(); - void Set(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_, unsigned int clock_); - void Clear(); - bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, XYPOSITION *positions_) const; - static unsigned int Hash(unsigned int styleNumber_, const char *s, unsigned int len); - bool NewerThan(const PositionCacheEntry &other) const; - void ResetClock(); -}; - -class Representation { -public: - std::string stringRep; - explicit Representation(const char *value="") : stringRep(value) { - } -}; - -typedef std::map MapRepresentation; - -class SpecialRepresentations { - MapRepresentation mapReprs; - short startByteHasReprs[0x100]; -public: - SpecialRepresentations(); - void SetRepresentation(const char *charBytes, const char *value); - void ClearRepresentation(const char *charBytes); - const Representation *RepresentationFromCharacter(const char *charBytes, size_t len) const; - bool Contains(const char *charBytes, size_t len) const; - void Clear(); -}; - -struct TextSegment { - int start; - int length; - const Representation *representation; - TextSegment(int start_=0, int length_=0, const Representation *representation_=0) : - start(start_), length(length_), representation(representation_) { - } - int end() const { - return start + length; - } -}; - -// Class to break a line of text into shorter runs at sensible places. -class BreakFinder { - const LineLayout *ll; - Range lineRange; - int posLineStart; - int nextBreak; - std::vector selAndEdge; - unsigned int saeCurrentPos; - int saeNext; - int subBreak; - const Document *pdoc; - EncodingFamily encodingFamily; - const SpecialRepresentations *preprs; - void Insert(int val); - // Private so BreakFinder objects can not be copied - BreakFinder(const BreakFinder &); -public: - // If a whole run is longer than lengthStartSubdivision then subdivide - // into smaller runs at spaces or punctuation. - enum { lengthStartSubdivision = 300 }; - // Try to make each subdivided run lengthEachSubdivision or shorter. - enum { lengthEachSubdivision = 100 }; - BreakFinder(const LineLayout *ll_, const Selection *psel, Range rangeLine_, int posLineStart_, - int xStart, bool breakForSelection, const Document *pdoc_, const SpecialRepresentations *preprs_, const ViewStyle *pvsDraw); - ~BreakFinder(); - TextSegment Next(); - bool More() const; -}; - -class PositionCache { - std::vector pces; - unsigned int clock; - bool allClear; - // Private so PositionCache objects can not be copied - PositionCache(const PositionCache &); -public: - PositionCache(); - ~PositionCache(); - void Clear(); - void SetSize(size_t size_); - size_t GetSize() const { return pces.size(); } - void MeasureWidths(Surface *surface, const ViewStyle &vstyle, unsigned int styleNumber, - const char *s, unsigned int len, XYPOSITION *positions, Document *pdoc); -}; - -inline bool IsSpaceOrTab(int ch) { - return ch == ' ' || ch == '\t'; -} - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/RESearch.cxx b/qrenderdoc/3rdparty/scintilla/src/RESearch.cxx deleted file mode 100644 index 4e290309c..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/RESearch.cxx +++ /dev/null @@ -1,962 +0,0 @@ -// Scintilla source code edit control -/** @file RESearch.cxx - ** Regular expression search library. - **/ - -/* - * regex - Regular expression pattern matching and replacement - * - * By: Ozan S. Yigit (oz) - * Dept. of Computer Science - * York University - * - * Original code available from http://www.cs.yorku.ca/~oz/ - * Translation to C++ by Neil Hodgson neilh@scintilla.org - * Removed all use of register. - * Converted to modern function prototypes. - * Put all global/static variables into an object so this code can be - * used from multiple threads, etc. - * Some extensions by Philippe Lhoste PhiLho(a)GMX.net - * '?' extensions by Michael Mullin masmullin@gmail.com - * - * These routines are the PUBLIC DOMAIN equivalents of regex - * routines as found in 4.nBSD UN*X, with minor extensions. - * - * These routines are derived from various implementations found - * in software tools books, and Conroy's grep. They are NOT derived - * from licensed/restricted software. - * For more interesting/academic/complicated implementations, - * see Henry Spencer's regexp routines, or GNU Emacs pattern - * matching module. - * - * Modification history removed. - * - * Interfaces: - * RESearch::Compile: compile a regular expression into a NFA. - * - * const char *RESearch::Compile(const char *pattern, int length, - * bool caseSensitive, bool posix) - * - * Returns a short error string if they fail. - * - * RESearch::Execute: execute the NFA to match a pattern. - * - * int RESearch::Execute(characterIndexer &ci, int lp, int endp) - * - * re_fail: failure routine for RESearch::Execute. (no longer used) - * - * void re_fail(char *msg, char op) - * - * Regular Expressions: - * - * [1] char matches itself, unless it is a special - * character (metachar): . \ [ ] * + ? ^ $ - * and ( ) if posix option. - * - * [2] . matches any character. - * - * [3] \ matches the character following it, except: - * - \a, \b, \f, \n, \r, \t, \v match the corresponding C - * escape char, respectively BEL, BS, FF, LF, CR, TAB and VT; - * Note that \r and \n are never matched because Scintilla - * regex searches are made line per line - * (stripped of end-of-line chars). - * - if not in posix mode, when followed by a - * left or right round bracket (see [8]); - * - when followed by a digit 1 to 9 (see [9]); - * - when followed by a left or right angle bracket - * (see [10]); - * - when followed by d, D, s, S, w or W (see [11]); - * - when followed by x and two hexa digits (see [12]. - * Backslash is used as an escape character for all - * other meta-characters, and itself. - * - * [4] [set] matches one of the characters in the set. - * If the first character in the set is "^", - * it matches the characters NOT in the set, i.e. - * complements the set. A shorthand S-E (start dash end) - * is used to specify a set of characters S up to - * E, inclusive. S and E must be characters, otherwise - * the dash is taken literally (eg. in expression [\d-a]). - * The special characters "]" and "-" have no special - * meaning if they appear as the first chars in the set. - * To include both, put - first: [-]A-Z] - * (or just backslash them). - * examples: match: - * - * [-]|] matches these 3 chars, - * - * []-|] matches from ] to | chars - * - * [a-z] any lowercase alpha - * - * [^-]] any char except - and ] - * - * [^A-Z] any char except uppercase - * alpha - * - * [a-zA-Z] any alpha - * - * [5] * any regular expression form [1] to [4] - * (except [8], [9] and [10] forms of [3]), - * followed by closure char (*) - * matches zero or more matches of that form. - * - * [6] + same as [5], except it matches one or more. - * - * [5-6] Both [5] and [6] are greedy (they match as much as possible). - * Unless they are followed by the 'lazy' quantifier (?) - * In which case both [5] and [6] try to match as little as possible - * - * [7] ? same as [5] except it matches zero or one. - * - * [8] a regular expression in the form [1] to [13], enclosed - * as \(form\) (or (form) with posix flag) matches what - * form matches. The enclosure creates a set of tags, - * used for [9] and for pattern substitution. - * The tagged forms are numbered starting from 1. - * - * [9] a \ followed by a digit 1 to 9 matches whatever a - * previously tagged regular expression ([8]) matched. - * - * [10] \< a regular expression starting with a \< construct - * \> and/or ending with a \> construct, restricts the - * pattern matching to the beginning of a word, and/or - * the end of a word. A word is defined to be a character - * string beginning and/or ending with the characters - * A-Z a-z 0-9 and _. Scintilla extends this definition - * by user setting. The word must also be preceded and/or - * followed by any character outside those mentioned. - * - * [11] \l a backslash followed by d, D, s, S, w or W, - * becomes a character class (both inside and - * outside sets []). - * d: decimal digits - * D: any char except decimal digits - * s: whitespace (space, \t \n \r \f \v) - * S: any char except whitespace (see above) - * w: alphanumeric & underscore (changed by user setting) - * W: any char except alphanumeric & underscore (see above) - * - * [12] \xHH a backslash followed by x and two hexa digits, - * becomes the character whose Ascii code is equal - * to these digits. If not followed by two digits, - * it is 'x' char itself. - * - * [13] a composite regular expression xy where x and y - * are in the form [1] to [12] matches the longest - * match of x followed by a match for y. - * - * [14] ^ a regular expression starting with a ^ character - * $ and/or ending with a $ character, restricts the - * pattern matching to the beginning of the line, - * or the end of line. [anchors] Elsewhere in the - * pattern, ^ and $ are treated as ordinary characters. - * - * - * Acknowledgements: - * - * HCR's Hugh Redelmeier has been most helpful in various - * stages of development. He convinced me to include BOW - * and EOW constructs, originally invented by Rob Pike at - * the University of Toronto. - * - * References: - * Software tools Kernighan & Plauger - * Software tools in Pascal Kernighan & Plauger - * Grep [rsx-11 C dist] David Conroy - * ed - text editor Un*x Programmer's Manual - * Advanced editing on Un*x B. W. Kernighan - * RegExp routines Henry Spencer - * - * Notes: - * - * This implementation uses a bit-set representation for character - * classes for speed and compactness. Each character is represented - * by one bit in a 256-bit block. Thus, CCL always takes a - * constant 32 bytes in the internal nfa, and RESearch::Execute does a single - * bit comparison to locate the character in the set. - * - * Examples: - * - * pattern: foo*.* - * compile: CHR f CHR o CLO CHR o END CLO ANY END END - * matches: fo foo fooo foobar fobar foxx ... - * - * pattern: fo[ob]a[rz] - * compile: CHR f CHR o CCL bitset CHR a CCL bitset END - * matches: fobar fooar fobaz fooaz - * - * pattern: foo\\+ - * compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END - * matches: foo\ foo\\ foo\\\ ... - * - * pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo) - * compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END - * matches: foo1foo foo2foo foo3foo - * - * pattern: \(fo.*\)-\1 - * compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END - * matches: foo-foo fo-fo fob-fob foobar-foobar ... - */ - -#include - -#include -#include -#include - -#include "Position.h" -#include "CharClassify.h" -#include "RESearch.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -#define OKP 1 -#define NOP 0 - -#define CHR 1 -#define ANY 2 -#define CCL 3 -#define BOL 4 -#define EOL 5 -#define BOT 6 -#define EOT 7 -#define BOW 8 -#define EOW 9 -#define REF 10 -#define CLO 11 -#define CLQ 12 /* 0 to 1 closure */ -#define LCLO 13 /* lazy closure */ - -#define END 0 - -/* - * The following defines are not meant to be changeable. - * They are for readability only. - */ -#define BLKIND 0370 -#define BITIND 07 - -const char bitarr[] = { 1, 2, 4, 8, 16, 32, 64, '\200' }; - -#define badpat(x) (*nfa = END, x) - -/* - * Character classification table for word boundary operators BOW - * and EOW is passed in by the creator of this object (Scintilla - * Document). The Document default state is that word chars are: - * 0-9, a-z, A-Z and _ - */ - -RESearch::RESearch(CharClassify *charClassTable) { - failure = 0; - charClass = charClassTable; - sta = NOP; /* status of lastpat */ - bol = 0; - std::fill(bittab, bittab + BITBLK, 0); - std::fill(tagstk, tagstk + MAXTAG, 0); - std::fill(nfa, nfa + MAXNFA, 0); - Clear(); -} - -RESearch::~RESearch() { - Clear(); -} - -void RESearch::Clear() { - for (int i = 0; i < MAXTAG; i++) { - pat[i].clear(); - bopat[i] = NOTFOUND; - eopat[i] = NOTFOUND; - } -} - -void RESearch::GrabMatches(CharacterIndexer &ci) { - for (unsigned int i = 0; i < MAXTAG; i++) { - if ((bopat[i] != NOTFOUND) && (eopat[i] != NOTFOUND)) { - unsigned int len = eopat[i] - bopat[i]; - pat[i].resize(len); - for (unsigned int j = 0; j < len; j++) - pat[i][j] = ci.CharAt(bopat[i] + j); - } - } -} - -void RESearch::ChSet(unsigned char c) { - bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND]; -} - -void RESearch::ChSetWithCase(unsigned char c, bool caseSensitive) { - if (caseSensitive) { - ChSet(c); - } else { - if ((c >= 'a') && (c <= 'z')) { - ChSet(c); - ChSet(static_cast(c - 'a' + 'A')); - } else if ((c >= 'A') && (c <= 'Z')) { - ChSet(c); - ChSet(static_cast(c - 'A' + 'a')); - } else { - ChSet(c); - } - } -} - -static unsigned char escapeValue(unsigned char ch) { - switch (ch) { - case 'a': return '\a'; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - } - return 0; -} - -static int GetHexaChar(unsigned char hd1, unsigned char hd2) { - int hexValue = 0; - if (hd1 >= '0' && hd1 <= '9') { - hexValue += 16 * (hd1 - '0'); - } else if (hd1 >= 'A' && hd1 <= 'F') { - hexValue += 16 * (hd1 - 'A' + 10); - } else if (hd1 >= 'a' && hd1 <= 'f') { - hexValue += 16 * (hd1 - 'a' + 10); - } else { - return -1; - } - if (hd2 >= '0' && hd2 <= '9') { - hexValue += hd2 - '0'; - } else if (hd2 >= 'A' && hd2 <= 'F') { - hexValue += hd2 - 'A' + 10; - } else if (hd2 >= 'a' && hd2 <= 'f') { - hexValue += hd2 - 'a' + 10; - } else { - return -1; - } - return hexValue; -} - -/** - * Called when the parser finds a backslash not followed - * by a valid expression (like \( in non-Posix mode). - * @param pattern : pointer on the char after the backslash. - * @param incr : (out) number of chars to skip after expression evaluation. - * @return the char if it resolves to a simple char, - * or -1 for a char class. In this case, bittab is changed. - */ -int RESearch::GetBackslashExpression( - const char *pattern, - int &incr) { - // Since error reporting is primitive and messages are not used anyway, - // I choose to interpret unexpected syntax in a logical way instead - // of reporting errors. Otherwise, we can stick on, eg., PCRE behavior. - incr = 0; // Most of the time, will skip the char "naturally". - int c; - int result = -1; - unsigned char bsc = *pattern; - if (!bsc) { - // Avoid overrun - result = '\\'; // \ at end of pattern, take it literally - return result; - } - - switch (bsc) { - case 'a': - case 'b': - case 'n': - case 'f': - case 'r': - case 't': - case 'v': - result = escapeValue(bsc); - break; - case 'x': { - unsigned char hd1 = *(pattern + 1); - unsigned char hd2 = *(pattern + 2); - int hexValue = GetHexaChar(hd1, hd2); - if (hexValue >= 0) { - result = hexValue; - incr = 2; // Must skip the digits - } else { - result = 'x'; // \x without 2 digits: see it as 'x' - } - } - break; - case 'd': - for (c = '0'; c <= '9'; c++) { - ChSet(static_cast(c)); - } - break; - case 'D': - for (c = 0; c < MAXCHR; c++) { - if (c < '0' || c > '9') { - ChSet(static_cast(c)); - } - } - break; - case 's': - ChSet(' '); - ChSet('\t'); - ChSet('\n'); - ChSet('\r'); - ChSet('\f'); - ChSet('\v'); - break; - case 'S': - for (c = 0; c < MAXCHR; c++) { - if (c != ' ' && !(c >= 0x09 && c <= 0x0D)) { - ChSet(static_cast(c)); - } - } - break; - case 'w': - for (c = 0; c < MAXCHR; c++) { - if (iswordc(static_cast(c))) { - ChSet(static_cast(c)); - } - } - break; - case 'W': - for (c = 0; c < MAXCHR; c++) { - if (!iswordc(static_cast(c))) { - ChSet(static_cast(c)); - } - } - break; - default: - result = bsc; - } - return result; -} - -const char *RESearch::Compile(const char *pattern, int length, bool caseSensitive, bool posix) { - char *mp=nfa; /* nfa pointer */ - char *lp; /* saved pointer */ - char *sp=nfa; /* another one */ - char *mpMax = mp + MAXNFA - BITBLK - 10; - - int tagi = 0; /* tag stack index */ - int tagc = 1; /* actual tag count */ - - int n; - char mask; /* xor mask -CCL/NCL */ - int c1, c2, prevChar; - - if (!pattern || !length) { - if (sta) - return 0; - else - return badpat("No previous regular expression"); - } - sta = NOP; - - const char *p=pattern; /* pattern pointer */ - for (int i=0; i mpMax) - return badpat("Pattern too long"); - lp = mp; - switch (*p) { - - case '.': /* match any char */ - *mp++ = ANY; - break; - - case '^': /* match beginning */ - if (p == pattern) { - *mp++ = BOL; - } else { - *mp++ = CHR; - *mp++ = *p; - } - break; - - case '$': /* match endofline */ - if (!*(p+1)) { - *mp++ = EOL; - } else { - *mp++ = CHR; - *mp++ = *p; - } - break; - - case '[': /* match char class */ - *mp++ = CCL; - prevChar = 0; - - i++; - if (*++p == '^') { - mask = '\377'; - i++; - p++; - } else { - mask = 0; - } - - if (*p == '-') { /* real dash */ - i++; - prevChar = *p; - ChSet(*p++); - } - if (*p == ']') { /* real brace */ - i++; - prevChar = *p; - ChSet(*p++); - } - while (*p && *p != ']') { - if (*p == '-') { - if (prevChar < 0) { - // Previous def. was a char class like \d, take dash literally - prevChar = *p; - ChSet(*p); - } else if (*(p+1)) { - if (*(p+1) != ']') { - c1 = prevChar + 1; - i++; - c2 = static_cast(*++p); - if (c2 == '\\') { - if (!*(p+1)) { // End of RE - return badpat("Missing ]"); - } else { - i++; - p++; - int incr; - c2 = GetBackslashExpression(p, incr); - i += incr; - p += incr; - if (c2 >= 0) { - // Convention: \c (c is any char) is case sensitive, whatever the option - ChSet(static_cast(c2)); - prevChar = c2; - } else { - // bittab is already changed - prevChar = -1; - } - } - } - if (prevChar < 0) { - // Char after dash is char class like \d, take dash literally - prevChar = '-'; - ChSet('-'); - } else { - // Put all chars between c1 and c2 included in the char set - while (c1 <= c2) { - ChSetWithCase(static_cast(c1++), caseSensitive); - } - } - } else { - // Dash before the ], take it literally - prevChar = *p; - ChSet(*p); - } - } else { - return badpat("Missing ]"); - } - } else if (*p == '\\' && *(p+1)) { - i++; - p++; - int incr; - int c = GetBackslashExpression(p, incr); - i += incr; - p += incr; - if (c >= 0) { - // Convention: \c (c is any char) is case sensitive, whatever the option - ChSet(static_cast(c)); - prevChar = c; - } else { - // bittab is already changed - prevChar = -1; - } - } else { - prevChar = static_cast(*p); - ChSetWithCase(*p, caseSensitive); - } - i++; - p++; - } - if (!*p) - return badpat("Missing ]"); - - for (n = 0; n < BITBLK; bittab[n++] = 0) - *mp++ = static_cast(mask ^ bittab[n]); - - break; - - case '*': /* match 0 or more... */ - case '+': /* match 1 or more... */ - case '?': - if (p == pattern) - return badpat("Empty closure"); - lp = sp; /* previous opcode */ - if (*lp == CLO || *lp == LCLO) /* equivalence... */ - break; - switch (*lp) { - - case BOL: - case BOT: - case EOT: - case BOW: - case EOW: - case REF: - return badpat("Illegal closure"); - default: - break; - } - - if (*p == '+') - for (sp = mp; lp < sp; lp++) - *mp++ = *lp; - - *mp++ = END; - *mp++ = END; - sp = mp; - - while (--mp > lp) - *mp = mp[-1]; - if (*p == '?') *mp = CLQ; - else if (*(p+1) == '?') *mp = LCLO; - else *mp = CLO; - - mp = sp; - break; - - case '\\': /* tags, backrefs... */ - i++; - switch (*++p) { - case '<': - *mp++ = BOW; - break; - case '>': - if (*sp == BOW) - return badpat("Null pattern inside \\<\\>"); - *mp++ = EOW; - break; - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - n = *p-'0'; - if (tagi > 0 && tagstk[tagi] == n) - return badpat("Cyclical reference"); - if (tagc > n) { - *mp++ = static_cast(REF); - *mp++ = static_cast(n); - } else { - return badpat("Undetermined reference"); - } - break; - default: - if (!posix && *p == '(') { - if (tagc < MAXTAG) { - tagstk[++tagi] = tagc; - *mp++ = BOT; - *mp++ = static_cast(tagc++); - } else { - return badpat("Too many \\(\\) pairs"); - } - } else if (!posix && *p == ')') { - if (*sp == BOT) - return badpat("Null pattern inside \\(\\)"); - if (tagi > 0) { - *mp++ = static_cast(EOT); - *mp++ = static_cast(tagstk[tagi--]); - } else { - return badpat("Unmatched \\)"); - } - } else { - int incr; - int c = GetBackslashExpression(p, incr); - i += incr; - p += incr; - if (c >= 0) { - *mp++ = CHR; - *mp++ = static_cast(c); - } else { - *mp++ = CCL; - mask = 0; - for (n = 0; n < BITBLK; bittab[n++] = 0) - *mp++ = static_cast(mask ^ bittab[n]); - } - } - } - break; - - default : /* an ordinary char */ - if (posix && *p == '(') { - if (tagc < MAXTAG) { - tagstk[++tagi] = tagc; - *mp++ = BOT; - *mp++ = static_cast(tagc++); - } else { - return badpat("Too many () pairs"); - } - } else if (posix && *p == ')') { - if (*sp == BOT) - return badpat("Null pattern inside ()"); - if (tagi > 0) { - *mp++ = static_cast(EOT); - *mp++ = static_cast(tagstk[tagi--]); - } else { - return badpat("Unmatched )"); - } - } else { - unsigned char c = *p; - if (!c) // End of RE - c = '\\'; // We take it as raw backslash - if (caseSensitive || !iswordc(c)) { - *mp++ = CHR; - *mp++ = c; - } else { - *mp++ = CCL; - mask = 0; - ChSetWithCase(c, false); - for (n = 0; n < BITBLK; bittab[n++] = 0) - *mp++ = static_cast(mask ^ bittab[n]); - } - } - break; - } - sp = lp; - } - if (tagi > 0) - return badpat((posix ? "Unmatched (" : "Unmatched \\(")); - *mp = END; - sta = OKP; - return 0; -} - -/* - * RESearch::Execute: - * execute nfa to find a match. - * - * special cases: (nfa[0]) - * BOL - * Match only once, starting from the - * beginning. - * CHR - * First locate the character without - * calling PMatch, and if found, call - * PMatch for the remaining string. - * END - * RESearch::Compile failed, poor luser did not - * check for it. Fail fast. - * - * If a match is found, bopat[0] and eopat[0] are set - * to the beginning and the end of the matched fragment, - * respectively. - * - */ -int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) { - unsigned char c; - int ep = NOTFOUND; - char *ap = nfa; - - bol = lp; - failure = 0; - - Clear(); - - switch (*ap) { - - case BOL: /* anchored: match from BOL only */ - ep = PMatch(ci, lp, endp, ap); - break; - case EOL: /* just searching for end of line normal path doesn't work */ - if (*(ap+1) == END) { - lp = endp; - ep = lp; - break; - } else { - return 0; - } - case CHR: /* ordinary char: locate it fast */ - c = *(ap+1); - while ((lp < endp) && (static_cast(ci.CharAt(lp)) != c)) - lp++; - if (lp >= endp) /* if EOS, fail, else fall through. */ - return 0; - default: /* regular matching all the way. */ - while (lp < endp) { - ep = PMatch(ci, lp, endp, ap); - if (ep != NOTFOUND) - break; - lp++; - } - break; - case END: /* munged automaton. fail always */ - return 0; - } - if (ep == NOTFOUND) - return 0; - - bopat[0] = lp; - eopat[0] = ep; - return 1; -} - -/* - * PMatch: internal routine for the hard part - * - * This code is partly snarfed from an early grep written by - * David Conroy. The backref and tag stuff, and various other - * innovations are by oz. - * - * special case optimizations: (nfa[n], nfa[n+1]) - * CLO ANY - * We KNOW .* will match everything up to the - * end of line. Thus, directly go to the end of - * line, without recursive PMatch calls. As in - * the other closure cases, the remaining pattern - * must be matched by moving backwards on the - * string recursively, to find a match for xy - * (x is ".*" and y is the remaining pattern) - * where the match satisfies the LONGEST match for - * x followed by a match for y. - * CLO CHR - * We can again scan the string forward for the - * single char and at the point of failure, we - * execute the remaining nfa recursively, same as - * above. - * - * At the end of a successful match, bopat[n] and eopat[n] - * are set to the beginning and end of subpatterns matched - * by tagged expressions (n = 1 to 9). - */ - -extern void re_fail(char *,char); - -#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND]) - -/* - * skip values for CLO XXX to skip past the closure - */ - -#define ANYSKIP 2 /* [CLO] ANY END */ -#define CHRSKIP 3 /* [CLO] CHR chr END */ -#define CCLSKIP 34 /* [CLO] CCL 32 bytes END */ - -int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) { - int op, c, n; - int e; /* extra pointer for CLO */ - int bp; /* beginning of subpat... */ - int ep; /* ending of subpat... */ - int are; /* to save the line ptr. */ - int llp; /* lazy lp for LCLO */ - - while ((op = *ap++) != END) - switch (op) { - - case CHR: - if (ci.CharAt(lp++) != *ap++) - return NOTFOUND; - break; - case ANY: - if (lp++ >= endp) - return NOTFOUND; - break; - case CCL: - if (lp >= endp) - return NOTFOUND; - c = ci.CharAt(lp++); - if (!isinset(ap,c)) - return NOTFOUND; - ap += BITBLK; - break; - case BOL: - if (lp != bol) - return NOTFOUND; - break; - case EOL: - if (lp < endp) - return NOTFOUND; - break; - case BOT: - bopat[static_cast(*ap++)] = lp; - break; - case EOT: - eopat[static_cast(*ap++)] = lp; - break; - case BOW: - if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp))) - return NOTFOUND; - break; - case EOW: - if (lp==bol || !iswordc(ci.CharAt(lp-1)) || iswordc(ci.CharAt(lp))) - return NOTFOUND; - break; - case REF: - n = *ap++; - bp = bopat[n]; - ep = eopat[n]; - while (bp < ep) - if (ci.CharAt(bp++) != ci.CharAt(lp++)) - return NOTFOUND; - break; - case LCLO: - case CLQ: - case CLO: - are = lp; - switch (*ap) { - - case ANY: - if (op == CLO || op == LCLO) - while (lp < endp) - lp++; - else if (lp < endp) - lp++; - - n = ANYSKIP; - break; - case CHR: - c = *(ap+1); - if (op == CLO || op == LCLO) - while ((lp < endp) && (c == ci.CharAt(lp))) - lp++; - else if ((lp < endp) && (c == ci.CharAt(lp))) - lp++; - n = CHRSKIP; - break; - case CCL: - while ((lp < endp) && isinset(ap+1,ci.CharAt(lp))) - lp++; - n = CCLSKIP; - break; - default: - failure = true; - //re_fail("closure: bad nfa.", *ap); - return NOTFOUND; - } - ap += n; - - llp = lp; - e = NOTFOUND; - while (llp >= are) { - int q; - if ((q = PMatch(ci, llp, endp, ap)) != NOTFOUND) { - e = q; - lp = llp; - if (op != LCLO) return e; - } - if (*ap == END) return e; - --llp; - } - if (*ap == EOT) - PMatch(ci, lp, endp, ap); - return e; - default: - //re_fail("RESearch::Execute: bad nfa.", static_cast(op)); - return NOTFOUND; - } - return lp; -} - - diff --git a/qrenderdoc/3rdparty/scintilla/src/RESearch.h b/qrenderdoc/3rdparty/scintilla/src/RESearch.h deleted file mode 100644 index 23795babe..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/RESearch.h +++ /dev/null @@ -1,73 +0,0 @@ -// Scintilla source code edit control -/** @file RESearch.h - ** Interface to the regular expression search library. - **/ -// Written by Neil Hodgson -// Based on the work of Ozan S. Yigit. -// This file is in the public domain. - -#ifndef RESEARCH_H -#define RESEARCH_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/* - * The following defines are not meant to be changeable. - * They are for readability only. - */ -#define MAXCHR 256 -#define CHRBIT 8 -#define BITBLK MAXCHR/CHRBIT - -class CharacterIndexer { -public: - virtual char CharAt(int index)=0; - virtual ~CharacterIndexer() { - } -}; - -class RESearch { - -public: - explicit RESearch(CharClassify *charClassTable); - ~RESearch(); - void Clear(); - void GrabMatches(CharacterIndexer &ci); - const char *Compile(const char *pattern, int length, bool caseSensitive, bool posix); - int Execute(CharacterIndexer &ci, int lp, int endp); - - enum { MAXTAG=10 }; - enum { MAXNFA=4096 }; - enum { NOTFOUND=-1 }; - - int bopat[MAXTAG]; - int eopat[MAXTAG]; - std::string pat[MAXTAG]; - -private: - void ChSet(unsigned char c); - void ChSetWithCase(unsigned char c, bool caseSensitive); - int GetBackslashExpression(const char *pattern, int &incr); - - int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap); - - int bol; - int tagstk[MAXTAG]; /* subpat tag stack */ - char nfa[MAXNFA]; /* automaton */ - int sta; - unsigned char bittab[BITBLK]; /* bit table for CCL pre-set bits */ - int failure; - CharClassify *charClass; - bool iswordc(unsigned char x) const { - return charClass->IsWord(x); - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif - diff --git a/qrenderdoc/3rdparty/scintilla/src/RunStyles.cxx b/qrenderdoc/3rdparty/scintilla/src/RunStyles.cxx deleted file mode 100644 index a136f022a..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/RunStyles.cxx +++ /dev/null @@ -1,289 +0,0 @@ -/** @file RunStyles.cxx - ** Data structure used to store sparse styles. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include - -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -// Find the first run at a position -int RunStyles::RunFromPosition(int position) const { - int run = starts->PartitionFromPosition(position); - // Go to first element with this position - while ((run > 0) && (position == starts->PositionFromPartition(run-1))) { - run--; - } - return run; -} - -// If there is no run boundary at position, insert one continuing style. -int RunStyles::SplitRun(int position) { - int run = RunFromPosition(position); - int posRun = starts->PositionFromPartition(run); - if (posRun < position) { - int runStyle = ValueAt(position); - run++; - starts->InsertPartition(run, position); - styles->InsertValue(run, 1, runStyle); - } - return run; -} - -void RunStyles::RemoveRun(int run) { - starts->RemovePartition(run); - styles->DeleteRange(run, 1); -} - -void RunStyles::RemoveRunIfEmpty(int run) { - if ((run < starts->Partitions()) && (starts->Partitions() > 1)) { - if (starts->PositionFromPartition(run) == starts->PositionFromPartition(run+1)) { - RemoveRun(run); - } - } -} - -void RunStyles::RemoveRunIfSameAsPrevious(int run) { - if ((run > 0) && (run < starts->Partitions())) { - if (styles->ValueAt(run-1) == styles->ValueAt(run)) { - RemoveRun(run); - } - } -} - -RunStyles::RunStyles() { - starts = new Partitioning(8); - styles = new SplitVector(); - styles->InsertValue(0, 2, 0); -} - -RunStyles::~RunStyles() { - delete starts; - starts = NULL; - delete styles; - styles = NULL; -} - -int RunStyles::Length() const { - return starts->PositionFromPartition(starts->Partitions()); -} - -int RunStyles::ValueAt(int position) const { - return styles->ValueAt(starts->PartitionFromPosition(position)); -} - -int RunStyles::FindNextChange(int position, int end) const { - int run = starts->PartitionFromPosition(position); - if (run < starts->Partitions()) { - int runChange = starts->PositionFromPartition(run); - if (runChange > position) - return runChange; - int nextChange = starts->PositionFromPartition(run + 1); - if (nextChange > position) { - return nextChange; - } else if (position < end) { - return end; - } else { - return end + 1; - } - } else { - return end + 1; - } -} - -int RunStyles::StartRun(int position) const { - return starts->PositionFromPartition(starts->PartitionFromPosition(position)); -} - -int RunStyles::EndRun(int position) const { - return starts->PositionFromPartition(starts->PartitionFromPosition(position) + 1); -} - -bool RunStyles::FillRange(int &position, int value, int &fillLength) { - if (fillLength <= 0) { - return false; - } - int end = position + fillLength; - if (end > Length()) { - return false; - } - int runEnd = RunFromPosition(end); - if (styles->ValueAt(runEnd) == value) { - // End already has value so trim range. - end = starts->PositionFromPartition(runEnd); - if (position >= end) { - // Whole range is already same as value so no action - return false; - } - fillLength = end - position; - } else { - runEnd = SplitRun(end); - } - int runStart = RunFromPosition(position); - if (styles->ValueAt(runStart) == value) { - // Start is in expected value so trim range. - runStart++; - position = starts->PositionFromPartition(runStart); - fillLength = end - position; - } else { - if (starts->PositionFromPartition(runStart) < position) { - runStart = SplitRun(position); - runEnd++; - } - } - if (runStart < runEnd) { - styles->SetValueAt(runStart, value); - // Remove each old run over the range - for (int run=runStart+1; runPositionFromPartition(runStart) == position) { - int runStyle = ValueAt(position); - // Inserting at start of run so make previous longer - if (runStart == 0) { - // Inserting at start of document so ensure 0 - if (runStyle) { - styles->SetValueAt(0, 0); - starts->InsertPartition(1, 0); - styles->InsertValue(1, 1, runStyle); - starts->InsertText(0, insertLength); - } else { - starts->InsertText(runStart, insertLength); - } - } else { - if (runStyle) { - starts->InsertText(runStart-1, insertLength); - } else { - // Insert at end of run so do not extend style - starts->InsertText(runStart, insertLength); - } - } - } else { - starts->InsertText(runStart, insertLength); - } -} - -void RunStyles::DeleteAll() { - delete starts; - starts = NULL; - delete styles; - styles = NULL; - starts = new Partitioning(8); - styles = new SplitVector(); - styles->InsertValue(0, 2, 0); -} - -void RunStyles::DeleteRange(int position, int deleteLength) { - int end = position + deleteLength; - int runStart = RunFromPosition(position); - int runEnd = RunFromPosition(end); - if (runStart == runEnd) { - // Deleting from inside one run - starts->InsertText(runStart, -deleteLength); - RemoveRunIfEmpty(runStart); - } else { - runStart = SplitRun(position); - runEnd = SplitRun(end); - starts->InsertText(runStart, -deleteLength); - // Remove each old run over the range - for (int run=runStart; runPartitions(); -} - -bool RunStyles::AllSame() const { - for (int run = 1; run < starts->Partitions(); run++) { - if (styles->ValueAt(run) != styles->ValueAt(run - 1)) - return false; - } - return true; -} - -bool RunStyles::AllSameAs(int value) const { - return AllSame() && (styles->ValueAt(0) == value); -} - -int RunStyles::Find(int value, int start) const { - if (start < Length()) { - int run = start ? RunFromPosition(start) : 0; - if (styles->ValueAt(run) == value) - return start; - run++; - while (run < starts->Partitions()) { - if (styles->ValueAt(run) == value) - return starts->PositionFromPartition(run); - run++; - } - } - return -1; -} - -void RunStyles::Check() const { - if (Length() < 0) { - throw std::runtime_error("RunStyles: Length can not be negative."); - } - if (starts->Partitions() < 1) { - throw std::runtime_error("RunStyles: Must always have 1 or more partitions."); - } - if (starts->Partitions() != styles->Length()-1) { - throw std::runtime_error("RunStyles: Partitions and styles different lengths."); - } - int start=0; - while (start < Length()) { - int end = EndRun(start); - if (start >= end) { - throw std::runtime_error("RunStyles: Partition is 0 length."); - } - start = end; - } - if (styles->ValueAt(styles->Length()-1) != 0) { - throw std::runtime_error("RunStyles: Unused style at end changed."); - } - for (int j=1; jLength()-1; j++) { - if (styles->ValueAt(j) == styles->ValueAt(j-1)) { - throw std::runtime_error("RunStyles: Style of a partition same as previous."); - } - } -} diff --git a/qrenderdoc/3rdparty/scintilla/src/RunStyles.h b/qrenderdoc/3rdparty/scintilla/src/RunStyles.h deleted file mode 100644 index b096ad800..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/RunStyles.h +++ /dev/null @@ -1,54 +0,0 @@ -/** @file RunStyles.h - ** Data structure used to store sparse styles. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -/// Styling buffer using one element for each run rather than using -/// a filled buffer. - -#ifndef RUNSTYLES_H -#define RUNSTYLES_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class RunStyles { -private: - Partitioning *starts; - SplitVector *styles; - int RunFromPosition(int position) const; - int SplitRun(int position); - void RemoveRun(int run); - void RemoveRunIfEmpty(int run); - void RemoveRunIfSameAsPrevious(int run); - // Private so RunStyles objects can not be copied - RunStyles(const RunStyles &); -public: - RunStyles(); - ~RunStyles(); - int Length() const; - int ValueAt(int position) const; - int FindNextChange(int position, int end) const; - int StartRun(int position) const; - int EndRun(int position) const; - // Returns true if some values may have changed - bool FillRange(int &position, int value, int &fillLength); - void SetValueAt(int position, int value); - void InsertSpace(int position, int insertLength); - void DeleteAll(); - void DeleteRange(int position, int deleteLength); - int Runs() const; - bool AllSame() const; - bool AllSameAs(int value) const; - int Find(int value, int start) const; - - void Check() const; -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/ScintillaBase.cxx b/qrenderdoc/3rdparty/scintilla/src/ScintillaBase.cxx deleted file mode 100644 index 08b9fe829..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ScintillaBase.cxx +++ /dev/null @@ -1,1088 +0,0 @@ -// Scintilla source code edit control -/** @file ScintillaBase.cxx - ** An enhanced subclass of Editor with calltips, autocomplete and context menu. - **/ -// Copyright 1998-2003 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "Platform.h" - -#include "ILexer.h" -#include "Scintilla.h" - -#ifdef SCI_LEXER -#include "SciLexer.h" -#endif - -#include "PropSetSimple.h" - -#ifdef SCI_LEXER -#include "LexerModule.h" -#include "Catalogue.h" -#endif - -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "ContractionState.h" -#include "CellBuffer.h" -#include "CallTip.h" -#include "KeyMap.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" -#include "CharClassify.h" -#include "Decoration.h" -#include "CaseFolder.h" -#include "Document.h" -#include "Selection.h" -#include "PositionCache.h" -#include "EditModel.h" -#include "MarginView.h" -#include "EditView.h" -#include "Editor.h" -#include "AutoComplete.h" -#include "ScintillaBase.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -ScintillaBase::ScintillaBase() { - displayPopupMenu = SC_POPUP_ALL; - listType = 0; - maxListWidth = 0; - multiAutoCMode = SC_MULTIAUTOC_ONCE; -} - -ScintillaBase::~ScintillaBase() { -} - -void ScintillaBase::Finalise() { - Editor::Finalise(); - popup.Destroy(); -} - -void ScintillaBase::AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS) { - bool isFillUp = ac.Active() && ac.IsFillUpChar(*s); - if (!isFillUp) { - Editor::AddCharUTF(s, len, treatAsDBCS); - } - if (ac.Active()) { - AutoCompleteCharacterAdded(s[0]); - // For fill ups add the character after the autocompletion has - // triggered so containers see the key so can display a calltip. - if (isFillUp) { - Editor::AddCharUTF(s, len, treatAsDBCS); - } - } -} - -void ScintillaBase::Command(int cmdId) { - - switch (cmdId) { - - case idAutoComplete: // Nothing to do - - break; - - case idCallTip: // Nothing to do - - break; - - case idcmdUndo: - WndProc(SCI_UNDO, 0, 0); - break; - - case idcmdRedo: - WndProc(SCI_REDO, 0, 0); - break; - - case idcmdCut: - WndProc(SCI_CUT, 0, 0); - break; - - case idcmdCopy: - WndProc(SCI_COPY, 0, 0); - break; - - case idcmdPaste: - WndProc(SCI_PASTE, 0, 0); - break; - - case idcmdDelete: - WndProc(SCI_CLEAR, 0, 0); - break; - - case idcmdSelectAll: - WndProc(SCI_SELECTALL, 0, 0); - break; - } -} - -int ScintillaBase::KeyCommand(unsigned int iMessage) { - // Most key commands cancel autocompletion mode - if (ac.Active()) { - switch (iMessage) { - // Except for these - case SCI_LINEDOWN: - AutoCompleteMove(1); - return 0; - case SCI_LINEUP: - AutoCompleteMove(-1); - return 0; - case SCI_PAGEDOWN: - AutoCompleteMove(ac.lb->GetVisibleRows()); - return 0; - case SCI_PAGEUP: - AutoCompleteMove(-ac.lb->GetVisibleRows()); - return 0; - case SCI_VCHOME: - AutoCompleteMove(-5000); - return 0; - case SCI_LINEEND: - AutoCompleteMove(5000); - return 0; - case SCI_DELETEBACK: - DelCharBack(true); - AutoCompleteCharacterDeleted(); - EnsureCaretVisible(); - return 0; - case SCI_DELETEBACKNOTLINE: - DelCharBack(false); - AutoCompleteCharacterDeleted(); - EnsureCaretVisible(); - return 0; - case SCI_TAB: - AutoCompleteCompleted(0, SC_AC_TAB); - return 0; - case SCI_NEWLINE: - AutoCompleteCompleted(0, SC_AC_NEWLINE); - return 0; - - default: - AutoCompleteCancel(); - } - } - - if (ct.inCallTipMode) { - if ( - (iMessage != SCI_CHARLEFT) && - (iMessage != SCI_CHARLEFTEXTEND) && - (iMessage != SCI_CHARRIGHT) && - (iMessage != SCI_CHARRIGHTEXTEND) && - (iMessage != SCI_EDITTOGGLEOVERTYPE) && - (iMessage != SCI_DELETEBACK) && - (iMessage != SCI_DELETEBACKNOTLINE) - ) { - ct.CallTipCancel(); - } - if ((iMessage == SCI_DELETEBACK) || (iMessage == SCI_DELETEBACKNOTLINE)) { - if (sel.MainCaret() <= ct.posStartCallTip) { - ct.CallTipCancel(); - } - } - } - return Editor::KeyCommand(iMessage); -} - -void ScintillaBase::AutoCompleteDoubleClick(void *p) { - ScintillaBase *sci = reinterpret_cast(p); - sci->AutoCompleteCompleted(0, SC_AC_DOUBLECLICK); -} - -void ScintillaBase::AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen) { - UndoGroup ug(pdoc); - if (multiAutoCMode == SC_MULTIAUTOC_ONCE) { - pdoc->DeleteChars(startPos, removeLen); - const int lengthInserted = pdoc->InsertString(startPos, text, textLen); - SetEmptySelection(startPos + lengthInserted); - } else { - // SC_MULTIAUTOC_EACH - for (size_t r=0; r= 0) { - positionInsert -= removeLen; - pdoc->DeleteChars(positionInsert, removeLen); - } - const int lengthInserted = pdoc->InsertString(positionInsert, text, textLen); - if (lengthInserted > 0) { - sel.Range(r).caret.SetPosition(positionInsert + lengthInserted); - sel.Range(r).anchor.SetPosition(positionInsert + lengthInserted); - } - sel.Range(r).ClearVirtualSpace(); - } - } - } -} - -void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) { - //Platform::DebugPrintf("AutoComplete %s\n", list); - ct.CallTipCancel(); - - if (ac.chooseSingle && (listType == 0)) { - if (list && !strchr(list, ac.GetSeparator())) { - const char *typeSep = strchr(list, ac.GetTypesep()); - int lenInsert = typeSep ? - static_cast(typeSep-list) : static_cast(strlen(list)); - if (ac.ignoreCase) { - // May need to convert the case before invocation, so remove lenEntered characters - AutoCompleteInsert(sel.MainCaret() - lenEntered, lenEntered, list, lenInsert); - } else { - AutoCompleteInsert(sel.MainCaret(), 0, list + lenEntered, lenInsert - lenEntered); - } - ac.Cancel(); - return; - } - } - ac.Start(wMain, idAutoComplete, sel.MainCaret(), PointMainCaret(), - lenEntered, vs.lineHeight, IsUnicodeMode(), technology); - - PRectangle rcClient = GetClientRectangle(); - Point pt = LocationFromPosition(sel.MainCaret() - lenEntered); - PRectangle rcPopupBounds = wMain.GetMonitorRect(pt); - if (rcPopupBounds.Height() == 0) - rcPopupBounds = rcClient; - - int heightLB = ac.heightLBDefault; - int widthLB = ac.widthLBDefault; - if (pt.x >= rcClient.right - widthLB) { - HorizontalScrollTo(static_cast(xOffset + pt.x - rcClient.right + widthLB)); - Redraw(); - pt = PointMainCaret(); - } - if (wMargin.GetID()) { - Point ptOrigin = GetVisibleOriginInMain(); - pt.x += ptOrigin.x; - pt.y += ptOrigin.y; - } - PRectangle rcac; - rcac.left = pt.x - ac.lb->CaretFromEdge(); - if (pt.y >= rcPopupBounds.bottom - heightLB && // Won't fit below. - pt.y >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2) { // and there is more room above. - rcac.top = pt.y - heightLB; - if (rcac.top < rcPopupBounds.top) { - heightLB -= static_cast(rcPopupBounds.top - rcac.top); - rcac.top = rcPopupBounds.top; - } - } else { - rcac.top = pt.y + vs.lineHeight; - } - rcac.right = rcac.left + widthLB; - rcac.bottom = static_cast(Platform::Minimum(static_cast(rcac.top) + heightLB, static_cast(rcPopupBounds.bottom))); - ac.lb->SetPositionRelative(rcac, wMain); - ac.lb->SetFont(vs.styles[STYLE_DEFAULT].font); - unsigned int aveCharWidth = static_cast(vs.styles[STYLE_DEFAULT].aveCharWidth); - ac.lb->SetAverageCharWidth(aveCharWidth); - ac.lb->SetDoubleClickAction(AutoCompleteDoubleClick, this); - - ac.SetList(list ? list : ""); - - // Fiddle the position of the list so it is right next to the target and wide enough for all its strings - PRectangle rcList = ac.lb->GetDesiredRect(); - int heightAlloced = static_cast(rcList.bottom - rcList.top); - widthLB = Platform::Maximum(widthLB, static_cast(rcList.right - rcList.left)); - if (maxListWidth != 0) - widthLB = Platform::Minimum(widthLB, aveCharWidth*maxListWidth); - // Make an allowance for large strings in list - rcList.left = pt.x - ac.lb->CaretFromEdge(); - rcList.right = rcList.left + widthLB; - if (((pt.y + vs.lineHeight) >= (rcPopupBounds.bottom - heightAlloced)) && // Won't fit below. - ((pt.y + vs.lineHeight / 2) >= (rcPopupBounds.bottom + rcPopupBounds.top) / 2)) { // and there is more room above. - rcList.top = pt.y - heightAlloced; - } else { - rcList.top = pt.y + vs.lineHeight; - } - rcList.bottom = rcList.top + heightAlloced; - ac.lb->SetPositionRelative(rcList, wMain); - ac.Show(true); - if (lenEntered != 0) { - AutoCompleteMoveToCurrentWord(); - } -} - -void ScintillaBase::AutoCompleteCancel() { - if (ac.Active()) { - SCNotification scn = {}; - scn.nmhdr.code = SCN_AUTOCCANCELLED; - scn.wParam = 0; - scn.listType = 0; - NotifyParent(scn); - } - ac.Cancel(); -} - -void ScintillaBase::AutoCompleteMove(int delta) { - ac.Move(delta); -} - -void ScintillaBase::AutoCompleteMoveToCurrentWord() { - std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret()); - ac.Select(wordCurrent.c_str()); -} - -void ScintillaBase::AutoCompleteCharacterAdded(char ch) { - if (ac.IsFillUpChar(ch)) { - AutoCompleteCompleted(ch, SC_AC_FILLUP); - } else if (ac.IsStopChar(ch)) { - AutoCompleteCancel(); - } else { - AutoCompleteMoveToCurrentWord(); - } -} - -void ScintillaBase::AutoCompleteCharacterDeleted() { - if (sel.MainCaret() < ac.posStart - ac.startLen) { - AutoCompleteCancel(); - } else if (ac.cancelAtStartPos && (sel.MainCaret() <= ac.posStart)) { - AutoCompleteCancel(); - } else { - AutoCompleteMoveToCurrentWord(); - } - SCNotification scn = {}; - scn.nmhdr.code = SCN_AUTOCCHARDELETED; - scn.wParam = 0; - scn.listType = 0; - NotifyParent(scn); -} - -void ScintillaBase::AutoCompleteCompleted(char ch, unsigned int completionMethod) { - int item = ac.GetSelection(); - if (item == -1) { - AutoCompleteCancel(); - return; - } - const std::string selected = ac.GetValue(item); - - ac.Show(false); - - SCNotification scn = {}; - scn.nmhdr.code = listType > 0 ? SCN_USERLISTSELECTION : SCN_AUTOCSELECTION; - scn.message = 0; - scn.ch = ch; - scn.listCompletionMethod = completionMethod; - scn.wParam = listType; - scn.listType = listType; - Position firstPos = ac.posStart - ac.startLen; - scn.position = firstPos; - scn.lParam = firstPos; - scn.text = selected.c_str(); - NotifyParent(scn); - - if (!ac.Active()) - return; - ac.Cancel(); - - if (listType > 0) - return; - - Position endPos = sel.MainCaret(); - if (ac.dropRestOfWord) - endPos = pdoc->ExtendWordSelect(endPos, 1, true); - if (endPos < firstPos) - return; - AutoCompleteInsert(firstPos, endPos - firstPos, selected.c_str(), static_cast(selected.length())); - SetLastXChosen(); - - scn.nmhdr.code = SCN_AUTOCCOMPLETED; - NotifyParent(scn); - -} - -int ScintillaBase::AutoCompleteGetCurrent() const { - if (!ac.Active()) - return -1; - return ac.GetSelection(); -} - -int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) const { - if (ac.Active()) { - int item = ac.GetSelection(); - if (item != -1) { - const std::string selected = ac.GetValue(item); - if (buffer != NULL) - memcpy(buffer, selected.c_str(), selected.length()+1); - return static_cast(selected.length()); - } - } - if (buffer != NULL) - *buffer = '\0'; - return 0; -} - -void ScintillaBase::CallTipShow(Point pt, const char *defn) { - ac.Cancel(); - // If container knows about STYLE_CALLTIP then use it in place of the - // STYLE_DEFAULT for the face name, size and character set. Also use it - // for the foreground and background colour. - int ctStyle = ct.UseStyleCallTip() ? STYLE_CALLTIP : STYLE_DEFAULT; - if (ct.UseStyleCallTip()) { - ct.SetForeBack(vs.styles[STYLE_CALLTIP].fore, vs.styles[STYLE_CALLTIP].back); - } - if (wMargin.GetID()) { - Point ptOrigin = GetVisibleOriginInMain(); - pt.x += ptOrigin.x; - pt.y += ptOrigin.y; - } - PRectangle rc = ct.CallTipStart(sel.MainCaret(), pt, - vs.lineHeight, - defn, - vs.styles[ctStyle].fontName, - vs.styles[ctStyle].sizeZoomed, - CodePage(), - vs.styles[ctStyle].characterSet, - vs.technology, - wMain); - // If the call-tip window would be out of the client - // space - PRectangle rcClient = GetClientRectangle(); - int offset = vs.lineHeight + static_cast(rc.Height()); - // adjust so it displays above the text. - if (rc.bottom > rcClient.bottom && rc.Height() < rcClient.Height()) { - rc.top -= offset; - rc.bottom -= offset; - } - // adjust so it displays below the text. - if (rc.top < rcClient.top && rc.Height() < rcClient.Height()) { - rc.top += offset; - rc.bottom += offset; - } - // Now display the window. - CreateCallTipWindow(rc); - ct.wCallTip.SetPositionRelative(rc, wMain); - ct.wCallTip.Show(); -} - -void ScintillaBase::CallTipClick() { - SCNotification scn = {}; - scn.nmhdr.code = SCN_CALLTIPCLICK; - scn.position = ct.clickPlace; - NotifyParent(scn); -} - -bool ScintillaBase::ShouldDisplayPopup(Point ptInWindowCoordinates) const { - return (displayPopupMenu == SC_POPUP_ALL || - (displayPopupMenu == SC_POPUP_TEXT && !PointInSelMargin(ptInWindowCoordinates))); -} - -void ScintillaBase::ContextMenu(Point pt) { - if (displayPopupMenu) { - bool writable = !WndProc(SCI_GETREADONLY, 0, 0); - popup.CreatePopUp(); - AddToPopUp("Undo", idcmdUndo, writable && pdoc->CanUndo()); - AddToPopUp("Redo", idcmdRedo, writable && pdoc->CanRedo()); - AddToPopUp(""); - AddToPopUp("Cut", idcmdCut, writable && !sel.Empty()); - AddToPopUp("Copy", idcmdCopy, !sel.Empty()); - AddToPopUp("Paste", idcmdPaste, writable && WndProc(SCI_CANPASTE, 0, 0)); - AddToPopUp("Delete", idcmdDelete, writable && !sel.Empty()); - AddToPopUp(""); - AddToPopUp("Select All", idcmdSelectAll); - popup.Show(pt, wMain); - } -} - -void ScintillaBase::CancelModes() { - AutoCompleteCancel(); - ct.CallTipCancel(); - Editor::CancelModes(); -} - -void ScintillaBase::ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) { - CancelModes(); - Editor::ButtonDownWithModifiers(pt, curTime, modifiers); -} - -void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt) { - ButtonDownWithModifiers(pt, curTime, ModifierFlags(shift, ctrl, alt)); -} - -void ScintillaBase::RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers) { - CancelModes(); - Editor::RightButtonDownWithModifiers(pt, curTime, modifiers); -} - -#ifdef SCI_LEXER - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class LexState : public LexInterface { - const LexerModule *lexCurrent; - void SetLexerModule(const LexerModule *lex); - PropSetSimple props; - int interfaceVersion; -public: - int lexLanguage; - - explicit LexState(Document *pdoc_); - virtual ~LexState(); - void SetLexer(uptr_t wParam); - void SetLexerLanguage(const char *languageName); - const char *DescribeWordListSets(); - void SetWordList(int n, const char *wl); - const char *GetName() const; - void *PrivateCall(int operation, void *pointer); - const char *PropertyNames(); - int PropertyType(const char *name); - const char *DescribeProperty(const char *name); - void PropSet(const char *key, const char *val); - const char *PropGet(const char *key) const; - int PropGetInt(const char *key, int defaultValue=0) const; - int PropGetExpanded(const char *key, char *result) const; - - int LineEndTypesSupported(); - int AllocateSubStyles(int styleBase, int numberStyles); - int SubStylesStart(int styleBase); - int SubStylesLength(int styleBase); - int StyleFromSubStyle(int subStyle); - int PrimaryStyleFromStyle(int style); - void FreeSubStyles(); - void SetIdentifiers(int style, const char *identifiers); - int DistanceToSecondaryStyles(); - const char *GetSubStyleBases(); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) { - lexCurrent = 0; - performingStyle = false; - interfaceVersion = lvOriginal; - lexLanguage = SCLEX_CONTAINER; -} - -LexState::~LexState() { - if (instance) { - instance->Release(); - instance = 0; - } -} - -LexState *ScintillaBase::DocumentLexState() { - if (!pdoc->pli) { - pdoc->pli = new LexState(pdoc); - } - return static_cast(pdoc->pli); -} - -void LexState::SetLexerModule(const LexerModule *lex) { - if (lex != lexCurrent) { - if (instance) { - instance->Release(); - instance = 0; - } - interfaceVersion = lvOriginal; - lexCurrent = lex; - if (lexCurrent) { - instance = lexCurrent->Create(); - interfaceVersion = instance->Version(); - } - pdoc->LexerChanged(); - } -} - -void LexState::SetLexer(uptr_t wParam) { - lexLanguage = static_cast(wParam); - if (lexLanguage == SCLEX_CONTAINER) { - SetLexerModule(0); - } else { - const LexerModule *lex = Catalogue::Find(lexLanguage); - if (!lex) - lex = Catalogue::Find(SCLEX_NULL); - SetLexerModule(lex); - } -} - -void LexState::SetLexerLanguage(const char *languageName) { - const LexerModule *lex = Catalogue::Find(languageName); - if (!lex) - lex = Catalogue::Find(SCLEX_NULL); - if (lex) - lexLanguage = lex->GetLanguage(); - SetLexerModule(lex); -} - -const char *LexState::DescribeWordListSets() { - if (instance) { - return instance->DescribeWordListSets(); - } else { - return 0; - } -} - -void LexState::SetWordList(int n, const char *wl) { - if (instance) { - int firstModification = instance->WordListSet(n, wl); - if (firstModification >= 0) { - pdoc->ModifiedAt(firstModification); - } - } -} - -const char *LexState::GetName() const { - return lexCurrent ? lexCurrent->languageName : ""; -} - -void *LexState::PrivateCall(int operation, void *pointer) { - if (pdoc && instance) { - return instance->PrivateCall(operation, pointer); - } else { - return 0; - } -} - -const char *LexState::PropertyNames() { - if (instance) { - return instance->PropertyNames(); - } else { - return 0; - } -} - -int LexState::PropertyType(const char *name) { - if (instance) { - return instance->PropertyType(name); - } else { - return SC_TYPE_BOOLEAN; - } -} - -const char *LexState::DescribeProperty(const char *name) { - if (instance) { - return instance->DescribeProperty(name); - } else { - return 0; - } -} - -void LexState::PropSet(const char *key, const char *val) { - props.Set(key, val); - if (instance) { - int firstModification = instance->PropertySet(key, val); - if (firstModification >= 0) { - pdoc->ModifiedAt(firstModification); - } - } -} - -const char *LexState::PropGet(const char *key) const { - return props.Get(key); -} - -int LexState::PropGetInt(const char *key, int defaultValue) const { - return props.GetInt(key, defaultValue); -} - -int LexState::PropGetExpanded(const char *key, char *result) const { - return props.GetExpanded(key, result); -} - -int LexState::LineEndTypesSupported() { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->LineEndTypesSupported(); - } - return 0; -} - -int LexState::AllocateSubStyles(int styleBase, int numberStyles) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->AllocateSubStyles(styleBase, numberStyles); - } - return -1; -} - -int LexState::SubStylesStart(int styleBase) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->SubStylesStart(styleBase); - } - return -1; -} - -int LexState::SubStylesLength(int styleBase) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->SubStylesLength(styleBase); - } - return 0; -} - -int LexState::StyleFromSubStyle(int subStyle) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->StyleFromSubStyle(subStyle); - } - return 0; -} - -int LexState::PrimaryStyleFromStyle(int style) { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->PrimaryStyleFromStyle(style); - } - return 0; -} - -void LexState::FreeSubStyles() { - if (instance && (interfaceVersion >= lvSubStyles)) { - static_cast(instance)->FreeSubStyles(); - } -} - -void LexState::SetIdentifiers(int style, const char *identifiers) { - if (instance && (interfaceVersion >= lvSubStyles)) { - static_cast(instance)->SetIdentifiers(style, identifiers); - pdoc->ModifiedAt(0); - } -} - -int LexState::DistanceToSecondaryStyles() { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->DistanceToSecondaryStyles(); - } - return 0; -} - -const char *LexState::GetSubStyleBases() { - if (instance && (interfaceVersion >= lvSubStyles)) { - return static_cast(instance)->GetSubStyleBases(); - } - return ""; -} - -#endif - -void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) { -#ifdef SCI_LEXER - if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) { - int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled()); - int endStyled = pdoc->LineStart(lineEndStyled); - DocumentLexState()->Colourise(endStyled, endStyleNeeded); - return; - } -#endif - Editor::NotifyStyleToNeeded(endStyleNeeded); -} - -void ScintillaBase::NotifyLexerChanged(Document *, void *) { -#ifdef SCI_LEXER - vs.EnsureStyle(0xff); -#endif -} - -sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { - switch (iMessage) { - case SCI_AUTOCSHOW: - listType = 0; - AutoCompleteStart(static_cast(wParam), reinterpret_cast(lParam)); - break; - - case SCI_AUTOCCANCEL: - ac.Cancel(); - break; - - case SCI_AUTOCACTIVE: - return ac.Active(); - - case SCI_AUTOCPOSSTART: - return ac.posStart; - - case SCI_AUTOCCOMPLETE: - AutoCompleteCompleted(0, SC_AC_COMMAND); - break; - - case SCI_AUTOCSETSEPARATOR: - ac.SetSeparator(static_cast(wParam)); - break; - - case SCI_AUTOCGETSEPARATOR: - return ac.GetSeparator(); - - case SCI_AUTOCSTOPS: - ac.SetStopChars(reinterpret_cast(lParam)); - break; - - case SCI_AUTOCSELECT: - ac.Select(reinterpret_cast(lParam)); - break; - - case SCI_AUTOCGETCURRENT: - return AutoCompleteGetCurrent(); - - case SCI_AUTOCGETCURRENTTEXT: - return AutoCompleteGetCurrentText(reinterpret_cast(lParam)); - - case SCI_AUTOCSETCANCELATSTART: - ac.cancelAtStartPos = wParam != 0; - break; - - case SCI_AUTOCGETCANCELATSTART: - return ac.cancelAtStartPos; - - case SCI_AUTOCSETFILLUPS: - ac.SetFillUpChars(reinterpret_cast(lParam)); - break; - - case SCI_AUTOCSETCHOOSESINGLE: - ac.chooseSingle = wParam != 0; - break; - - case SCI_AUTOCGETCHOOSESINGLE: - return ac.chooseSingle; - - case SCI_AUTOCSETIGNORECASE: - ac.ignoreCase = wParam != 0; - break; - - case SCI_AUTOCGETIGNORECASE: - return ac.ignoreCase; - - case SCI_AUTOCSETCASEINSENSITIVEBEHAVIOUR: - ac.ignoreCaseBehaviour = static_cast(wParam); - break; - - case SCI_AUTOCGETCASEINSENSITIVEBEHAVIOUR: - return ac.ignoreCaseBehaviour; - - case SCI_AUTOCSETMULTI: - multiAutoCMode = static_cast(wParam); - break; - - case SCI_AUTOCGETMULTI: - return multiAutoCMode; - - case SCI_AUTOCSETORDER: - ac.autoSort = static_cast(wParam); - break; - - case SCI_AUTOCGETORDER: - return ac.autoSort; - - case SCI_USERLISTSHOW: - listType = static_cast(wParam); - AutoCompleteStart(0, reinterpret_cast(lParam)); - break; - - case SCI_AUTOCSETAUTOHIDE: - ac.autoHide = wParam != 0; - break; - - case SCI_AUTOCGETAUTOHIDE: - return ac.autoHide; - - case SCI_AUTOCSETDROPRESTOFWORD: - ac.dropRestOfWord = wParam != 0; - break; - - case SCI_AUTOCGETDROPRESTOFWORD: - return ac.dropRestOfWord; - - case SCI_AUTOCSETMAXHEIGHT: - ac.lb->SetVisibleRows(static_cast(wParam)); - break; - - case SCI_AUTOCGETMAXHEIGHT: - return ac.lb->GetVisibleRows(); - - case SCI_AUTOCSETMAXWIDTH: - maxListWidth = static_cast(wParam); - break; - - case SCI_AUTOCGETMAXWIDTH: - return maxListWidth; - - case SCI_REGISTERIMAGE: - ac.lb->RegisterImage(static_cast(wParam), reinterpret_cast(lParam)); - break; - - case SCI_REGISTERRGBAIMAGE: - ac.lb->RegisterRGBAImage(static_cast(wParam), static_cast(sizeRGBAImage.x), static_cast(sizeRGBAImage.y), - reinterpret_cast(lParam)); - break; - - case SCI_CLEARREGISTEREDIMAGES: - ac.lb->ClearRegisteredImages(); - break; - - case SCI_AUTOCSETTYPESEPARATOR: - ac.SetTypesep(static_cast(wParam)); - break; - - case SCI_AUTOCGETTYPESEPARATOR: - return ac.GetTypesep(); - - case SCI_CALLTIPSHOW: - CallTipShow(LocationFromPosition(static_cast(wParam)), - reinterpret_cast(lParam)); - break; - - case SCI_CALLTIPCANCEL: - ct.CallTipCancel(); - break; - - case SCI_CALLTIPACTIVE: - return ct.inCallTipMode; - - case SCI_CALLTIPPOSSTART: - return ct.posStartCallTip; - - case SCI_CALLTIPSETPOSSTART: - ct.posStartCallTip = static_cast(wParam); - break; - - case SCI_CALLTIPSETHLT: - ct.SetHighlight(static_cast(wParam), static_cast(lParam)); - break; - - case SCI_CALLTIPSETBACK: - ct.colourBG = ColourDesired(static_cast(wParam)); - vs.styles[STYLE_CALLTIP].back = ct.colourBG; - InvalidateStyleRedraw(); - break; - - case SCI_CALLTIPSETFORE: - ct.colourUnSel = ColourDesired(static_cast(wParam)); - vs.styles[STYLE_CALLTIP].fore = ct.colourUnSel; - InvalidateStyleRedraw(); - break; - - case SCI_CALLTIPSETFOREHLT: - ct.colourSel = ColourDesired(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_CALLTIPUSESTYLE: - ct.SetTabSize(static_cast(wParam)); - InvalidateStyleRedraw(); - break; - - case SCI_CALLTIPSETPOSITION: - ct.SetPosition(wParam != 0); - InvalidateStyleRedraw(); - break; - - case SCI_USEPOPUP: - displayPopupMenu = static_cast(wParam); - break; - -#ifdef SCI_LEXER - case SCI_SETLEXER: - DocumentLexState()->SetLexer(static_cast(wParam)); - break; - - case SCI_GETLEXER: - return DocumentLexState()->lexLanguage; - - case SCI_COLOURISE: - if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) { - pdoc->ModifiedAt(static_cast(wParam)); - NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : static_cast(lParam)); - } else { - DocumentLexState()->Colourise(static_cast(wParam), static_cast(lParam)); - } - Redraw(); - break; - - case SCI_SETPROPERTY: - DocumentLexState()->PropSet(reinterpret_cast(wParam), - reinterpret_cast(lParam)); - break; - - case SCI_GETPROPERTY: - return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast(wParam))); - - case SCI_GETPROPERTYEXPANDED: - return DocumentLexState()->PropGetExpanded(reinterpret_cast(wParam), - reinterpret_cast(lParam)); - - case SCI_GETPROPERTYINT: - return DocumentLexState()->PropGetInt(reinterpret_cast(wParam), static_cast(lParam)); - - case SCI_SETKEYWORDS: - DocumentLexState()->SetWordList(static_cast(wParam), reinterpret_cast(lParam)); - break; - - case SCI_SETLEXERLANGUAGE: - DocumentLexState()->SetLexerLanguage(reinterpret_cast(lParam)); - break; - - case SCI_GETLEXERLANGUAGE: - return StringResult(lParam, DocumentLexState()->GetName()); - - case SCI_PRIVATELEXERCALL: - return reinterpret_cast( - DocumentLexState()->PrivateCall(static_cast(wParam), reinterpret_cast(lParam))); - - case SCI_GETSTYLEBITSNEEDED: - return 8; - - case SCI_PROPERTYNAMES: - return StringResult(lParam, DocumentLexState()->PropertyNames()); - - case SCI_PROPERTYTYPE: - return DocumentLexState()->PropertyType(reinterpret_cast(wParam)); - - case SCI_DESCRIBEPROPERTY: - return StringResult(lParam, - DocumentLexState()->DescribeProperty(reinterpret_cast(wParam))); - - case SCI_DESCRIBEKEYWORDSETS: - return StringResult(lParam, DocumentLexState()->DescribeWordListSets()); - - case SCI_GETLINEENDTYPESSUPPORTED: - return DocumentLexState()->LineEndTypesSupported(); - - case SCI_ALLOCATESUBSTYLES: - return DocumentLexState()->AllocateSubStyles(static_cast(wParam), static_cast(lParam)); - - case SCI_GETSUBSTYLESSTART: - return DocumentLexState()->SubStylesStart(static_cast(wParam)); - - case SCI_GETSUBSTYLESLENGTH: - return DocumentLexState()->SubStylesLength(static_cast(wParam)); - - case SCI_GETSTYLEFROMSUBSTYLE: - return DocumentLexState()->StyleFromSubStyle(static_cast(wParam)); - - case SCI_GETPRIMARYSTYLEFROMSTYLE: - return DocumentLexState()->PrimaryStyleFromStyle(static_cast(wParam)); - - case SCI_FREESUBSTYLES: - DocumentLexState()->FreeSubStyles(); - break; - - case SCI_SETIDENTIFIERS: - DocumentLexState()->SetIdentifiers(static_cast(wParam), - reinterpret_cast(lParam)); - break; - - case SCI_DISTANCETOSECONDARYSTYLES: - return DocumentLexState()->DistanceToSecondaryStyles(); - - case SCI_GETSUBSTYLEBASES: - return StringResult(lParam, DocumentLexState()->GetSubStyleBases()); -#endif - - default: - return Editor::WndProc(iMessage, wParam, lParam); - } - return 0l; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/ScintillaBase.h b/qrenderdoc/3rdparty/scintilla/src/ScintillaBase.h deleted file mode 100644 index e66403367..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ScintillaBase.h +++ /dev/null @@ -1,106 +0,0 @@ -// Scintilla source code edit control -/** @file ScintillaBase.h - ** Defines an enhanced subclass of Editor with calltips, autocomplete and context menu. - **/ -// Copyright 1998-2002 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SCINTILLABASE_H -#define SCINTILLABASE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -#ifdef SCI_LEXER -class LexState; -#endif - -/** - */ -class ScintillaBase : public Editor { - // Private so ScintillaBase objects can not be copied - explicit ScintillaBase(const ScintillaBase &); - ScintillaBase &operator=(const ScintillaBase &); - -protected: - /** Enumeration of commands and child windows. */ - enum { - idCallTip=1, - idAutoComplete=2, - - idcmdUndo=10, - idcmdRedo=11, - idcmdCut=12, - idcmdCopy=13, - idcmdPaste=14, - idcmdDelete=15, - idcmdSelectAll=16 - }; - - enum { maxLenInputIME = 200 }; - - int displayPopupMenu; - Menu popup; - AutoComplete ac; - - CallTip ct; - - int listType; ///< 0 is an autocomplete list - int maxListWidth; /// Maximum width of list, in average character widths - int multiAutoCMode; /// Mode for autocompleting when multiple selections are present - -#ifdef SCI_LEXER - LexState *DocumentLexState(); - void SetLexer(uptr_t wParam); - void SetLexerLanguage(const char *languageName); - void Colourise(int start, int end); -#endif - - ScintillaBase(); - virtual ~ScintillaBase(); - virtual void Initialise() = 0; - virtual void Finalise(); - - virtual void AddCharUTF(const char *s, unsigned int len, bool treatAsDBCS=false); - void Command(int cmdId); - virtual void CancelModes(); - virtual int KeyCommand(unsigned int iMessage); - - void AutoCompleteInsert(Position startPos, int removeLen, const char *text, int textLen); - void AutoCompleteStart(int lenEntered, const char *list); - void AutoCompleteCancel(); - void AutoCompleteMove(int delta); - int AutoCompleteGetCurrent() const; - int AutoCompleteGetCurrentText(char *buffer) const; - void AutoCompleteCharacterAdded(char ch); - void AutoCompleteCharacterDeleted(); - void AutoCompleteCompleted(char ch, unsigned int completionMethod); - void AutoCompleteMoveToCurrentWord(); - static void AutoCompleteDoubleClick(void *p); - - void CallTipClick(); - void CallTipShow(Point pt, const char *defn); - virtual void CreateCallTipWindow(PRectangle rc) = 0; - - virtual void AddToPopUp(const char *label, int cmd=0, bool enabled=true) = 0; - bool ShouldDisplayPopup(Point ptInWindowCoordinates) const; - void ContextMenu(Point pt); - - virtual void ButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers); - virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt); - virtual void RightButtonDownWithModifiers(Point pt, unsigned int curTime, int modifiers); - - void NotifyStyleToNeeded(int endStyleNeeded); - void NotifyLexerChanged(Document *doc, void *userData); - -public: - // Public so scintilla_send_message can use it - virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam); -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Selection.cxx b/qrenderdoc/3rdparty/scintilla/src/Selection.cxx deleted file mode 100644 index d58a03980..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Selection.cxx +++ /dev/null @@ -1,436 +0,0 @@ -// Scintilla source code edit control -/** @file Selection.cxx - ** Classes maintaining the selection. - **/ -// Copyright 2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" - -#include "Position.h" -#include "Selection.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) { - if (insertion) { - if (position == startChange) { - int virtualLengthRemove = std::min(length, virtualSpace); - virtualSpace -= virtualLengthRemove; - position += virtualLengthRemove; - } else if (position > startChange) { - position += length; - } - } else { - if (position == startChange) { - virtualSpace = 0; - } - if (position > startChange) { - int endDeletion = startChange + length; - if (position > endDeletion) { - position -= length; - } else { - position = startChange; - virtualSpace = 0; - } - } - } -} - -bool SelectionPosition::operator <(const SelectionPosition &other) const { - if (position == other.position) - return virtualSpace < other.virtualSpace; - else - return position < other.position; -} - -bool SelectionPosition::operator >(const SelectionPosition &other) const { - if (position == other.position) - return virtualSpace > other.virtualSpace; - else - return position > other.position; -} - -bool SelectionPosition::operator <=(const SelectionPosition &other) const { - if (position == other.position && virtualSpace == other.virtualSpace) - return true; - else - return other > *this; -} - -bool SelectionPosition::operator >=(const SelectionPosition &other) const { - if (position == other.position && virtualSpace == other.virtualSpace) - return true; - else - return *this > other; -} - -int SelectionRange::Length() const { - if (anchor > caret) { - return anchor.Position() - caret.Position(); - } else { - return caret.Position() - anchor.Position(); - } -} - -void SelectionRange::MoveForInsertDelete(bool insertion, int startChange, int length) { - caret.MoveForInsertDelete(insertion, startChange, length); - anchor.MoveForInsertDelete(insertion, startChange, length); -} - -bool SelectionRange::Contains(int pos) const { - if (anchor > caret) - return (pos >= caret.Position()) && (pos <= anchor.Position()); - else - return (pos >= anchor.Position()) && (pos <= caret.Position()); -} - -bool SelectionRange::Contains(SelectionPosition sp) const { - if (anchor > caret) - return (sp >= caret) && (sp <= anchor); - else - return (sp >= anchor) && (sp <= caret); -} - -bool SelectionRange::ContainsCharacter(int posCharacter) const { - if (anchor > caret) - return (posCharacter >= caret.Position()) && (posCharacter < anchor.Position()); - else - return (posCharacter >= anchor.Position()) && (posCharacter < caret.Position()); -} - -SelectionSegment SelectionRange::Intersect(SelectionSegment check) const { - SelectionSegment inOrder(caret, anchor); - if ((inOrder.start <= check.end) || (inOrder.end >= check.start)) { - SelectionSegment portion = check; - if (portion.start < inOrder.start) - portion.start = inOrder.start; - if (portion.end > inOrder.end) - portion.end = inOrder.end; - if (portion.start > portion.end) - return SelectionSegment(); - else - return portion; - } else { - return SelectionSegment(); - } -} - -void SelectionRange::Swap() { - std::swap(caret, anchor); -} - -bool SelectionRange::Trim(SelectionRange range) { - SelectionPosition startRange = range.Start(); - SelectionPosition endRange = range.End(); - SelectionPosition start = Start(); - SelectionPosition end = End(); - PLATFORM_ASSERT(start <= end); - PLATFORM_ASSERT(startRange <= endRange); - if ((startRange <= end) && (endRange >= start)) { - if ((start > startRange) && (end < endRange)) { - // Completely covered by range -> empty at start - end = start; - } else if ((start < startRange) && (end > endRange)) { - // Completely covers range -> empty at start - end = start; - } else if (start <= startRange) { - // Trim end - end = startRange; - } else { // - PLATFORM_ASSERT(end >= endRange); - // Trim start - start = endRange; - } - if (anchor > caret) { - caret = start; - anchor = end; - } else { - anchor = start; - caret = end; - } - return Empty(); - } else { - return false; - } -} - -// If range is all virtual collapse to start of virtual space -void SelectionRange::MinimizeVirtualSpace() { - if (caret.Position() == anchor.Position()) { - int virtualSpace = caret.VirtualSpace(); - if (virtualSpace > anchor.VirtualSpace()) - virtualSpace = anchor.VirtualSpace(); - caret.SetVirtualSpace(virtualSpace); - anchor.SetVirtualSpace(virtualSpace); - } -} - -Selection::Selection() : mainRange(0), moveExtends(false), tentativeMain(false), selType(selStream) { - AddSelection(SelectionRange(SelectionPosition(0))); -} - -Selection::~Selection() { -} - -bool Selection::IsRectangular() const { - return (selType == selRectangle) || (selType == selThin); -} - -int Selection::MainCaret() const { - return ranges[mainRange].caret.Position(); -} - -int Selection::MainAnchor() const { - return ranges[mainRange].anchor.Position(); -} - -SelectionRange &Selection::Rectangular() { - return rangeRectangular; -} - -SelectionSegment Selection::Limits() const { - if (ranges.empty()) { - return SelectionSegment(); - } else { - SelectionSegment sr(ranges[0].anchor, ranges[0].caret); - for (size_t i=1; i 1) && (r < ranges.size())) { - size_t mainNew = mainRange; - if (mainNew >= r) { - if (mainNew == 0) { - mainNew = ranges.size() - 2; - } else { - mainNew--; - } - } - ranges.erase(ranges.begin() + r); - mainRange = mainNew; - } -} - -void Selection::DropAdditionalRanges() { - SetSelection(RangeMain()); -} - -void Selection::TentativeSelection(SelectionRange range) { - if (!tentativeMain) { - rangesSaved = ranges; - } - ranges = rangesSaved; - AddSelection(range); - TrimSelection(ranges[mainRange]); - tentativeMain = true; -} - -void Selection::CommitTentative() { - rangesSaved.clear(); - tentativeMain = false; -} - -int Selection::CharacterInSelection(int posCharacter) const { - for (size_t i=0; i ranges[i].Start().Position()) && (pos <= ranges[i].End().Position())) - return i == mainRange ? 1 : 2; - } - return 0; -} - -int Selection::VirtualSpaceFor(int pos) const { - int virtualSpace = 0; - for (size_t i=0; i= j) - mainRange--; - } else { - j++; - } - } - } - } -} - -void Selection::RotateMain() { - mainRange = (mainRange + 1) % ranges.size(); -} - diff --git a/qrenderdoc/3rdparty/scintilla/src/Selection.h b/qrenderdoc/3rdparty/scintilla/src/Selection.h deleted file mode 100644 index 5ec5c5424..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Selection.h +++ /dev/null @@ -1,196 +0,0 @@ -// Scintilla source code edit control -/** @file Selection.h - ** Classes maintaining the selection. - **/ -// Copyright 2009 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SELECTION_H -#define SELECTION_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -class SelectionPosition { - int position; - int virtualSpace; -public: - explicit SelectionPosition(int position_=INVALID_POSITION, int virtualSpace_=0) : position(position_), virtualSpace(virtualSpace_) { - PLATFORM_ASSERT(virtualSpace < 800000); - if (virtualSpace < 0) - virtualSpace = 0; - } - void Reset() { - position = 0; - virtualSpace = 0; - } - void MoveForInsertDelete(bool insertion, int startChange, int length); - bool operator ==(const SelectionPosition &other) const { - return position == other.position && virtualSpace == other.virtualSpace; - } - bool operator <(const SelectionPosition &other) const; - bool operator >(const SelectionPosition &other) const; - bool operator <=(const SelectionPosition &other) const; - bool operator >=(const SelectionPosition &other) const; - int Position() const { - return position; - } - void SetPosition(int position_) { - position = position_; - virtualSpace = 0; - } - int VirtualSpace() const { - return virtualSpace; - } - void SetVirtualSpace(int virtualSpace_) { - PLATFORM_ASSERT(virtualSpace_ < 800000); - if (virtualSpace_ >= 0) - virtualSpace = virtualSpace_; - } - void Add(int increment) { - position = position + increment; - } - bool IsValid() const { - return position >= 0; - } -}; - -// Ordered range to make drawing simpler -struct SelectionSegment { - SelectionPosition start; - SelectionPosition end; - SelectionSegment() : start(), end() { - } - SelectionSegment(SelectionPosition a, SelectionPosition b) { - if (a < b) { - start = a; - end = b; - } else { - start = b; - end = a; - } - } - bool Empty() const { - return start == end; - } - void Extend(SelectionPosition p) { - if (start > p) - start = p; - if (end < p) - end = p; - } -}; - -struct SelectionRange { - SelectionPosition caret; - SelectionPosition anchor; - - SelectionRange() : caret(), anchor() { - } - explicit SelectionRange(SelectionPosition single) : caret(single), anchor(single) { - } - explicit SelectionRange(int single) : caret(single), anchor(single) { - } - SelectionRange(SelectionPosition caret_, SelectionPosition anchor_) : caret(caret_), anchor(anchor_) { - } - SelectionRange(int caret_, int anchor_) : caret(caret_), anchor(anchor_) { - } - bool Empty() const { - return anchor == caret; - } - int Length() const; - // int Width() const; // Like Length but takes virtual space into account - bool operator ==(const SelectionRange &other) const { - return caret == other.caret && anchor == other.anchor; - } - bool operator <(const SelectionRange &other) const { - return caret < other.caret || ((caret == other.caret) && (anchor < other.anchor)); - } - void Reset() { - anchor.Reset(); - caret.Reset(); - } - void ClearVirtualSpace() { - anchor.SetVirtualSpace(0); - caret.SetVirtualSpace(0); - } - void MoveForInsertDelete(bool insertion, int startChange, int length); - bool Contains(int pos) const; - bool Contains(SelectionPosition sp) const; - bool ContainsCharacter(int posCharacter) const; - SelectionSegment Intersect(SelectionSegment check) const; - SelectionPosition Start() const { - return (anchor < caret) ? anchor : caret; - } - SelectionPosition End() const { - return (anchor < caret) ? caret : anchor; - } - void Swap(); - bool Trim(SelectionRange range); - // If range is all virtual collapse to start of virtual space - void MinimizeVirtualSpace(); -}; - -class Selection { - std::vector ranges; - std::vector rangesSaved; - SelectionRange rangeRectangular; - size_t mainRange; - bool moveExtends; - bool tentativeMain; -public: - enum selTypes { noSel, selStream, selRectangle, selLines, selThin }; - selTypes selType; - - Selection(); - ~Selection(); - bool IsRectangular() const; - int MainCaret() const; - int MainAnchor() const; - SelectionRange &Rectangular(); - SelectionSegment Limits() const; - // This is for when you want to move the caret in response to a - // user direction command - for rectangular selections, use the range - // that covers all selected text otherwise return the main selection. - SelectionSegment LimitsForRectangularElseMain() const; - size_t Count() const; - size_t Main() const; - void SetMain(size_t r); - SelectionRange &Range(size_t r); - const SelectionRange &Range(size_t r) const; - SelectionRange &RangeMain(); - const SelectionRange &RangeMain() const; - SelectionPosition Start() const; - bool MoveExtends() const; - void SetMoveExtends(bool moveExtends_); - bool Empty() const; - SelectionPosition Last() const; - int Length() const; - void MovePositions(bool insertion, int startChange, int length); - void TrimSelection(SelectionRange range); - void TrimOtherSelections(size_t r, SelectionRange range); - void SetSelection(SelectionRange range); - void AddSelection(SelectionRange range); - void AddSelectionWithoutTrim(SelectionRange range); - void DropSelection(size_t r); - void DropAdditionalRanges(); - void TentativeSelection(SelectionRange range); - void CommitTentative(); - int CharacterInSelection(int posCharacter) const; - int InSelectionForEOL(int pos) const; - int VirtualSpaceFor(int pos) const; - void Clear(); - void RemoveDuplicates(); - void RotateMain(); - bool Tentative() const { return tentativeMain; } - std::vector RangesCopy() const { - return ranges; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/SparseVector.h b/qrenderdoc/3rdparty/scintilla/src/SparseVector.h deleted file mode 100644 index f96b36b8b..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/SparseVector.h +++ /dev/null @@ -1,186 +0,0 @@ -// Scintilla source code edit control -/** @file SparseVector.h - ** Hold data sparsely associated with elements in a range. - **/ -// Copyright 2016 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SPARSEVECTOR_H -#define SPARSEVECTOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -// SparseVector is similar to RunStyles but is more efficient for cases where values occur -// for one position instead of over a range of positions. -template -class SparseVector { -private: - Partitioning *starts; - SplitVector *values; - // Private so SparseVector objects can not be copied - SparseVector(const SparseVector &); - void ClearValue(int partition) { - values->SetValueAt(partition, T()); - } - void CommonSetValueAt(int position, T value) { - // Do the work of setting the value to allow for specialization of SetValueAt. - assert(position < Length()); - const int partition = starts->PartitionFromPosition(position); - const int startPartition = starts->PositionFromPartition(partition); - if (value == T()) { - // Setting the empty value is equivalent to deleting the position - if (position == 0) { - ClearValue(partition); - } else if (position == startPartition) { - // Currently an element at this position, so remove - ClearValue(partition); - starts->RemovePartition(partition); - values->Delete(partition); - } - // Else element remains empty - } else { - if (position == startPartition) { - // Already a value at this position, so replace - ClearValue(partition); - values->SetValueAt(partition, value); - } else { - // Insert a new element - starts->InsertPartition(partition + 1, position); - values->InsertValue(partition + 1, 1, value); - } - } - } -public: - SparseVector() { - starts = new Partitioning(8); - values = new SplitVector(); - values->InsertValue(0, 2, T()); - } - ~SparseVector() { - delete starts; - starts = NULL; - // starts dead here but not used by ClearValue. - for (int part = 0; part < values->Length(); part++) { - ClearValue(part); - } - delete values; - values = NULL; - } - int Length() const { - return starts->PositionFromPartition(starts->Partitions()); - } - int Elements() const { - return starts->Partitions(); - } - int PositionOfElement(int element) const { - return starts->PositionFromPartition(element); - } - T ValueAt(int position) const { - assert(position < Length()); - const int partition = starts->PartitionFromPosition(position); - const int startPartition = starts->PositionFromPartition(partition); - if (startPartition == position) { - return values->ValueAt(partition); - } else { - return T(); - } - } - void SetValueAt(int position, T value) { - CommonSetValueAt(position, value); - } - void InsertSpace(int position, int insertLength) { - assert(position <= Length()); // Only operation that works at end. - const int partition = starts->PartitionFromPosition(position); - const int startPartition = starts->PositionFromPartition(partition); - if (startPartition == position) { - T valueCurrent = values->ValueAt(partition); - // Inserting at start of run so make previous longer - if (partition == 0) { - // Inserting at start of document so ensure 0 - if (valueCurrent != T()) { - ClearValue(0); - starts->InsertPartition(1, 0); - values->InsertValue(1, 1, valueCurrent); - starts->InsertText(0, insertLength); - } else { - starts->InsertText(partition, insertLength); - } - } else { - if (valueCurrent != T()) { - starts->InsertText(partition - 1, insertLength); - } else { - // Insert at end of run so do not extend style - starts->InsertText(partition, insertLength); - } - } - } else { - starts->InsertText(partition, insertLength); - } - } - void DeletePosition(int position) { - assert(position < Length()); - int partition = starts->PartitionFromPosition(position); - const int startPartition = starts->PositionFromPartition(partition); - if (startPartition == position) { - if (partition == 0) { - ClearValue(0); - } else if (partition == starts->Partitions()) { - // This should not be possible - ClearValue(partition); - throw std::runtime_error("SparseVector: deleting end partition."); - } else { - ClearValue(partition); - starts->RemovePartition(partition); - values->Delete(partition); - // Its the previous partition now that gets smaller - partition--; - } - } - starts->InsertText(partition, -1); - } - void Check() const { - if (Length() < 0) { - throw std::runtime_error("SparseVector: Length can not be negative."); - } - if (starts->Partitions() < 1) { - throw std::runtime_error("SparseVector: Must always have 1 or more partitions."); - } - if (starts->Partitions() != values->Length() - 1) { - throw std::runtime_error("SparseVector: Partitions and values different lengths."); - } - // The final element can not be set - if (values->ValueAt(values->Length() - 1) != T()) { - throw std::runtime_error("SparseVector: Unused style at end changed."); - } - } -}; - -// The specialization for const char * makes copies and deletes them as needed. - -template<> -inline void SparseVector::ClearValue(int partition) { - const char *value = values->ValueAt(partition); - delete []value; - values->SetValueAt(partition, NULL); -} - -template<> -inline void SparseVector::SetValueAt(int position, const char *value) { - // Make a copy of the string - if (value) { - const size_t len = strlen(value); - char *valueCopy = new char[len + 1](); - std::copy(value, value + len, valueCopy); - CommonSetValueAt(position, valueCopy); - } else { - CommonSetValueAt(position, NULL); - } -} - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/SplitVector.h b/qrenderdoc/3rdparty/scintilla/src/SplitVector.h deleted file mode 100644 index df722530e..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/SplitVector.h +++ /dev/null @@ -1,296 +0,0 @@ -// Scintilla source code edit control -/** @file SplitVector.h - ** Main data structure for holding arrays that handle insertions - ** and deletions efficiently. - **/ -// Copyright 1998-2007 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef SPLITVECTOR_H -#define SPLITVECTOR_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -template -class SplitVector { -protected: - T *body; - int size; - int lengthBody; - int part1Length; - int gapLength; /// invariant: gapLength == size - lengthBody - int growSize; - - /// Move the gap to a particular position so that insertion and - /// deletion at that point will not require much copying and - /// hence be fast. - void GapTo(int position) { - if (position != part1Length) { - if (position < part1Length) { - // Moving the gap towards start so moving elements towards end - std::copy_backward( - body + position, - body + part1Length, - body + gapLength + part1Length); - } else { // position > part1Length - // Moving the gap towards end so moving elements towards start - std::copy( - body + part1Length + gapLength, - body + gapLength + position, - body + part1Length); - } - part1Length = position; - } - } - - /// Check that there is room in the buffer for an insertion, - /// reallocating if more space needed. - void RoomFor(int insertionLength) { - if (gapLength <= insertionLength) { - while (growSize < size / 6) - growSize *= 2; - ReAllocate(size + insertionLength + growSize); - } - } - - void Init() { - body = NULL; - growSize = 8; - size = 0; - lengthBody = 0; - part1Length = 0; - gapLength = 0; - } - -public: - /// Construct a split buffer. - SplitVector() { - Init(); - } - - ~SplitVector() { - delete []body; - body = 0; - } - - int GetGrowSize() const { - return growSize; - } - - void SetGrowSize(int growSize_) { - growSize = growSize_; - } - - /// Reallocate the storage for the buffer to be newSize and - /// copy exisiting contents to the new buffer. - /// Must not be used to decrease the size of the buffer. - void ReAllocate(int newSize) { - if (newSize < 0) - throw std::runtime_error("SplitVector::ReAllocate: negative size."); - - if (newSize > size) { - // Move the gap to the end - GapTo(lengthBody); - T *newBody = new T[newSize]; - if ((size != 0) && (body != 0)) { - std::copy(body, body + lengthBody, newBody); - delete []body; - } - body = newBody; - gapLength += newSize - size; - size = newSize; - } - } - - /// Retrieve the character at a particular position. - /// Retrieving positions outside the range of the buffer returns 0. - /// The assertions here are disabled since calling code can be - /// simpler if out of range access works and returns 0. - T ValueAt(int position) const { - if (position < part1Length) { - //PLATFORM_ASSERT(position >= 0); - if (position < 0) { - return 0; - } else { - return body[position]; - } - } else { - //PLATFORM_ASSERT(position < lengthBody); - if (position >= lengthBody) { - return 0; - } else { - return body[gapLength + position]; - } - } - } - - void SetValueAt(int position, T v) { - if (position < part1Length) { - PLATFORM_ASSERT(position >= 0); - if (position < 0) { - ; - } else { - body[position] = v; - } - } else { - PLATFORM_ASSERT(position < lengthBody); - if (position >= lengthBody) { - ; - } else { - body[gapLength + position] = v; - } - } - } - - T &operator[](int position) const { - PLATFORM_ASSERT(position >= 0 && position < lengthBody); - if (position < part1Length) { - return body[position]; - } else { - return body[gapLength + position]; - } - } - - /// Retrieve the length of the buffer. - int Length() const { - return lengthBody; - } - - /// Insert a single value into the buffer. - /// Inserting at positions outside the current range fails. - void Insert(int position, T v) { - PLATFORM_ASSERT((position >= 0) && (position <= lengthBody)); - if ((position < 0) || (position > lengthBody)) { - return; - } - RoomFor(1); - GapTo(position); - body[part1Length] = v; - lengthBody++; - part1Length++; - gapLength--; - } - - /// Insert a number of elements into the buffer setting their value. - /// Inserting at positions outside the current range fails. - void InsertValue(int position, int insertLength, T v) { - PLATFORM_ASSERT((position >= 0) && (position <= lengthBody)); - if (insertLength > 0) { - if ((position < 0) || (position > lengthBody)) { - return; - } - RoomFor(insertLength); - GapTo(position); - std::fill(&body[part1Length], &body[part1Length + insertLength], v); - lengthBody += insertLength; - part1Length += insertLength; - gapLength -= insertLength; - } - } - - /// Ensure at least length elements allocated, - /// appending zero valued elements if needed. - void EnsureLength(int wantedLength) { - if (Length() < wantedLength) { - InsertValue(Length(), wantedLength - Length(), 0); - } - } - - /// Insert text into the buffer from an array. - void InsertFromArray(int positionToInsert, const T s[], int positionFrom, int insertLength) { - PLATFORM_ASSERT((positionToInsert >= 0) && (positionToInsert <= lengthBody)); - if (insertLength > 0) { - if ((positionToInsert < 0) || (positionToInsert > lengthBody)) { - return; - } - RoomFor(insertLength); - GapTo(positionToInsert); - std::copy(s + positionFrom, s + positionFrom + insertLength, body + part1Length); - lengthBody += insertLength; - part1Length += insertLength; - gapLength -= insertLength; - } - } - - /// Delete one element from the buffer. - void Delete(int position) { - PLATFORM_ASSERT((position >= 0) && (position < lengthBody)); - if ((position < 0) || (position >= lengthBody)) { - return; - } - DeleteRange(position, 1); - } - - /// Delete a range from the buffer. - /// Deleting positions outside the current range fails. - void DeleteRange(int position, int deleteLength) { - PLATFORM_ASSERT((position >= 0) && (position + deleteLength <= lengthBody)); - if ((position < 0) || ((position + deleteLength) > lengthBody)) { - return; - } - if ((position == 0) && (deleteLength == lengthBody)) { - // Full deallocation returns storage and is faster - delete []body; - Init(); - } else if (deleteLength > 0) { - GapTo(position); - lengthBody -= deleteLength; - gapLength += deleteLength; - } - } - - /// Delete all the buffer contents. - void DeleteAll() { - DeleteRange(0, lengthBody); - } - - // Retrieve a range of elements into an array - void GetRange(T *buffer, int position, int retrieveLength) const { - // Split into up to 2 ranges, before and after the split then use memcpy on each. - int range1Length = 0; - if (position < part1Length) { - int part1AfterPosition = part1Length - position; - range1Length = retrieveLength; - if (range1Length > part1AfterPosition) - range1Length = part1AfterPosition; - } - std::copy(body + position, body + position + range1Length, buffer); - buffer += range1Length; - position = position + range1Length + gapLength; - int range2Length = retrieveLength - range1Length; - std::copy(body + position, body + position + range2Length, buffer); - } - - T *BufferPointer() { - RoomFor(1); - GapTo(lengthBody); - body[lengthBody] = 0; - return body; - } - - T *RangePointer(int position, int rangeLength) { - if (position < part1Length) { - if ((position + rangeLength) > part1Length) { - // Range overlaps gap, so move gap to start of range. - GapTo(position); - return body + position + gapLength; - } else { - return body + position; - } - } else { - return body + position + gapLength; - } - } - - int GapPosition() const { - return part1Length; - } -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/Style.cxx b/qrenderdoc/3rdparty/scintilla/src/Style.cxx deleted file mode 100644 index d8efd0ece..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Style.cxx +++ /dev/null @@ -1,169 +0,0 @@ -// Scintilla source code edit control -/** @file Style.cxx - ** Defines the font and colour style for a class of text. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Style.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -FontAlias::FontAlias() { -} - -FontAlias::FontAlias(const FontAlias &other) : Font() { - SetID(other.fid); -} - -FontAlias::~FontAlias() { - SetID(0); - // ~Font will not release the actual font resource since it is now 0 -} - -void FontAlias::MakeAlias(Font &fontOrigin) { - SetID(fontOrigin.GetID()); -} - -void FontAlias::ClearFont() { - SetID(0); -} - -bool FontSpecification::operator==(const FontSpecification &other) const { - return fontName == other.fontName && - weight == other.weight && - italic == other.italic && - size == other.size && - characterSet == other.characterSet && - extraFontFlag == other.extraFontFlag; -} - -bool FontSpecification::operator<(const FontSpecification &other) const { - if (fontName != other.fontName) - return fontName < other.fontName; - if (weight != other.weight) - return weight < other.weight; - if (italic != other.italic) - return italic == false; - if (size != other.size) - return size < other.size; - if (characterSet != other.characterSet) - return characterSet < other.characterSet; - if (extraFontFlag != other.extraFontFlag) - return extraFontFlag < other.extraFontFlag; - return false; -} - -FontMeasurements::FontMeasurements() { - Clear(); -} - -void FontMeasurements::Clear() { - ascent = 1; - descent = 1; - aveCharWidth = 1; - spaceWidth = 1; - sizeZoomed = 2; -} - -Style::Style() : FontSpecification() { - Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, 0, SC_CHARSET_DEFAULT, - SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); -} - -Style::Style(const Style &source) : FontSpecification(), FontMeasurements() { - Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - 0, 0, 0, - SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); - fore = source.fore; - back = source.back; - characterSet = source.characterSet; - weight = source.weight; - italic = source.italic; - size = source.size; - fontName = source.fontName; - eolFilled = source.eolFilled; - underline = source.underline; - caseForce = source.caseForce; - visible = source.visible; - changeable = source.changeable; - hotspot = source.hotspot; -} - -Style::~Style() { -} - -Style &Style::operator=(const Style &source) { - if (this == &source) - return * this; - Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff), - 0, 0, SC_CHARSET_DEFAULT, - SC_WEIGHT_NORMAL, false, false, false, caseMixed, true, true, false); - fore = source.fore; - back = source.back; - characterSet = source.characterSet; - weight = source.weight; - italic = source.italic; - size = source.size; - fontName = source.fontName; - eolFilled = source.eolFilled; - underline = source.underline; - caseForce = source.caseForce; - visible = source.visible; - changeable = source.changeable; - return *this; -} - -void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_, - const char *fontName_, int characterSet_, - int weight_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, - bool visible_, bool changeable_, bool hotspot_) { - fore = fore_; - back = back_; - characterSet = characterSet_; - weight = weight_; - italic = italic_; - size = size_; - fontName = fontName_; - eolFilled = eolFilled_; - underline = underline_; - caseForce = caseForce_; - visible = visible_; - changeable = changeable_; - hotspot = hotspot_; - font.ClearFont(); - FontMeasurements::Clear(); -} - -void Style::ClearTo(const Style &source) { - Clear( - source.fore, - source.back, - source.size, - source.fontName, - source.characterSet, - source.weight, - source.italic, - source.eolFilled, - source.underline, - source.caseForce, - source.visible, - source.changeable, - source.hotspot); -} - -void Style::Copy(Font &font_, const FontMeasurements &fm_) { - font.MakeAlias(font_); - (FontMeasurements &)(*this) = fm_; -} diff --git a/qrenderdoc/3rdparty/scintilla/src/Style.h b/qrenderdoc/3rdparty/scintilla/src/Style.h deleted file mode 100644 index cc9148af6..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/Style.h +++ /dev/null @@ -1,91 +0,0 @@ -// Scintilla source code edit control -/** @file Style.h - ** Defines the font and colour style for a class of text. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef STYLE_H -#define STYLE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -struct FontSpecification { - const char *fontName; - int weight; - bool italic; - int size; - int characterSet; - int extraFontFlag; - FontSpecification() : - fontName(0), - weight(SC_WEIGHT_NORMAL), - italic(false), - size(10 * SC_FONT_SIZE_MULTIPLIER), - characterSet(0), - extraFontFlag(0) { - } - bool operator==(const FontSpecification &other) const; - bool operator<(const FontSpecification &other) const; -}; - -// Just like Font but only has a copy of the FontID so should not delete it -class FontAlias : public Font { - // Private so FontAlias objects can not be assigned except for intiialization - FontAlias &operator=(const FontAlias &); -public: - FontAlias(); - FontAlias(const FontAlias &); - virtual ~FontAlias(); - void MakeAlias(Font &fontOrigin); - void ClearFont(); -}; - -struct FontMeasurements { - unsigned int ascent; - unsigned int descent; - XYPOSITION aveCharWidth; - XYPOSITION spaceWidth; - int sizeZoomed; - FontMeasurements(); - void Clear(); -}; - -/** - */ -class Style : public FontSpecification, public FontMeasurements { -public: - ColourDesired fore; - ColourDesired back; - bool eolFilled; - bool underline; - enum ecaseForced {caseMixed, caseUpper, caseLower, caseCamel}; - ecaseForced caseForce; - bool visible; - bool changeable; - bool hotspot; - - FontAlias font; - - Style(); - Style(const Style &source); - ~Style(); - Style &operator=(const Style &source); - void Clear(ColourDesired fore_, ColourDesired back_, - int size_, - const char *fontName_, int characterSet_, - int weight_, bool italic_, bool eolFilled_, - bool underline_, ecaseForced caseForce_, - bool visible_, bool changeable_, bool hotspot_); - void ClearTo(const Style &source); - void Copy(Font &font_, const FontMeasurements &fm_); - bool IsProtected() const { return !(changeable && visible);} -}; - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/UniConversion.cxx b/qrenderdoc/3rdparty/scintilla/src/UniConversion.cxx deleted file mode 100644 index 4da9e102a..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/UniConversion.cxx +++ /dev/null @@ -1,309 +0,0 @@ -// Scintilla source code edit control -/** @file UniConversion.cxx - ** Functions to handle UTF-8 and UTF-16 strings. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include - -#include - -#include "UniConversion.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen) { - unsigned int len = 0; - for (unsigned int i = 0; i < tlen && uptr[i];) { - unsigned int uch = uptr[i]; - if (uch < 0x80) { - len++; - } else if (uch < 0x800) { - len += 2; - } else if ((uch >= SURROGATE_LEAD_FIRST) && - (uch <= SURROGATE_TRAIL_LAST)) { - len += 4; - i++; - } else { - len += 3; - } - i++; - } - return len; -} - -void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len) { - unsigned int k = 0; - for (unsigned int i = 0; i < tlen && uptr[i];) { - unsigned int uch = uptr[i]; - if (uch < 0x80) { - putf[k++] = static_cast(uch); - } else if (uch < 0x800) { - putf[k++] = static_cast(0xC0 | (uch >> 6)); - putf[k++] = static_cast(0x80 | (uch & 0x3f)); - } else if ((uch >= SURROGATE_LEAD_FIRST) && - (uch <= SURROGATE_TRAIL_LAST)) { - // Half a surrogate pair - i++; - unsigned int xch = 0x10000 + ((uch & 0x3ff) << 10) + (uptr[i] & 0x3ff); - putf[k++] = static_cast(0xF0 | (xch >> 18)); - putf[k++] = static_cast(0x80 | ((xch >> 12) & 0x3f)); - putf[k++] = static_cast(0x80 | ((xch >> 6) & 0x3f)); - putf[k++] = static_cast(0x80 | (xch & 0x3f)); - } else { - putf[k++] = static_cast(0xE0 | (uch >> 12)); - putf[k++] = static_cast(0x80 | ((uch >> 6) & 0x3f)); - putf[k++] = static_cast(0x80 | (uch & 0x3f)); - } - i++; - } - if (k < len) - putf[k] = '\0'; -} - -unsigned int UTF8CharLength(unsigned char ch) { - if (ch < 0x80) { - return 1; - } else if (ch < 0x80 + 0x40 + 0x20) { - return 2; - } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { - return 3; - } else { - return 4; - } -} - -size_t UTF16Length(const char *s, size_t len) { - size_t ulen = 0; - size_t charLen; - for (size_t i = 0; i(s[i]); - if (ch < 0x80) { - charLen = 1; - } else if (ch < 0x80 + 0x40 + 0x20) { - charLen = 2; - } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { - charLen = 3; - } else { - charLen = 4; - ulen++; - } - i += charLen; - ulen++; - } - return ulen; -} - -size_t UTF16FromUTF8(const char *s, size_t len, wchar_t *tbuf, size_t tlen) { - size_t ui = 0; - const unsigned char *us = reinterpret_cast(s); - size_t i = 0; - while ((i((ch & 0x1F) << 6); - ch = us[i++]; - tbuf[ui] = static_cast(tbuf[ui] + (ch & 0x7F)); - } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) { - tbuf[ui] = static_cast((ch & 0xF) << 12); - ch = us[i++]; - tbuf[ui] = static_cast(tbuf[ui] + ((ch & 0x7F) << 6)); - ch = us[i++]; - tbuf[ui] = static_cast(tbuf[ui] + (ch & 0x7F)); - } else { - // Outside the BMP so need two surrogates - int val = (ch & 0x7) << 18; - ch = us[i++]; - val += (ch & 0x3F) << 12; - ch = us[i++]; - val += (ch & 0x3F) << 6; - ch = us[i++]; - val += (ch & 0x3F); - tbuf[ui] = static_cast(((val - 0x10000) >> 10) + SURROGATE_LEAD_FIRST); - ui++; - tbuf[ui] = static_cast((val & 0x3ff) + SURROGATE_TRAIL_FIRST); - } - ui++; - } - return ui; -} - -unsigned int UTF32FromUTF8(const char *s, unsigned int len, unsigned int *tbuf, unsigned int tlen) { - unsigned int ui=0; - const unsigned char *us = reinterpret_cast(s); - unsigned int i=0; - while ((i= 1) && (ch < 0x80 + 0x40 + 0x20)) { - value = (ch & 0x1F) << 6; - ch = us[i++]; - value += ch & 0x7F; - } else if (((len-i) >= 2) && (ch < 0x80 + 0x40 + 0x20 + 0x10)) { - value = (ch & 0xF) << 12; - ch = us[i++]; - value += (ch & 0x7F) << 6; - ch = us[i++]; - value += ch & 0x7F; - } else if ((len-i) >= 3) { - value = (ch & 0x7) << 18; - ch = us[i++]; - value += (ch & 0x3F) << 12; - ch = us[i++]; - value += (ch & 0x3F) << 6; - ch = us[i++]; - value += ch & 0x3F; - } - tbuf[ui] = value; - ui++; - } - return ui; -} - -unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf) { - if (val < SUPPLEMENTAL_PLANE_FIRST) { - tbuf[0] = static_cast(val); - return 1; - } else { - tbuf[0] = static_cast(((val - SUPPLEMENTAL_PLANE_FIRST) >> 10) + SURROGATE_LEAD_FIRST); - tbuf[1] = static_cast((val & 0x3ff) + SURROGATE_TRAIL_FIRST); - return 2; - } -} - -int UTF8BytesOfLead[256]; -static bool initialisedBytesOfLead = false; - -static int BytesFromLead(int leadByte) { - if (leadByte < 0xC2) { - // Single byte or invalid - return 1; - } else if (leadByte < 0xE0) { - return 2; - } else if (leadByte < 0xF0) { - return 3; - } else if (leadByte < 0xF5) { - return 4; - } else { - // Characters longer than 4 bytes not possible in current UTF-8 - return 1; - } -} - -void UTF8BytesOfLeadInitialise() { - if (!initialisedBytesOfLead) { - for (int i=0; i<256; i++) { - UTF8BytesOfLead[i] = BytesFromLead(i); - } - initialisedBytesOfLead = true; - } -} - -// Return both the width of the first character in the string and a status -// saying whether it is valid or invalid. -// Most invalid sequences return a width of 1 so are treated as isolated bytes but -// the non-characters *FFFE, *FFFF and FDD0 .. FDEF return 3 or 4 as they can be -// reasonably treated as code points in some circumstances. They will, however, -// not have associated glyphs. -int UTF8Classify(const unsigned char *us, int len) { - // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - if (*us < 0x80) { - // Single bytes easy - return 1; - } else if (*us > 0xf4) { - // Characters longer than 4 bytes not possible in current UTF-8 - return UTF8MaskInvalid | 1; - } else if (*us >= 0xf0) { - // 4 bytes - if (len < 4) - return UTF8MaskInvalid | 1; - if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2]) && UTF8IsTrailByte(us[3])) { - if (((us[1] & 0xf) == 0xf) && (us[2] == 0xbf) && ((us[3] == 0xbe) || (us[3] == 0xbf))) { - // *FFFE or *FFFF non-character - return UTF8MaskInvalid | 4; - } - if (*us == 0xf4) { - // Check if encoding a value beyond the last Unicode character 10FFFF - if (us[1] > 0x8f) { - return UTF8MaskInvalid | 1; - } else if (us[1] == 0x8f) { - if (us[2] > 0xbf) { - return UTF8MaskInvalid | 1; - } else if (us[2] == 0xbf) { - if (us[3] > 0xbf) { - return UTF8MaskInvalid | 1; - } - } - } - } else if ((*us == 0xf0) && ((us[1] & 0xf0) == 0x80)) { - // Overlong - return UTF8MaskInvalid | 1; - } - return 4; - } else { - return UTF8MaskInvalid | 1; - } - } else if (*us >= 0xe0) { - // 3 bytes - if (len < 3) - return UTF8MaskInvalid | 1; - if (UTF8IsTrailByte(us[1]) && UTF8IsTrailByte(us[2])) { - if ((*us == 0xe0) && ((us[1] & 0xe0) == 0x80)) { - // Overlong - return UTF8MaskInvalid | 1; - } - if ((*us == 0xed) && ((us[1] & 0xe0) == 0xa0)) { - // Surrogate - return UTF8MaskInvalid | 1; - } - if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbe)) { - // U+FFFE non-character - 3 bytes long - return UTF8MaskInvalid | 3; - } - if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbf)) { - // U+FFFF non-character - 3 bytes long - return UTF8MaskInvalid | 3; - } - if ((*us == 0xef) && (us[1] == 0xb7) && (((us[2] & 0xf0) == 0x90) || ((us[2] & 0xf0) == 0xa0))) { - // U+FDD0 .. U+FDEF - return UTF8MaskInvalid | 3; - } - return 3; - } else { - return UTF8MaskInvalid | 1; - } - } else if (*us >= 0xc2) { - // 2 bytes - if (len < 2) - return UTF8MaskInvalid | 1; - if (UTF8IsTrailByte(us[1])) { - return 2; - } else { - return UTF8MaskInvalid | 1; - } - } else { - // 0xc0 .. 0xc1 is overlong encoding - // 0x80 .. 0xbf is trail byte - return UTF8MaskInvalid | 1; - } -} - -int UTF8DrawBytes(const unsigned char *us, int len) { - int utf8StatusNext = UTF8Classify(us, len); - return (utf8StatusNext & UTF8MaskInvalid) ? 1 : (utf8StatusNext & UTF8MaskWidth); -} - -#ifdef SCI_NAMESPACE -} -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/UniConversion.h b/qrenderdoc/3rdparty/scintilla/src/UniConversion.h deleted file mode 100644 index aeb13f0c2..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/UniConversion.h +++ /dev/null @@ -1,72 +0,0 @@ -// Scintilla source code edit control -/** @file UniConversion.h - ** Functions to handle UTF-8 and UTF-16 strings. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef UNICONVERSION_H -#define UNICONVERSION_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -const int UTF8MaxBytes = 4; - -const int unicodeReplacementChar = 0xFFFD; - -unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen); -void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len); -unsigned int UTF8CharLength(unsigned char ch); -size_t UTF16Length(const char *s, size_t len); -size_t UTF16FromUTF8(const char *s, size_t len, wchar_t *tbuf, size_t tlen); -unsigned int UTF32FromUTF8(const char *s, unsigned int len, unsigned int *tbuf, unsigned int tlen); -unsigned int UTF16FromUTF32Character(unsigned int val, wchar_t *tbuf); - -extern int UTF8BytesOfLead[256]; -void UTF8BytesOfLeadInitialise(); - -inline bool UTF8IsTrailByte(int ch) { - return (ch >= 0x80) && (ch < 0xc0); -} - -inline bool UTF8IsAscii(int ch) { - return ch < 0x80; -} - -enum { UTF8MaskWidth=0x7, UTF8MaskInvalid=0x8 }; -int UTF8Classify(const unsigned char *us, int len); - -// Similar to UTF8Classify but returns a length of 1 for invalid bytes -// instead of setting the invalid flag -int UTF8DrawBytes(const unsigned char *us, int len); - -// Line separator is U+2028 \xe2\x80\xa8 -// Paragraph separator is U+2029 \xe2\x80\xa9 -const int UTF8SeparatorLength = 3; -inline bool UTF8IsSeparator(const unsigned char *us) { - return (us[0] == 0xe2) && (us[1] == 0x80) && ((us[2] == 0xa8) || (us[2] == 0xa9)); -} - -// NEL is U+0085 \xc2\x85 -const int UTF8NELLength = 2; -inline bool UTF8IsNEL(const unsigned char *us) { - return (us[0] == 0xc2) && (us[1] == 0x85); -} - -enum { SURROGATE_LEAD_FIRST = 0xD800 }; -enum { SURROGATE_LEAD_LAST = 0xDBFF }; -enum { SURROGATE_TRAIL_FIRST = 0xDC00 }; -enum { SURROGATE_TRAIL_LAST = 0xDFFF }; -enum { SUPPLEMENTAL_PLANE_FIRST = 0x10000 }; - -inline unsigned int UTF16CharLength(wchar_t uch) { - return ((uch >= SURROGATE_LEAD_FIRST) && (uch <= SURROGATE_LEAD_LAST)) ? 2 : 1; -} - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/UnicodeFromUTF8.h b/qrenderdoc/3rdparty/scintilla/src/UnicodeFromUTF8.h deleted file mode 100644 index ae66cb0a9..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/UnicodeFromUTF8.h +++ /dev/null @@ -1,32 +0,0 @@ -// Scintilla source code edit control -/** @file UnicodeFromUTF8.h - ** Lexer infrastructure. - **/ -// Copyright 2013 by Neil Hodgson -// This file is in the public domain. - -#ifndef UNICODEFROMUTF8_H -#define UNICODEFROMUTF8_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -inline int UnicodeFromUTF8(const unsigned char *us) { - if (us[0] < 0xC2) { - return us[0]; - } else if (us[0] < 0xE0) { - return ((us[0] & 0x1F) << 6) + (us[1] & 0x3F); - } else if (us[0] < 0xF0) { - return ((us[0] & 0xF) << 12) + ((us[1] & 0x3F) << 6) + (us[2] & 0x3F); - } else if (us[0] < 0xF5) { - return ((us[0] & 0x7) << 18) + ((us[1] & 0x3F) << 12) + ((us[2] & 0x3F) << 6) + (us[3] & 0x3F); - } - return us[0]; -} - -#ifdef SCI_NAMESPACE -} -#endif - -#endif diff --git a/qrenderdoc/3rdparty/scintilla/src/ViewStyle.cxx b/qrenderdoc/3rdparty/scintilla/src/ViewStyle.cxx deleted file mode 100644 index b694a62e3..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ViewStyle.cxx +++ /dev/null @@ -1,623 +0,0 @@ -// Scintilla source code edit control -/** @file ViewStyle.cxx - ** Store information on how the document is to be viewed. - **/ -// Copyright 1998-2003 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#include -#include - -#include -#include -#include - -#include "Platform.h" - -#include "Scintilla.h" -#include "Position.h" -#include "SplitVector.h" -#include "Partitioning.h" -#include "RunStyles.h" -#include "Indicator.h" -#include "XPM.h" -#include "LineMarker.h" -#include "Style.h" -#include "ViewStyle.h" - -#ifdef SCI_NAMESPACE -using namespace Scintilla; -#endif - -MarginStyle::MarginStyle() : - style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) { -} - -// A list of the fontnames - avoids wasting space in each style -FontNames::FontNames() { -} - -FontNames::~FontNames() { - Clear(); -} - -void FontNames::Clear() { - for (std::vector::const_iterator it=names.begin(); it != names.end(); ++it) { - delete []*it; - } - names.clear(); -} - -const char *FontNames::Save(const char *name) { - if (!name) - return 0; - - for (std::vector::const_iterator it=names.begin(); it != names.end(); ++it) { - if (strcmp(*it, name) == 0) { - return *it; - } - } - const size_t lenName = strlen(name) + 1; - char *nameSave = new char[lenName]; - memcpy(nameSave, name, lenName); - names.push_back(nameSave); - return nameSave; -} - -FontRealised::FontRealised() { -} - -FontRealised::~FontRealised() { - font.Release(); -} - -void FontRealised::Realise(Surface &surface, int zoomLevel, int technology, const FontSpecification &fs) { - PLATFORM_ASSERT(fs.fontName); - sizeZoomed = fs.size + zoomLevel * SC_FONT_SIZE_MULTIPLIER; - if (sizeZoomed <= 2 * SC_FONT_SIZE_MULTIPLIER) // Hangs if sizeZoomed <= 1 - sizeZoomed = 2 * SC_FONT_SIZE_MULTIPLIER; - - float deviceHeight = static_cast(surface.DeviceHeightFont(sizeZoomed)); - FontParameters fp(fs.fontName, deviceHeight / SC_FONT_SIZE_MULTIPLIER, fs.weight, fs.italic, fs.extraFontFlag, technology, fs.characterSet); - font.Create(fp); - - ascent = static_cast(surface.Ascent(font)); - descent = static_cast(surface.Descent(font)); - aveCharWidth = surface.AverageCharWidth(font); - spaceWidth = surface.WidthChar(font, ' '); -} - -ViewStyle::ViewStyle() { - Init(); -} - -ViewStyle::ViewStyle(const ViewStyle &source) { - Init(source.styles.size()); - for (unsigned int sty=0; stysecond; - } - fonts.clear(); -} - -void ViewStyle::CalculateMarginWidthAndMask() { - fixedColumnWidth = marginInside ? leftMarginWidth : 0; - maskInLine = 0xffffffff; - int maskDefinedMarkers = 0; - for (size_t margin = 0; margin < ms.size(); margin++) { - fixedColumnWidth += ms[margin].width; - if (ms[margin].width > 0) - maskInLine &= ~ms[margin].mask; - maskDefinedMarkers |= ms[margin].mask; - } - maskDrawInText = 0; - for (int markBit = 0; markBit < 32; markBit++) { - const int maskBit = 1 << markBit; - switch (markers[markBit].markType) { - case SC_MARK_EMPTY: - maskInLine &= ~maskBit; - break; - case SC_MARK_BACKGROUND: - case SC_MARK_UNDERLINE: - maskInLine &= ~maskBit; - maskDrawInText |= maskDefinedMarkers & maskBit; - break; - } - } -} - -void ViewStyle::Init(size_t stylesSize_) { - AllocStyles(stylesSize_); - nextExtendedStyle = 256; - fontNames.Clear(); - ResetDefaultStyle(); - - // There are no image markers by default, so no need for calling CalcLargestMarkerHeight() - largestMarkerHeight = 0; - - indicators[0] = Indicator(INDIC_SQUIGGLE, ColourDesired(0, 0x7f, 0)); - indicators[1] = Indicator(INDIC_TT, ColourDesired(0, 0, 0xff)); - indicators[2] = Indicator(INDIC_PLAIN, ColourDesired(0xff, 0, 0)); - - technology = SC_TECHNOLOGY_DEFAULT; - indicatorsDynamic = 0; - indicatorsSetFore = 0; - lineHeight = 1; - lineOverlap = 0; - maxAscent = 1; - maxDescent = 1; - aveCharWidth = 8; - spaceWidth = 8; - tabWidth = spaceWidth * 8; - - selColours.fore = ColourOptional(ColourDesired(0xff, 0, 0)); - selColours.back = ColourOptional(ColourDesired(0xc0, 0xc0, 0xc0), true); - selAdditionalForeground = ColourDesired(0xff, 0, 0); - selAdditionalBackground = ColourDesired(0xd7, 0xd7, 0xd7); - selBackground2 = ColourDesired(0xb0, 0xb0, 0xb0); - selAlpha = SC_ALPHA_NOALPHA; - selAdditionalAlpha = SC_ALPHA_NOALPHA; - selEOLFilled = false; - - foldmarginColour = ColourOptional(ColourDesired(0xff, 0, 0)); - foldmarginHighlightColour = ColourOptional(ColourDesired(0xc0, 0xc0, 0xc0)); - - whitespaceColours.fore = ColourOptional(); - whitespaceColours.back = ColourOptional(ColourDesired(0xff, 0xff, 0xff)); - controlCharSymbol = 0; /* Draw the control characters */ - controlCharWidth = 0; - selbar = Platform::Chrome(); - selbarlight = Platform::ChromeHighlight(); - styles[STYLE_LINENUMBER].fore = ColourDesired(0, 0, 0); - styles[STYLE_LINENUMBER].back = Platform::Chrome(); - caretcolour = ColourDesired(0, 0, 0); - additionalCaretColour = ColourDesired(0x7f, 0x7f, 0x7f); - showCaretLineBackground = false; - alwaysShowCaretLineBackground = false; - caretLineBackground = ColourDesired(0xff, 0xff, 0); - caretLineAlpha = SC_ALPHA_NOALPHA; - caretStyle = CARETSTYLE_LINE; - caretWidth = 1; - someStylesProtected = false; - someStylesForceCase = false; - - hotspotColours.fore = ColourOptional(ColourDesired(0, 0, 0xff)); - hotspotColours.back = ColourOptional(ColourDesired(0xff, 0xff, 0xff)); - hotspotUnderline = true; - hotspotSingleLine = true; - - leftMarginWidth = 1; - rightMarginWidth = 1; - ms.resize(SC_MAX_MARGIN + 1); - ms[0].style = SC_MARGIN_NUMBER; - ms[0].width = 0; - ms[0].mask = 0; - ms[1].style = SC_MARGIN_SYMBOL; - ms[1].width = 16; - ms[1].mask = ~SC_MASK_FOLDERS; - ms[2].style = SC_MARGIN_SYMBOL; - ms[2].width = 0; - ms[2].mask = 0; - marginInside = true; - CalculateMarginWidthAndMask(); - textStart = marginInside ? fixedColumnWidth : leftMarginWidth; - zoomLevel = 0; - viewWhitespace = wsInvisible; - tabDrawMode = tdLongArrow; - whitespaceSize = 1; - viewIndentationGuides = ivNone; - viewEOL = false; - extraFontFlag = 0; - extraAscent = 0; - extraDescent = 0; - marginStyleOffset = 0; - annotationVisible = ANNOTATION_HIDDEN; - annotationStyleOffset = 0; - braceHighlightIndicatorSet = false; - braceHighlightIndicator = 0; - braceBadLightIndicatorSet = false; - braceBadLightIndicator = 0; - - edgeState = EDGE_NONE; - theEdge = EdgeProperties(0, ColourDesired(0xc0, 0xc0, 0xc0)); - - marginNumberPadding = 3; - ctrlCharPadding = 3; // +3 For a blank on front and rounded edge each side - lastSegItalicsOffset = 2; - - wrapState = eWrapNone; - wrapVisualFlags = 0; - wrapVisualFlagsLocation = 0; - wrapVisualStartIndent = 0; - wrapIndentMode = SC_WRAPINDENT_FIXED; -} - -void ViewStyle::Refresh(Surface &surface, int tabInChars) { - for (FontMap::iterator it = fonts.begin(); it != fonts.end(); ++it) { - delete it->second; - } - fonts.clear(); - - selbar = Platform::Chrome(); - selbarlight = Platform::ChromeHighlight(); - - for (unsigned int i=0; isecond->Realise(surface, zoomLevel, technology, it->first); - } - - for (unsigned int k=0; kfont, *fr); - } - indicatorsDynamic = 0; - indicatorsSetFore = 0; - for (int ind = 0; ind <= INDIC_MAX; ind++) { - if (indicators[ind].IsDynamic()) - indicatorsDynamic++; - if (indicators[ind].OverridesTextFore()) - indicatorsSetFore++; - } - maxAscent = 1; - maxDescent = 1; - FindMaxAscentDescent(); - maxAscent += extraAscent; - maxDescent += extraDescent; - lineHeight = maxAscent + maxDescent; - lineOverlap = lineHeight / 10; - if (lineOverlap < 2) - lineOverlap = 2; - if (lineOverlap > lineHeight) - lineOverlap = lineHeight; - - someStylesProtected = false; - someStylesForceCase = false; - for (unsigned int l=0; l= 32) { - controlCharWidth = surface.WidthChar(styles[STYLE_CONTROLCHAR].font, static_cast(controlCharSymbol)); - } - - CalculateMarginWidthAndMask(); - textStart = marginInside ? fixedColumnWidth : leftMarginWidth; -} - -void ViewStyle::ReleaseAllExtendedStyles() { - nextExtendedStyle = 256; -} - -int ViewStyle::AllocateExtendedStyles(int numberStyles) { - int startRange = static_cast(nextExtendedStyle); - nextExtendedStyle += numberStyles; - EnsureStyle(nextExtendedStyle); - for (size_t i=startRange; i= styles.size()) { - AllocStyles(index+1); - } -} - -void ViewStyle::ResetDefaultStyle() { - styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0), - ColourDesired(0xff,0xff,0xff), - Platform::DefaultFontSize() * SC_FONT_SIZE_MULTIPLIER, fontNames.Save(Platform::DefaultFont()), - SC_CHARSET_DEFAULT, - SC_WEIGHT_NORMAL, false, false, false, Style::caseMixed, true, true, false); -} - -void ViewStyle::ClearStyles() { - // Reset all styles to be like the default style - for (unsigned int i=0; i= x) && (pt.x < x + ms[i].width)) - margin = static_cast(i); - x += ms[i].width; - } - return margin; -} - -bool ViewStyle::ValidStyle(size_t styleIndex) const { - return styleIndex < styles.size(); -} - -void ViewStyle::CalcLargestMarkerHeight() { - largestMarkerHeight = 0; - for (int m = 0; m <= MARKER_MAX; ++m) { - switch (markers[m].markType) { - case SC_MARK_PIXMAP: - if (markers[m].pxpm && markers[m].pxpm->GetHeight() > largestMarkerHeight) - largestMarkerHeight = markers[m].pxpm->GetHeight(); - break; - case SC_MARK_RGBAIMAGE: - if (markers[m].image && markers[m].image->GetHeight() > largestMarkerHeight) - largestMarkerHeight = markers[m].image->GetHeight(); - break; - } - } -} - -// See if something overrides the line background color: Either if caret is on the line -// and background color is set for that, or if a marker is defined that forces its background -// color onto the line, or if a marker is defined but has no selection margin in which to -// display itself (as long as it's not an SC_MARK_EMPTY marker). These are checked in order -// with the earlier taking precedence. When multiple markers cause background override, -// the color for the highest numbered one is used. -ColourOptional ViewStyle::Background(int marksOfLine, bool caretActive, bool lineContainsCaret) const { - ColourOptional background; - if ((caretActive || alwaysShowCaretLineBackground) && showCaretLineBackground && (caretLineAlpha == SC_ALPHA_NOALPHA) && lineContainsCaret) { - background = ColourOptional(caretLineBackground, true); - } - if (!background.isSet && marksOfLine) { - int marks = marksOfLine; - for (int markBit = 0; (markBit < 32) && marks; markBit++) { - if ((marks & 1) && (markers[markBit].markType == SC_MARK_BACKGROUND) && - (markers[markBit].alpha == SC_ALPHA_NOALPHA)) { - background = ColourOptional(markers[markBit].back, true); - } - marks >>= 1; - } - } - if (!background.isSet && maskInLine) { - int marksMasked = marksOfLine & maskInLine; - if (marksMasked) { - for (int markBit = 0; (markBit < 32) && marksMasked; markBit++) { - if ((marksMasked & 1) && - (markers[markBit].alpha == SC_ALPHA_NOALPHA)) { - background = ColourOptional(markers[markBit].back, true); - } - marksMasked >>= 1; - } - } - } - return background; -} - -bool ViewStyle::SelectionBackgroundDrawn() const { - return selColours.back.isSet && - ((selAlpha == SC_ALPHA_NOALPHA) || (selAdditionalAlpha == SC_ALPHA_NOALPHA)); -} - -bool ViewStyle::WhitespaceBackgroundDrawn() const { - return (viewWhitespace != wsInvisible) && (whitespaceColours.back.isSet); -} - -bool ViewStyle::WhiteSpaceVisible(bool inIndent) const { - return (!inIndent && viewWhitespace == wsVisibleAfterIndent) || - (inIndent && viewWhitespace == wsVisibleOnlyInIndent) || - viewWhitespace == wsVisibleAlways; -} - -ColourDesired ViewStyle::WrapColour() const { - if (whitespaceColours.fore.isSet) - return whitespaceColours.fore; - else - return styles[STYLE_DEFAULT].fore; -} - -bool ViewStyle::SetWrapState(int wrapState_) { - WrapMode wrapStateWanted; - switch (wrapState_) { - case SC_WRAP_WORD: - wrapStateWanted = eWrapWord; - break; - case SC_WRAP_CHAR: - wrapStateWanted = eWrapChar; - break; - case SC_WRAP_WHITESPACE: - wrapStateWanted = eWrapWhitespace; - break; - default: - wrapStateWanted = eWrapNone; - break; - } - bool changed = wrapState != wrapStateWanted; - wrapState = wrapStateWanted; - return changed; -} - -bool ViewStyle::SetWrapVisualFlags(int wrapVisualFlags_) { - bool changed = wrapVisualFlags != wrapVisualFlags_; - wrapVisualFlags = wrapVisualFlags_; - return changed; -} - -bool ViewStyle::SetWrapVisualFlagsLocation(int wrapVisualFlagsLocation_) { - bool changed = wrapVisualFlagsLocation != wrapVisualFlagsLocation_; - wrapVisualFlagsLocation = wrapVisualFlagsLocation_; - return changed; -} - -bool ViewStyle::SetWrapVisualStartIndent(int wrapVisualStartIndent_) { - bool changed = wrapVisualStartIndent != wrapVisualStartIndent_; - wrapVisualStartIndent = wrapVisualStartIndent_; - return changed; -} - -bool ViewStyle::SetWrapIndentMode(int wrapIndentMode_) { - bool changed = wrapIndentMode != wrapIndentMode_; - wrapIndentMode = wrapIndentMode_; - return changed; -} - -void ViewStyle::AllocStyles(size_t sizeNew) { - size_t i=styles.size(); - styles.resize(sizeNew); - if (styles.size() > STYLE_DEFAULT) { - for (; isecond; - FontMap::iterator it = fonts.find(fs); - if (it != fonts.end()) { - // Should always reach here since map was just set for all styles - return it->second; - } - return 0; -} - -void ViewStyle::FindMaxAscentDescent() { - for (FontMap::const_iterator it = fonts.begin(); it != fonts.end(); ++it) { - if (maxAscent < it->second->ascent) - maxAscent = it->second->ascent; - if (maxDescent < it->second->descent) - maxDescent = it->second->descent; - } -} diff --git a/qrenderdoc/3rdparty/scintilla/src/ViewStyle.h b/qrenderdoc/3rdparty/scintilla/src/ViewStyle.h deleted file mode 100644 index 1a876f85e..000000000 --- a/qrenderdoc/3rdparty/scintilla/src/ViewStyle.h +++ /dev/null @@ -1,219 +0,0 @@ -// Scintilla source code edit control -/** @file ViewStyle.h - ** Store information on how the document is to be viewed. - **/ -// Copyright 1998-2001 by Neil Hodgson -// The License.txt file describes the conditions under which this software may be distributed. - -#ifndef VIEWSTYLE_H -#define VIEWSTYLE_H - -#ifdef SCI_NAMESPACE -namespace Scintilla { -#endif - -/** - */ -class MarginStyle { -public: - int style; - ColourDesired back; - int width; - int mask; - bool sensitive; - int cursor; - MarginStyle(); -}; - -/** - */ -class FontNames { -private: - std::vector names; - - // Private so FontNames objects can not be copied - FontNames(const FontNames &); -public: - FontNames(); - ~FontNames(); - void Clear(); - const char *Save(const char *name); -}; - -class FontRealised : public FontMeasurements { - // Private so FontRealised objects can not be copied - FontRealised(const FontRealised &); - FontRealised &operator=(const FontRealised &); -public: - Font font; - FontRealised(); - virtual ~FontRealised(); - void Realise(Surface &surface, int zoomLevel, int technology, const FontSpecification &fs); -}; - -enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth}; - -enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2, wsVisibleOnlyInIndent=3}; - -enum TabDrawMode {tdLongArrow=0, tdStrikeOut=1}; - -typedef std::map FontMap; - -enum WrapMode { eWrapNone, eWrapWord, eWrapChar, eWrapWhitespace }; - -class ColourOptional : public ColourDesired { -public: - bool isSet; - ColourOptional(ColourDesired colour_=ColourDesired(0,0,0), bool isSet_=false) : ColourDesired(colour_), isSet(isSet_) { - } - ColourOptional(uptr_t wParam, sptr_t lParam) : ColourDesired(static_cast(lParam)), isSet(wParam != 0) { - } -}; - -struct ForeBackColours { - ColourOptional fore; - ColourOptional back; -}; - -struct EdgeProperties { - int column; - ColourDesired colour; - EdgeProperties(int column_ = 0, ColourDesired colour_ = ColourDesired(0)) : - column(column_), colour(colour_) { - } - EdgeProperties(uptr_t wParam, sptr_t lParam) : - column(static_cast(wParam)), colour(static_cast(lParam)) { - } -}; - -/** - */ -class ViewStyle { - FontNames fontNames; - FontMap fonts; -public: - std::vector - - xml.writeEndElement(); // - } - - { - xml.writeStartElement(lit("body")); - - xml.writeStartElement(lit("h1")); - xml.writeCharacters(title); - xml.writeEndElement(); - - xml.writeStartElement(lit("h3")); - { - QString context = tr("Frame %1").arg(m_Ctx.FrameInfo().frameNumber); - - const DrawcallDescription *draw = m_Ctx.CurDrawcall(); - - QList drawstack; - const DrawcallDescription *parent = m_Ctx.GetDrawcall(draw->parent); - while(parent) - { - drawstack.push_front(parent); - parent = m_Ctx.GetDrawcall(parent->parent); - } - - for(const DrawcallDescription *d : drawstack) - { - context += QFormatStr(" > %1").arg(ToQStr(d->name)); - } - - context += QFormatStr(" => %1").arg(ToQStr(draw->name)); - - xml.writeCharacters(context); - } - xml.writeEndElement(); // - } - - // body is open - - return xmlptr; - } - - RDDialog::critical( - this, tr("Error exporting pipeline state"), - tr("Couldn't open path %1 for write.\n%2").arg(filename).arg(f->errorString())); - - delete f; - - return NULL; - } - else - { - RDDialog::critical(this, tr("Invalid directory"), - tr("Cannot find target directory to save to")); - return NULL; - } - } - - return NULL; -} - -void PipelineStateViewer::exportHTMLTable(QXmlStreamWriter &xml, const QStringList &cols, - const QList &rows) -{ - xml.writeStartElement(lit("table")); - - { - xml.writeStartElement(lit("thead")); - xml.writeStartElement(lit("tr")); - - for(const QString &col : cols) - { - xml.writeStartElement(lit("th")); - xml.writeCharacters(col); - xml.writeEndElement(); - } - - xml.writeEndElement(); - xml.writeEndElement(); - } - - { - xml.writeStartElement(lit("tbody")); - - if(rows.isEmpty()) - { - xml.writeStartElement(lit("tr")); - - for(int i = 0; i < cols.count(); i++) - { - xml.writeStartElement(lit("td")); - xml.writeCharacters(lit("-")); - xml.writeEndElement(); - } - - xml.writeEndElement(); - } - else - { - for(const QVariantList &row : rows) - { - xml.writeStartElement(lit("tr")); - - for(const QVariant &el : row) - { - xml.writeStartElement(lit("td")); - - QMetaType::Type type = (QMetaType::Type)el.type(); - - if(type == QMetaType::Bool) - xml.writeCharacters(el.toBool() ? tr("True") : tr("False")); - else - xml.writeCharacters(el.toString()); - - xml.writeEndElement(); - } - - xml.writeEndElement(); - } - } - - xml.writeEndElement(); - } - - xml.writeEndElement(); -} - -void PipelineStateViewer::exportHTMLTable(QXmlStreamWriter &xml, const QStringList &cols, - const QVariantList &row) -{ - exportHTMLTable(xml, cols, QList({row})); -} - -void PipelineStateViewer::endHTMLExport(QXmlStreamWriter *xml) -{ - xml->writeEndElement(); // - - xml->writeEndElement(); // - - xml->writeEndDocument(); - - // delete the file the writer was writing to - QFile *f = qobject_cast(xml->device()); - delete f; - - delete xml; -} - -void PipelineStateViewer::setTopologyDiagram(QLabel *diagram, Topology topo) -{ - int idx = qMin((int)topo, (int)Topology::PatchList); - - if(m_TopoPixmaps[idx].isNull()) - { - QSvgRenderer svg; - switch(topo) - { - case Topology::PointList: svg.load(lit(":/topologies/topo_pointlist.svg")); break; - case Topology::LineList: svg.load(lit(":/topologies/topo_linelist.svg")); break; - case Topology::LineStrip: svg.load(lit(":/topologies/topo_linestrip.svg")); break; - case Topology::TriangleList: svg.load(lit(":/topologies/topo_trilist.svg")); break; - case Topology::TriangleStrip: svg.load(lit(":/topologies/topo_tristrip.svg")); break; - case Topology::LineList_Adj: svg.load(lit(":/topologies/topo_linelist_adj.svg")); break; - case Topology::LineStrip_Adj: svg.load(lit(":/topologies/topo_linestrip_adj.svg")); break; - case Topology::TriangleList_Adj: svg.load(lit(":/topologies/topo_trilist_adj.svg")); break; - case Topology::TriangleStrip_Adj: svg.load(lit(":/topologies/topo_tristrip_adj.svg")); break; - default: svg.load(lit(":/topologies/topo_patch.svg")); break; - } - - QRect rect = svg.viewBox(); - - QImage im(rect.size() * diagram->devicePixelRatio(), QImage::Format_ARGB32); - - im.fill(QColor(0, 0, 0, 0)); - - QPainter p(&im); - - svg.render(&p); - - // convert the colors - black maps to Text (foreground) and white maps to Base (background) - QColor white = diagram->palette().color(QPalette::Active, QPalette::Base); - QColor black = diagram->palette().color(QPalette::Active, QPalette::Text); - - const float br = black.redF(); - const float bg = black.greenF(); - const float bb = black.blueF(); - - const float wr = white.redF(); - const float wg = white.greenF(); - const float wb = white.blueF(); - - for(int y = 0; y < im.height(); y++) - { - QRgb *line = (QRgb *)im.scanLine(y); - - for(int x = 0; x < im.width(); x++) - { - // delta of 0 is black, delta of 255 is white - const float delta = float(qRed(*line)); - const float bd = 255.0f - delta; - const float wd = delta; - - const int r = int(br * bd + wr * wd); - const int g = int(bg * bd + wg * wd); - const int b = int(bb * bd + wb * wd); - - *line = qRgba(r, g, b, qAlpha(*line)); - - line++; - } - } - - m_TopoPixmaps[idx] = QPixmap::fromImage(im); - m_TopoPixmaps[idx].setDevicePixelRatio(diagram->devicePixelRatioF()); - } - - diagram->setPixmap(m_TopoPixmaps[idx]); -} - -void PipelineStateViewer::setMeshViewPixmap(RDLabel *meshView) -{ - QImage meshIcon = Pixmaps::wireframe_mesh(meshView->devicePixelRatio()).toImage(); - QImage colSwapped(meshIcon.size(), QImage::Format_ARGB32); - colSwapped.fill(meshView->palette().color(QPalette::WindowText)); - - for(int y = 0; y < meshIcon.height(); y++) - { - const QRgb *in = (const QRgb *)meshIcon.constScanLine(y); - QRgb *out = (QRgb *)colSwapped.scanLine(y); - - for(int x = 0; x < meshIcon.width(); x++) - { - *out = qRgba(qRed(*out), qGreen(*out), qBlue(*out), qAlpha(*in)); - - in++; - out++; - } - } - - QPixmap p = QPixmap::fromImage(colSwapped); - p.setDevicePixelRatio(meshView->devicePixelRatioF()); - - meshView->setPixmap(p); - meshView->setPreserveAspectRatio(true); - - QPalette pal = meshView->palette(); - pal.setColor(QPalette::Shadow, pal.color(QPalette::Window).darker(120)); - meshView->setPalette(pal); - meshView->setBackgroundRole(QPalette::Window); - meshView->setMouseTracking(true); - - QObject::connect(meshView, &RDLabel::mouseMoved, [meshView](QMouseEvent *) { - meshView->setBackgroundRole(QPalette::Shadow); - meshView->setAutoFillBackground(true); - }); - QObject::connect(meshView, &RDLabel::leave, [meshView]() { - meshView->setBackgroundRole(QPalette::Window); - meshView->setAutoFillBackground(false); - }); -} - -bool PipelineStateViewer::PrepareShaderEditing(const ShaderReflection *shaderDetails, - QString &entryFunc, QStringMap &files, - QString &mainfile) -{ - if(!shaderDetails->DebugInfo.files.empty()) - { - entryFunc = ToQStr(shaderDetails->EntryPoint); - - QStringList uniqueFiles; - - for(auto &s : shaderDetails->DebugInfo.files) - { - QString filename = ToQStr(s.first); - if(uniqueFiles.contains(filename.toLower())) - { - qWarning() << lit("Duplicate full filename") << ToQStr(s.first); - continue; - } - uniqueFiles.push_back(filename.toLower()); - - files[filename] = ToQStr(s.second); - } - - mainfile = ToQStr(shaderDetails->DebugInfo.files[0].first); - - return true; - } - - return false; -} - -void PipelineStateViewer::MakeShaderVariablesHLSL(bool cbufferContents, - const rdctype::array &vars, - QString &struct_contents, QString &struct_defs) -{ - for(const ShaderConstant &v : vars) - { - if(v.type.members.count > 0) - { - QString def = lit("struct %1 {\n").arg(ToQStr(v.type.descriptor.name)); - - if(!struct_defs.contains(def)) - { - QString contents; - MakeShaderVariablesHLSL(false, v.type.members, contents, struct_defs); - - struct_defs += def + contents + lit("};\n\n"); - } - } - - struct_contents += lit("\t%1 %2").arg(ToQStr(v.type.descriptor.name)).arg(ToQStr(v.name)); - - char comp = 'x'; - if(v.reg.comp == 1) - comp = 'y'; - if(v.reg.comp == 2) - comp = 'z'; - if(v.reg.comp == 3) - comp = 'w'; - - if(cbufferContents) - struct_contents += lit(" : packoffset(c%1.%2);").arg(v.reg.vec).arg(QLatin1Char(comp)); - else - struct_contents += lit(";"); - - struct_contents += lit("\n"); - } -} - -QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDetails, - const QString &entryFunc) -{ - QString hlsl = lit("// No HLSL available - function stub generated\n\n"); - - const QString textureDim[ENUM_ARRAY_SIZE(TextureDim)] = { - lit("Unknown"), lit("Buffer"), lit("Texture1D"), lit("Texture1DArray"), - lit("Texture2D"), lit("TextureRect"), lit("Texture2DArray"), lit("Texture2DMS"), - lit("Texture2DMSArray"), lit("Texture3D"), lit("TextureCube"), lit("TextureCubeArray"), - }; - - for(int i = 0; i < 2; i++) - { - const rdctype::array &resources = - (i == 0 ? shaderDetails->ReadOnlyResources : shaderDetails->ReadWriteResources); - for(const ShaderResource &res : resources) - { - if(res.IsSampler) - { - hlsl += lit("//SamplerComparisonState %1 : register(s%2); // can't disambiguate\n" - "SamplerState %1 : register(s%2); // can't disambiguate\n") - .arg(ToQStr(res.name)) - .arg(res.bindPoint); - } - else - { - char regChar = 't'; - - if(i == 1) - { - hlsl += lit("RW"); - regChar = 'u'; - } - - if(res.IsTexture) - { - hlsl += lit("%1<%2> %3 : register(%4%5);\n") - .arg(textureDim[(size_t)res.resType]) - .arg(ToQStr(res.variableType.descriptor.name)) - .arg(ToQStr(res.name)) - .arg(QLatin1Char(regChar)) - .arg(res.bindPoint); - } - else - { - if(res.variableType.descriptor.rows > 1) - hlsl += lit("Structured"); - - hlsl += lit("Buffer<%1> %2 : register(%3%4);\n") - .arg(ToQStr(res.variableType.descriptor.name)) - .arg(ToQStr(res.name)) - .arg(QLatin1Char(regChar)) - .arg(res.bindPoint); - } - } - } - } - - hlsl += lit("\n\n"); - - QString cbuffers; - - int cbufIdx = 0; - for(const ConstantBlock &cbuf : shaderDetails->ConstantBlocks) - { - if(cbuf.name.count > 0 && cbuf.variables.count > 0) - { - QString cbufName = ToQStr(cbuf.name); - if(cbufName == lit("$Globals")) - cbufName = lit("_Globals"); - cbuffers += lit("cbuffer %1 : register(b%2) {\n").arg(cbufName).arg(cbuf.bindPoint); - MakeShaderVariablesHLSL(true, cbuf.variables, cbuffers, hlsl); - cbuffers += lit("};\n\n"); - } - cbufIdx++; - } - - hlsl += cbuffers; - - hlsl += lit("\n\n"); - - hlsl += lit("struct InputStruct {\n"); - for(const SigParameter &sig : shaderDetails->InputSig) - hlsl += lit("\t%1 %2 : %3;\n") - .arg(TypeString(sig)) - .arg(sig.varName.count > 0 ? ToQStr(sig.varName) : lit("param%1").arg(sig.regIndex)) - .arg(D3DSemanticString(sig)); - hlsl += lit("};\n\n"); - - hlsl += lit("struct OutputStruct {\n"); - for(const SigParameter &sig : shaderDetails->OutputSig) - hlsl += lit("\t%1 %2 : %3;\n") - .arg(TypeString(sig)) - .arg(sig.varName.count > 0 ? ToQStr(sig.varName) : lit("param%1").arg(sig.regIndex)) - .arg(D3DSemanticString(sig)); - hlsl += lit("};\n\n"); - - hlsl += lit("OutputStruct %1(in InputStruct IN)\n" - "{\n" - "\tOutputStruct OUT = (OutputStruct)0;\n" - "\n" - "\t// ...\n" - "\n" - "\treturn OUT;\n" - "}\n") - .arg(entryFunc); - - return hlsl; -} - -void PipelineStateViewer::EditShader(ShaderStage shaderType, ResourceId id, - const ShaderReflection *shaderDetails, const QString &entryFunc, - const QStringMap &files, const QString &mainfile) -{ - IShaderViewer *sv = m_Ctx.EditShader( - false, entryFunc, files, - // save callback - [entryFunc, mainfile, shaderType, id, shaderDetails]( - ICaptureContext *ctx, IShaderViewer *viewer, const QStringMap &updatedfiles) { - QString compileSource = updatedfiles[mainfile]; - - // try and match up #includes against the files that we have. This isn't always - // possible as fxc only seems to include the source for files if something in - // that file was included in the compiled output. So you might end up with - // dangling #includes - we just have to ignore them - int offs = compileSource.indexOf(lit("#include")); - - while(offs >= 0) - { - // search back to ensure this is a valid #include (ie. not in a comment). - // Must only see whitespace before, then a newline. - int ws = qMax(0, offs - 1); - while(ws >= 0 && - (compileSource[ws] == QLatin1Char(' ') || compileSource[ws] == QLatin1Char('\t'))) - ws--; - - // not valid? jump to next. - if(ws > 0 && compileSource[ws] != QLatin1Char('\n')) - { - offs = compileSource.indexOf(lit("#include"), offs + 1); - continue; - } - - int start = ws + 1; - - bool tail = true; - - int lineEnd = compileSource.indexOf(QLatin1Char('\n'), start + 1); - if(lineEnd == -1) - { - lineEnd = compileSource.length(); - tail = false; - } - - ws = offs + sizeof("#include") - 1; - while(compileSource[ws] == QLatin1Char(' ') || compileSource[ws] == QLatin1Char('\t')) - ws++; - - QString line = compileSource.mid(offs, lineEnd - offs + 1); - - if(compileSource[ws] != QLatin1Char('<') && compileSource[ws] != QLatin1Char('"')) - { - viewer->ShowErrors(lit("Invalid #include directive found:\r\n") + line); - return; - } - - // find matching char, either <> or ""; - int end = compileSource.indexOf( - compileSource[ws] == QLatin1Char('"') ? QLatin1Char('"') : QLatin1Char('>'), ws + 1); - - if(end == -1) - { - viewer->ShowErrors(lit("Invalid #include directive found:\r\n") + line); - return; - } - - QString fname = compileSource.mid(ws + 1, end - ws - 1); - - QString fileText; - - // look for exact match first - if(updatedfiles.contains(fname)) - { - fileText = updatedfiles[fname]; - } - else - { - QString search = QFileInfo(fname).fileName(); - // if not, try and find the same filename (this is not proper include handling!) - for(const QString &k : updatedfiles.keys()) - { - if(QFileInfo(k).fileName().compare(search, Qt::CaseInsensitive) == 0) - { - fileText = updatedfiles[k]; - break; - } - } - - if(fileText.isEmpty()) - fileText = QFormatStr("// Can't find file %1\n").arg(fname); - } - - compileSource = compileSource.left(offs) + lit("\n\n") + fileText + lit("\n\n") + - (tail ? compileSource.mid(lineEnd + 1) : QString()); - - // need to start searching from the beginning - wasteful but allows nested includes to - // work - offs = compileSource.indexOf(lit("#include")); - } - - if(updatedfiles.contains(lit("@cmdline"))) - compileSource = updatedfiles[lit("@cmdline")] + lit("\n\n") + compileSource; - - // invoke off to the ReplayController to replace the log's shader - // with our edited one - ctx->Replay().AsyncInvoke([ctx, entryFunc, compileSource, shaderType, id, shaderDetails, - viewer](IReplayController *r) { - rdctype::str errs; - - uint flags = shaderDetails->DebugInfo.compileFlags; - - ResourceId from = id; - ResourceId to; - - std::tie(to, errs) = r->BuildTargetShader( - entryFunc.toUtf8().data(), compileSource.toUtf8().data(), flags, shaderType); - - GUIInvoke::call([viewer, errs]() { viewer->ShowErrors(ToQStr(errs)); }); - if(to == ResourceId()) - { - r->RemoveReplacement(from); - GUIInvoke::call([ctx]() { ctx->RefreshStatus(); }); - } - else - { - r->ReplaceResource(from, to); - GUIInvoke::call([ctx]() { ctx->RefreshStatus(); }); - } - }); - }, - - // Close Callback - [id](ICaptureContext *ctx) { - // remove the replacement on close (we could make this more sophisticated if there - // was a place to control replaced resources/shaders). - ctx->Replay().AsyncInvoke([ctx, id](IReplayController *r) { - r->RemoveReplacement(id); - GUIInvoke::call([ctx] { ctx->RefreshStatus(); }); - }); - }); - - m_Ctx.AddDockWindow(sv->Widget(), DockReference::AddTo, this); -} - -bool PipelineStateViewer::SaveShaderFile(const ShaderReflection *shader) -{ - if(!shader) - return false; - - QString filter; - - if(m_Ctx.CurPipelineState().IsLogD3D11() || m_Ctx.CurPipelineState().IsLogD3D12()) - { - filter = tr("DXBC Shader files (*.dxbc)"); - } - else if(m_Ctx.CurPipelineState().IsLogGL()) - { - filter = tr("GLSL files (*.glsl)"); - } - else if(m_Ctx.CurPipelineState().IsLogVK()) - { - filter = tr("SPIR-V files (*.spv)"); - } - - QString filename = RDDialog::getSaveFileName(this, tr("Save Shader As"), QString(), filter); - - if(!filename.isEmpty()) - { - QDir dirinfo = QFileInfo(filename).dir(); - if(dirinfo.exists()) - { - QFile f(filename); - if(f.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - f.write((const char *)shader->RawBytes.elems, (qint64)shader->RawBytes.count); - } - else - { - RDDialog::critical( - this, tr("Error saving shader"), - tr("Couldn't open path %1 for write.\n%2").arg(filename).arg(f.errorString())); - return false; - } - } - else - { - RDDialog::critical(this, tr("Invalid directory"), - tr("Cannot find target directory to save to")); - return false; - } - } - - return true; -} diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h deleted file mode 100644 index 416cb46cb..000000000 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -namespace Ui -{ -class PipelineStateViewer; -} - -class QXmlStreamWriter; - -class RDLabel; - -class D3D11PipelineStateViewer; -class D3D12PipelineStateViewer; -class GLPipelineStateViewer; -class VulkanPipelineStateViewer; - -class PipelineStateViewer : public QFrame, public IPipelineStateViewer, public ILogViewer -{ - Q_OBJECT - - Q_PROPERTY(QVariant persistData READ persistData WRITE setPersistData DESIGNABLE false SCRIPTABLE false) - -public: - explicit PipelineStateViewer(ICaptureContext &ctx, QWidget *parent = 0); - ~PipelineStateViewer(); - - // IPipelineStateViewer - QWidget *Widget() override { return this; } - bool SaveShaderFile(const ShaderReflection *shader) override; - - // ILogViewerForm - void OnLogfileLoaded() override; - void OnLogfileClosed() override; - void OnSelectedEventChanged(uint32_t eventID) override {} - void OnEventChanged(uint32_t eventID) override; - - QVariant persistData(); - - void setPersistData(const QVariant &persistData); - - bool PrepareShaderEditing(const ShaderReflection *shaderDetails, QString &entryFunc, - QStringMap &files, QString &mainfile); - QString GenerateHLSLStub(const ShaderReflection *shaderDetails, const QString &entryFunc); - void EditShader(ShaderStage shaderType, ResourceId id, const ShaderReflection *shaderDetails, - const QString &entryFunc, const QStringMap &files, const QString &mainfile); - - void setTopologyDiagram(QLabel *diagram, Topology topo); - void setMeshViewPixmap(RDLabel *meshView); - - QXmlStreamWriter *beginHTMLExport(); - void exportHTMLTable(QXmlStreamWriter &xml, const QStringList &cols, - const QList &rows); - void exportHTMLTable(QXmlStreamWriter &xml, const QStringList &cols, const QVariantList &row); - void endHTMLExport(QXmlStreamWriter *xml); - -private: - Ui::PipelineStateViewer *ui; - ICaptureContext &m_Ctx; - - void MakeShaderVariablesHLSL(bool cbufferContents, const rdctype::array &vars, - QString &struct_contents, QString &struct_defs); - - QPixmap m_TopoPixmaps[(int)Topology::PatchList + 1]; - - void setToD3D11(); - void setToD3D12(); - void setToGL(); - void setToVulkan(); - void reset(); - - QString GetCurrentAPI(); - - D3D11PipelineStateViewer *m_D3D11; - D3D12PipelineStateViewer *m_D3D12; - GLPipelineStateViewer *m_GL; - VulkanPipelineStateViewer *m_Vulkan; - ILogViewer *m_Current; -}; diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.ui deleted file mode 100644 index 59bf84763..000000000 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.ui +++ /dev/null @@ -1,36 +0,0 @@ - - - PipelineStateViewer - - - - 0 - 0 - 400 - 300 - - - - Pipeline State - - - - 0 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp deleted file mode 100644 index 70af8ab12..000000000 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ /dev/null @@ -1,3268 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "VulkanPipelineStateViewer.h" -#include -#include -#include -#include -#include "3rdparty/toolwindowmanager/ToolWindowManager.h" -#include "Code/Resources.h" -#include "Widgets/Extended/RDHeaderView.h" -#include "PipelineStateViewer.h" -#include "ui_VulkanPipelineStateViewer.h" - -Q_DECLARE_METATYPE(ResourceId); -Q_DECLARE_METATYPE(SamplerData); - -struct VulkanVBIBTag -{ - VulkanVBIBTag() { offset = 0; } - VulkanVBIBTag(ResourceId i, uint64_t offs) - { - id = i; - offset = offs; - } - - ResourceId id; - uint64_t offset; -}; - -Q_DECLARE_METATYPE(VulkanVBIBTag); - -struct VulkanCBufferTag -{ - VulkanCBufferTag() { slotIdx = arrayIdx = 0; } - VulkanCBufferTag(uint32_t s, uint32_t i) - { - slotIdx = s; - arrayIdx = i; - } - uint32_t slotIdx; - uint32_t arrayIdx; -}; - -Q_DECLARE_METATYPE(VulkanCBufferTag); - -struct VulkanBufferTag -{ - VulkanBufferTag() - { - rwRes = false; - bindPoint = 0; - offset = size = 0; - } - VulkanBufferTag(bool rw, uint32_t b, ResourceId id, uint64_t offs, uint64_t sz) - { - rwRes = rw; - bindPoint = b; - ID = id; - offset = offs; - size = sz; - } - bool rwRes; - uint32_t bindPoint; - ResourceId ID; - uint64_t offset; - uint64_t size; -}; - -Q_DECLARE_METATYPE(VulkanBufferTag); - -VulkanPipelineStateViewer::VulkanPipelineStateViewer(ICaptureContext &ctx, - PipelineStateViewer &common, QWidget *parent) - : QFrame(parent), ui(new Ui::VulkanPipelineStateViewer), m_Ctx(ctx), m_Common(common) -{ - ui->setupUi(this); - - const QIcon &action = Icons::action(); - const QIcon &action_hover = Icons::action_hover(); - - RDLabel *shaderLabels[] = { - ui->vsShader, ui->tcsShader, ui->tesShader, ui->gsShader, ui->fsShader, ui->csShader, - }; - - QToolButton *viewButtons[] = { - ui->vsShaderViewButton, ui->tcsShaderViewButton, ui->tesShaderViewButton, - ui->gsShaderViewButton, ui->fsShaderViewButton, ui->csShaderViewButton, - }; - - QToolButton *editButtons[] = { - ui->vsShaderEditButton, ui->tcsShaderEditButton, ui->tesShaderEditButton, - ui->gsShaderEditButton, ui->fsShaderEditButton, ui->csShaderEditButton, - }; - - QToolButton *saveButtons[] = { - ui->vsShaderSaveButton, ui->tcsShaderSaveButton, ui->tesShaderSaveButton, - ui->gsShaderSaveButton, ui->fsShaderSaveButton, ui->csShaderSaveButton, - }; - - RDTreeWidget *resources[] = { - ui->vsResources, ui->tcsResources, ui->tesResources, - ui->gsResources, ui->fsResources, ui->csResources, - }; - - RDTreeWidget *ubos[] = { - ui->vsUBOs, ui->tcsUBOs, ui->tesUBOs, ui->gsUBOs, ui->fsUBOs, ui->csUBOs, - }; - - for(QToolButton *b : viewButtons) - QObject::connect(b, &QToolButton::clicked, this, &VulkanPipelineStateViewer::shaderView_clicked); - - for(RDLabel *b : shaderLabels) - { - QObject::connect(b, &RDLabel::clicked, this, &VulkanPipelineStateViewer::shaderLabel_clicked); - b->setAutoFillBackground(true); - b->setBackgroundRole(QPalette::ToolTipBase); - b->setForegroundRole(QPalette::ToolTipText); - } - - for(QToolButton *b : editButtons) - QObject::connect(b, &QToolButton::clicked, this, &VulkanPipelineStateViewer::shaderEdit_clicked); - - for(QToolButton *b : saveButtons) - QObject::connect(b, &QToolButton::clicked, this, &VulkanPipelineStateViewer::shaderSave_clicked); - - QObject::connect(ui->viAttrs, &RDTreeWidget::leave, this, &VulkanPipelineStateViewer::vertex_leave); - QObject::connect(ui->viBuffers, &RDTreeWidget::leave, this, - &VulkanPipelineStateViewer::vertex_leave); - - QObject::connect(ui->framebuffer, &RDTreeWidget::itemActivated, this, - &VulkanPipelineStateViewer::resource_itemActivated); - - for(RDTreeWidget *res : resources) - QObject::connect(res, &RDTreeWidget::itemActivated, this, - &VulkanPipelineStateViewer::resource_itemActivated); - - for(RDTreeWidget *ubo : ubos) - QObject::connect(ubo, &RDTreeWidget::itemActivated, this, - &VulkanPipelineStateViewer::ubo_itemActivated); - - addGridLines(ui->rasterizerGridLayout, palette().color(QPalette::WindowText)); - addGridLines(ui->MSAAGridLayout, palette().color(QPalette::WindowText)); - addGridLines(ui->blendStateGridLayout, palette().color(QPalette::WindowText)); - addGridLines(ui->depthStateGridLayout, palette().color(QPalette::WindowText)); - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->viAttrs->setHeader(header); - - ui->viAttrs->setColumns({tr("Index"), tr("Name"), tr("Location"), tr("Binding"), tr("Format"), - tr("Offset"), tr("Go")}); - header->setColumnStretchHints({1, 4, 1, 2, 3, 2, -1}); - - ui->viAttrs->setHoverIconColumn(6, action, action_hover); - ui->viAttrs->setClearSelectionOnFocusLoss(true); - ui->viAttrs->setInstantTooltips(true); - } - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->viBuffers->setHeader(header); - - ui->viBuffers->setColumns({tr("Slot"), tr("Buffer"), tr("Rate"), tr("Offset"), tr("Stride"), - tr("Byte Length"), tr("Go")}); - header->setColumnStretchHints({1, 4, 2, 2, 2, 3, -1}); - - ui->viBuffers->setHoverIconColumn(6, action, action_hover); - ui->viBuffers->setClearSelectionOnFocusLoss(true); - ui->viBuffers->setInstantTooltips(true); - } - - for(RDTreeWidget *res : resources) - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - res->setHeader(header); - - res->setColumns({QString(), tr("Set"), tr("Binding"), tr("Type"), tr("Resource"), - tr("Contents"), tr("cont.d"), tr("Go")}); - header->setColumnStretchHints({-1, -1, 2, 2, 2, 4, 4, -1}); - - res->setHoverIconColumn(7, action, action_hover); - res->setClearSelectionOnFocusLoss(true); - res->setInstantTooltips(true); - } - - for(RDTreeWidget *ubo : ubos) - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ubo->setHeader(header); - - ubo->setColumns({QString(), tr("Set"), tr("Binding"), tr("Buffer"), tr("Byte Range"), - tr("Size"), tr("Go")}); - header->setColumnStretchHints({-1, -1, 2, 4, 3, 3, -1}); - - ubo->setHoverIconColumn(6, action, action_hover); - ubo->setClearSelectionOnFocusLoss(true); - ubo->setInstantTooltips(true); - } - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->viewports->setHeader(header); - - ui->viewports->setColumns( - {tr("Slot"), tr("X"), tr("Y"), tr("Width"), tr("Height"), tr("MinDepth"), tr("MaxDepth")}); - header->setColumnStretchHints({-1, -1, -1, -1, -1, -1, 1}); - header->setMinimumSectionSize(40); - - ui->viewports->setClearSelectionOnFocusLoss(true); - ui->viewports->setInstantTooltips(true); - } - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->scissors->setHeader(header); - - ui->scissors->setColumns({tr("Slot"), tr("X"), tr("Y"), tr("Width"), tr("Height")}); - header->setColumnStretchHints({-1, -1, -1, -1, 1}); - header->setMinimumSectionSize(40); - - ui->scissors->setClearSelectionOnFocusLoss(true); - ui->scissors->setInstantTooltips(true); - } - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->framebuffer->setHeader(header); - - ui->framebuffer->setColumns({tr("Slot"), tr("Resource"), tr("Type"), tr("Width"), tr("Height"), - tr("Depth"), tr("Array Size"), tr("Format"), tr("Go")}); - header->setColumnStretchHints({2, 4, 2, 1, 1, 1, 1, 3, -1}); - - ui->framebuffer->setHoverIconColumn(8, action, action_hover); - ui->framebuffer->setClearSelectionOnFocusLoss(true); - ui->framebuffer->setInstantTooltips(true); - } - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->blends->setHeader(header); - - ui->blends->setColumns({tr("Slot"), tr("Enabled"), tr("Col Src"), tr("Col Dst"), tr("Col Op"), - tr("Alpha Src"), tr("Alpha Dst"), tr("Alpha Op"), tr("Write Mask")}); - header->setColumnStretchHints({-1, 1, 2, 2, 2, 2, 2, 2, 1}); - - ui->blends->setClearSelectionOnFocusLoss(true); - ui->blends->setInstantTooltips(true); - } - - { - RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); - ui->stencils->setHeader(header); - - ui->stencils->setColumns({tr("Face"), tr("Func"), tr("Fail Op"), tr("Depth Fail Op"), - tr("Pass Op"), tr("Write Mask"), tr("Comp Mask"), tr("Ref")}); - header->setColumnStretchHints({1, 2, 2, 2, 2, 1, 1, 1}); - - ui->stencils->setClearSelectionOnFocusLoss(true); - ui->stencils->setInstantTooltips(true); - } - - // this is often changed just because we're changing some tab in the designer. - ui->stagesTabs->setCurrentIndex(0); - - ui->stagesTabs->tabBar()->setVisible(false); - - ui->pipeFlow->setStages( - { - lit("VTX"), lit("VS"), lit("TCS"), lit("TES"), lit("GS"), lit("RS"), lit("FS"), lit("FB"), - lit("CS"), - }, - { - tr("Vertex Input"), tr("Vertex Shader"), tr("Tess. Control Shader"), - tr("Tess. Eval. Shader"), tr("Geometry Shader"), tr("Rasterizer"), tr("Fragment Shader"), - tr("Framebuffer Output"), tr("Compute Shader"), - }); - - ui->pipeFlow->setIsolatedStage(8); // compute shader isolated - - ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true}); - - m_Common.setMeshViewPixmap(ui->meshView); - - ui->viAttrs->setFont(Formatter::PreferredFont()); - ui->viBuffers->setFont(Formatter::PreferredFont()); - ui->vsShader->setFont(Formatter::PreferredFont()); - ui->vsResources->setFont(Formatter::PreferredFont()); - ui->vsUBOs->setFont(Formatter::PreferredFont()); - ui->gsShader->setFont(Formatter::PreferredFont()); - ui->gsResources->setFont(Formatter::PreferredFont()); - ui->gsUBOs->setFont(Formatter::PreferredFont()); - ui->tcsShader->setFont(Formatter::PreferredFont()); - ui->tcsResources->setFont(Formatter::PreferredFont()); - ui->tcsUBOs->setFont(Formatter::PreferredFont()); - ui->tesShader->setFont(Formatter::PreferredFont()); - ui->tesResources->setFont(Formatter::PreferredFont()); - ui->tesUBOs->setFont(Formatter::PreferredFont()); - ui->fsShader->setFont(Formatter::PreferredFont()); - ui->fsResources->setFont(Formatter::PreferredFont()); - ui->fsUBOs->setFont(Formatter::PreferredFont()); - ui->csShader->setFont(Formatter::PreferredFont()); - ui->csResources->setFont(Formatter::PreferredFont()); - ui->csUBOs->setFont(Formatter::PreferredFont()); - ui->viewports->setFont(Formatter::PreferredFont()); - ui->scissors->setFont(Formatter::PreferredFont()); - ui->framebuffer->setFont(Formatter::PreferredFont()); - ui->blends->setFont(Formatter::PreferredFont()); - - // reset everything back to defaults - clearState(); -} - -VulkanPipelineStateViewer::~VulkanPipelineStateViewer() -{ - delete ui; -} - -void VulkanPipelineStateViewer::OnLogfileLoaded() -{ - OnEventChanged(m_Ctx.CurEvent()); -} - -void VulkanPipelineStateViewer::OnLogfileClosed() -{ - ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true}); - - clearState(); -} - -void VulkanPipelineStateViewer::OnEventChanged(uint32_t eventID) -{ - setState(); -} - -void VulkanPipelineStateViewer::on_showDisabled_toggled(bool checked) -{ - setState(); -} - -void VulkanPipelineStateViewer::on_showEmpty_toggled(bool checked) -{ - setState(); -} - -void VulkanPipelineStateViewer::setInactiveRow(RDTreeWidgetItem *node) -{ - node->setItalic(true); -} - -void VulkanPipelineStateViewer::setEmptyRow(RDTreeWidgetItem *node) -{ - node->setBackgroundColor(QColor(255, 70, 70)); - node->setForegroundColor(QColor(0, 0, 0)); -} - -template -void VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const bindType &view, - TextureDescription *tex) -{ - if(tex == NULL) - return; - - QString text; - - bool viewdetails = false; - - { - for(const VKPipe::ImageData &im : m_Ctx.CurVulkanPipelineState().images) - { - if(im.image == tex->ID) - { - text += tr("Texture is in the '%1' layout\n\n").arg(ToQStr(im.layouts[0].name)); - break; - } - } - - if(view.viewfmt != tex->format) - { - text += tr("The texture is format %1, the view treats it as %2.\n") - .arg(ToQStr(tex->format.strname)) - .arg(ToQStr(view.viewfmt.strname)); - - viewdetails = true; - } - - if(tex->mips > 1 && (tex->mips != view.numMip || view.baseMip > 0)) - { - if(view.numMip == 1) - text += - tr("The texture has %1 mips, the view covers mip %2.\n").arg(tex->mips).arg(view.baseMip); - else - text += tr("The texture has %1 mips, the view covers mips %2-%3.\n") - .arg(tex->mips) - .arg(view.baseMip) - .arg(view.baseMip + view.numMip - 1); - - viewdetails = true; - } - - if(tex->arraysize > 1 && (tex->arraysize != view.numLayer || view.baseLayer > 0)) - { - if(view.numLayer == 1) - text += tr("The texture has %1 array slices, the view covers slice %2.\n") - .arg(tex->arraysize) - .arg(view.baseLayer); - else - text += tr("The texture has %1 array slices, the view covers slices %2-%3.\n") - .arg(tex->arraysize) - .arg(view.baseLayer) - .arg(view.baseLayer + view.numLayer); - - viewdetails = true; - } - } - - text = text.trimmed(); - - node->setToolTip(text); - - if(viewdetails) - { - node->setBackgroundColor(QColor(127, 255, 212)); - node->setForegroundColor(QColor(0, 0, 0)); - } -} - -template -void VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const bindType &view, - BufferDescription *buf) -{ - if(buf == NULL) - return; - - QString text; - - if(view.offset > 0 || view.size < buf->length) - { - text += tr("The view covers bytes %1-%2.\nThe buffer is %3 bytes in length.") - .arg(view.offset) - .arg(view.offset + view.size) - .arg(buf->length); - } - else - { - return; - } - - node->setToolTip(text); - node->setBackgroundColor(QColor(127, 255, 212)); - node->setForegroundColor(QColor(0, 0, 0)); -} - -bool VulkanPipelineStateViewer::showNode(bool usedSlot, bool filledSlot) -{ - const bool showDisabled = ui->showDisabled->isChecked(); - const bool showEmpty = ui->showEmpty->isChecked(); - - // show if it's referenced by the shader - regardless of empty or not - if(usedSlot) - return true; - - // it's bound, but not referenced, and we have "show disabled" - if(showDisabled && !usedSlot && filledSlot) - return true; - - // it's empty, and we have "show empty" - if(showEmpty && !filledSlot) - return true; - - return false; -} - -const VKPipe::Shader *VulkanPipelineStateViewer::stageForSender(QWidget *widget) -{ - if(!m_Ctx.LogLoaded()) - return NULL; - - while(widget) - { - if(widget == ui->stagesTabs->widget(0)) - return &m_Ctx.CurVulkanPipelineState().m_VS; - if(widget == ui->stagesTabs->widget(1)) - return &m_Ctx.CurVulkanPipelineState().m_VS; - if(widget == ui->stagesTabs->widget(2)) - return &m_Ctx.CurVulkanPipelineState().m_TCS; - if(widget == ui->stagesTabs->widget(3)) - return &m_Ctx.CurVulkanPipelineState().m_TES; - if(widget == ui->stagesTabs->widget(4)) - return &m_Ctx.CurVulkanPipelineState().m_GS; - if(widget == ui->stagesTabs->widget(5)) - return &m_Ctx.CurVulkanPipelineState().m_FS; - if(widget == ui->stagesTabs->widget(6)) - return &m_Ctx.CurVulkanPipelineState().m_FS; - if(widget == ui->stagesTabs->widget(7)) - return &m_Ctx.CurVulkanPipelineState().m_FS; - if(widget == ui->stagesTabs->widget(8)) - return &m_Ctx.CurVulkanPipelineState().m_CS; - - widget = widget->parentWidget(); - } - - qCritical() << "Unrecognised control calling event handler"; - - return NULL; -} - -void VulkanPipelineStateViewer::clearShaderState(QLabel *shader, RDTreeWidget *resources, - RDTreeWidget *cbuffers) -{ - shader->setText(tr("Unbound Shader")); - resources->clear(); - cbuffers->clear(); -} - -void VulkanPipelineStateViewer::clearState() -{ - m_VBNodes.clear(); - m_BindNodes.clear(); - - ui->viAttrs->clear(); - ui->viBuffers->clear(); - ui->topology->setText(QString()); - ui->primRestart->setVisible(false); - ui->topologyDiagram->setPixmap(QPixmap()); - - clearShaderState(ui->vsShader, ui->vsResources, ui->vsUBOs); - clearShaderState(ui->tcsShader, ui->tcsResources, ui->tcsUBOs); - clearShaderState(ui->tesShader, ui->tesResources, ui->tesUBOs); - clearShaderState(ui->gsShader, ui->gsResources, ui->gsUBOs); - clearShaderState(ui->fsShader, ui->fsResources, ui->fsUBOs); - clearShaderState(ui->csShader, ui->csResources, ui->csUBOs); - - const QPixmap &tick = Pixmaps::tick(this); - - ui->fillMode->setText(tr("Solid", "Fill Mode")); - ui->cullMode->setText(tr("Front", "Cull Mode")); - ui->frontCCW->setPixmap(tick); - - ui->depthBias->setText(lit("0.0")); - ui->depthBiasClamp->setText(lit("0.0")); - ui->slopeScaledBias->setText(lit("0.0")); - - ui->depthClamp->setPixmap(tick); - ui->rasterizerDiscard->setPixmap(tick); - ui->lineWidth->setText(lit("1.0")); - - ui->sampleCount->setText(lit("1")); - ui->sampleShading->setPixmap(tick); - ui->minSampleShading->setText(lit("0.0")); - ui->sampleMask->setText(lit("FFFFFFFF")); - - ui->viewports->clear(); - ui->scissors->clear(); - - ui->framebuffer->clear(); - ui->blends->clear(); - - ui->blendFactor->setText(lit("0.00, 0.00, 0.00, 0.00")); - ui->logicOp->setText(lit("-")); - ui->alphaToOne->setPixmap(tick); - - ui->depthEnabled->setPixmap(tick); - ui->depthFunc->setText(lit("GREATER_EQUAL")); - ui->depthWrite->setPixmap(tick); - - ui->depthBounds->setText(lit("0.0-1.0")); - ui->depthBounds->setPixmap(QPixmap()); - - ui->stencils->clear(); -} - -QVariantList VulkanPipelineStateViewer::makeSampler(const QString &bindset, const QString &slotname, - const VKPipe::BindingElement &descriptor) -{ - QString addressing; - QString addPrefix; - QString addVal; - - QString filter; - - QString addr[] = {ToQStr(descriptor.AddressU), ToQStr(descriptor.AddressV), - ToQStr(descriptor.AddressW)}; - - // arrange like either UVW: WRAP or UV: WRAP, W: CLAMP - for(int a = 0; a < 3; a++) - { - QString prefix = QString(QLatin1Char("UVW"[a])); - - if(a == 0 || addr[a] == addr[a - 1]) - { - addPrefix += prefix; - } - else - { - addressing += addPrefix + lit(": ") + addVal + lit(", "); - - addPrefix = prefix; - } - addVal = addr[a]; - } - - addressing += addPrefix + lit(": ") + addVal; - - if(descriptor.UseBorder()) - addressing += QFormatStr(" <%1, %2, %3, %4>") - .arg(descriptor.BorderColor[0]) - .arg(descriptor.BorderColor[1]) - .arg(descriptor.BorderColor[2]) - .arg(descriptor.BorderColor[3]); - - if(descriptor.unnormalized) - addressing += lit(" (Un-norm)"); - - filter = ToQStr(descriptor.Filter); - - if(descriptor.maxAniso > 1.0f) - filter += lit(" Aniso %1x").arg(descriptor.maxAniso); - - if(descriptor.Filter.func == FilterFunc::Comparison) - filter += QFormatStr(" (%1)").arg(ToQStr(descriptor.comparison)); - else if(descriptor.Filter.func != FilterFunc::Normal) - filter += QFormatStr(" (%1)").arg(ToQStr(descriptor.Filter.func)); - - QString lod = - lit("LODs: %1 - %2") - .arg((descriptor.minlod == -FLT_MAX ? lit("0") : QString::number(descriptor.minlod))) - .arg((descriptor.maxlod == FLT_MAX ? lit("FLT_MAX") : QString::number(descriptor.maxlod))); - - if(descriptor.mipBias != 0.0f) - lod += lit(" Bias %1").arg(descriptor.mipBias); - - return {QString(), - bindset, - slotname, - descriptor.immutableSampler ? tr("Immutable Sampler") : tr("Sampler"), - ToQStr(descriptor.name), - addressing, - filter + lit(", ") + lod}; -} - -void VulkanPipelineStateViewer::addResourceRow(ShaderReflection *shaderDetails, - const VKPipe::Shader &stage, int bindset, int bind, - const VKPipe::Pipeline &pipe, RDTreeWidget *resources, - QMap &samplers) -{ - const ShaderResource *shaderRes = NULL; - const BindpointMap *bindMap = NULL; - - bool isrw = false; - uint bindPoint = 0; - - if(shaderDetails != NULL) - { - // we find the matching binding for this set/binding. - // The spec requires that there are no overlapping definitions, or if there are they have - // compatible types so we can just pick the first one we come across. - // The spec also doesn't require variables which are statically unused to have valid bindings, - // so they may be overlapping or possibly just defaulted to 0. - // Any variables with no binding declared at all were set to 0 and sorted to the end at - // reflection time, so we can just use a single algorithm to select the best candidate: - // - // 1. Search for matching bindset/bind resources. It doesn't matter which 'namespace' (sampler/ - // read-only/read-write) we search in, because if there's a conflict the behaviour is - // illegal and if there's no conflict we won't get any ambiguity. - // 2. If we find a match, select it for use. - // 3. If we find a second match, use it in preference only if the old one was !used, and the new - // one is used. - // - // This will make us select the best possible option - the first declared used resource - // at a particular binding, ignoring any unused resources at that binding before/after. Or if - // there's no used resource at all, the first declared unused resource (which will prefer - // resources with proper bindings over those without, as with the sorting mentioned above). - - for(int i = 0; i < shaderDetails->ReadOnlyResources.count; i++) - { - const ShaderResource &ro = shaderDetails->ReadOnlyResources[i]; - - if(stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bindset == bindset && - stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bind == bind) - { - // use this one either if we have no candidate, or the candidate we have is unused and this - // one is used - if(bindMap == NULL || - (!bindMap->used && stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].used)) - { - bindPoint = (uint)i; - shaderRes = &ro; - bindMap = &stage.BindpointMapping.ReadOnlyResources[ro.bindPoint]; - } - } - } - - for(int i = 0; i < shaderDetails->ReadWriteResources.count; i++) - { - const ShaderResource &rw = shaderDetails->ReadWriteResources[i]; - - if(stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bindset == bindset && - stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bind == bind) - { - // use this one either if we have no candidate, or the candidate we have is unused and this - // one is used - if(bindMap == NULL || - (!bindMap->used && stage.BindpointMapping.ReadWriteResources[rw.bindPoint].used)) - { - bindPoint = (uint)i; - isrw = true; - shaderRes = &rw; - bindMap = &stage.BindpointMapping.ReadWriteResources[rw.bindPoint]; - } - } - } - } - - const rdctype::array *slotBinds = NULL; - BindType bindType = BindType::Unknown; - ShaderStageMask stageBits = ShaderStageMask::Unknown; - - if(bindset < pipe.DescSets.count && bind < pipe.DescSets[bindset].bindings.count) - { - slotBinds = &pipe.DescSets[bindset].bindings[bind].binds; - bindType = pipe.DescSets[bindset].bindings[bind].type; - stageBits = pipe.DescSets[bindset].bindings[bind].stageFlags; - } - else - { - if(shaderRes->IsSampler) - bindType = BindType::Sampler; - else if(shaderRes->IsSampler && shaderRes->IsTexture) - bindType = BindType::ImageSampler; - else if(shaderRes->resType == TextureDim::Buffer) - bindType = BindType::ReadOnlyTBuffer; - else - bindType = BindType::ReadOnlyImage; - } - - bool usedSlot = bindMap != NULL && bindMap->used; - bool stageBitsIncluded = bool(stageBits & MaskForStage(stage.stage)); - - // skip descriptors that aren't for this shader stage - if(!usedSlot && !stageBitsIncluded) - return; - - if(bindType == BindType::ConstantBuffer) - return; - - // TODO - check compatibility between bindType and shaderRes.resType ? - - // consider it filled if any array element is filled - bool filledSlot = false; - for(int idx = 0; slotBinds != NULL && idx < slotBinds->count; idx++) - { - filledSlot |= (*slotBinds)[idx].res != ResourceId(); - if(bindType == BindType::Sampler || bindType == BindType::ImageSampler) - filledSlot |= (*slotBinds)[idx].sampler != ResourceId(); - } - - // if it's masked out by stage bits, act as if it's not filled, so it's marked in red - if(!stageBitsIncluded) - filledSlot = false; - - if(showNode(usedSlot, filledSlot)) - { - RDTreeWidgetItem *parentNode = resources->invisibleRootItem(); - - QString setname = QString::number(bindset); - - QString slotname = QString::number(bind); - if(shaderRes != NULL && shaderRes->name.count > 0) - slotname += lit(": ") + ToQStr(shaderRes->name); - - int arrayLength = 0; - if(slotBinds != NULL) - arrayLength = slotBinds->count; - else - arrayLength = (int)bindMap->arraySize; - - // for arrays, add a parent element that we add the real cbuffers below - if(arrayLength > 1) - { - RDTreeWidgetItem *node = - new RDTreeWidgetItem({QString(), setname, slotname, tr("Array[%1]").arg(arrayLength), - QString(), QString(), QString(), QString()}); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - - resources->addTopLevelItem(node); - - // show the tree column - resources->showColumn(0); - parentNode = node; - } - - for(int idx = 0; idx < arrayLength; idx++) - { - const VKPipe::BindingElement *descriptorBind = NULL; - if(slotBinds != NULL) - descriptorBind = &(*slotBinds)[idx]; - - if(arrayLength > 1) - { - if(shaderRes != NULL && shaderRes->name.count > 0) - slotname = QFormatStr("%1[%2]: %3").arg(bind).arg(idx).arg(ToQStr(shaderRes->name)); - else - slotname = QFormatStr("%1[%2]").arg(bind).arg(idx); - } - - bool isbuf = false; - uint32_t w = 1, h = 1, d = 1; - uint32_t a = 1; - uint32_t samples = 1; - uint64_t len = 0; - QString format = tr("Unknown"); - QString name = tr("Empty"); - TextureDim restype = TextureDim::Unknown; - QVariant tag; - - TextureDescription *tex = NULL; - BufferDescription *buf = NULL; - - uint64_t descriptorLen = descriptorBind ? descriptorBind->size : 0; - - if(filledSlot && descriptorBind != NULL) - { - name = tr("Object %1").arg(ToQStr(descriptorBind->res)); - - format = ToQStr(descriptorBind->viewfmt.strname); - - // check to see if it's a texture - tex = m_Ctx.GetTexture(descriptorBind->res); - if(tex) - { - w = tex->width; - h = tex->height; - d = tex->depth; - a = tex->arraysize; - name = ToQStr(tex->name); - restype = tex->resType; - samples = tex->msSamp; - - tag = QVariant::fromValue(descriptorBind->res); - } - - // if not a texture, it must be a buffer - buf = m_Ctx.GetBuffer(descriptorBind->res); - if(buf) - { - len = buf->length; - w = 0; - h = 0; - d = 0; - a = 0; - name = ToQStr(buf->name); - restype = TextureDim::Buffer; - - if(descriptorLen == UINT64_MAX) - descriptorLen = len - descriptorBind->offset; - - tag = QVariant::fromValue( - VulkanBufferTag(isrw, bindPoint, buf->ID, descriptorBind->offset, descriptorLen)); - - isbuf = true; - } - } - else - { - name = tr("Empty"); - format = lit("-"); - w = h = d = a = 0; - } - - RDTreeWidgetItem *node = NULL; - RDTreeWidgetItem *samplerNode = NULL; - - if(bindType == BindType::ReadWriteBuffer || bindType == BindType::ReadOnlyTBuffer || - bindType == BindType::ReadWriteTBuffer) - { - if(!isbuf) - { - node = new RDTreeWidgetItem({ - QString(), bindset, slotname, ToQStr(bindType), lit("-"), lit("-"), QString(), - }); - - setEmptyRow(node); - } - else - { - QString range = lit("-"); - if(descriptorBind != NULL) - range = QFormatStr("%1 - %2").arg(descriptorBind->offset).arg(descriptorLen); - - node = new RDTreeWidgetItem({ - QString(), bindset, slotname, ToQStr(bindType), name, tr("%1 bytes").arg(len), range, - }); - - node->setTag(tag); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - } - } - else if(bindType == BindType::Sampler) - { - if(descriptorBind == NULL || descriptorBind->sampler == ResourceId()) - { - node = new RDTreeWidgetItem({ - QString(), bindset, slotname, ToQStr(bindType), lit("-"), lit("-"), QString(), - }); - - setEmptyRow(node); - } - else - { - node = - new RDTreeWidgetItem(makeSampler(QString::number(bindset), slotname, *descriptorBind)); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - - SamplerData sampData; - sampData.node = node; - node->setTag(QVariant::fromValue(sampData)); - - if(!samplers.contains(descriptorBind->sampler)) - samplers.insert(descriptorBind->sampler, sampData); - } - } - else - { - if(descriptorBind == NULL || descriptorBind->res == ResourceId()) - { - node = new RDTreeWidgetItem({ - QString(), bindset, slotname, ToQStr(bindType), lit("-"), lit("-"), QString(), - }); - - setEmptyRow(node); - } - else - { - QString typeName = ToQStr(restype) + lit(" ") + ToQStr(bindType); - - QString dim; - - if(restype == TextureDim::Texture3D) - dim = QFormatStr("%1x%2x%3").arg(w).arg(h).arg(d); - else if(restype == TextureDim::Texture1D || restype == TextureDim::Texture1DArray) - dim = QString::number(w); - else - dim = QFormatStr("%1x%2").arg(w).arg(h); - - if(descriptorBind->swizzle[0] != TextureSwizzle::Red || - descriptorBind->swizzle[1] != TextureSwizzle::Green || - descriptorBind->swizzle[2] != TextureSwizzle::Blue || - descriptorBind->swizzle[3] != TextureSwizzle::Alpha) - { - format += tr(" swizzle[%1%2%3%4]") - .arg(ToQStr(descriptorBind->swizzle[0])) - .arg(ToQStr(descriptorBind->swizzle[1])) - .arg(ToQStr(descriptorBind->swizzle[2])) - .arg(ToQStr(descriptorBind->swizzle[3])); - } - - if(restype == TextureDim::Texture1DArray || restype == TextureDim::Texture2DArray || - restype == TextureDim::Texture2DMSArray || restype == TextureDim::TextureCubeArray) - { - dim += QFormatStr(" %1[%2]").arg(ToQStr(restype)).arg(a); - } - - if(restype == TextureDim::Texture2DMS || restype == TextureDim::Texture2DMSArray) - dim += QFormatStr(", %1x MSAA").arg(samples); - - node = new RDTreeWidgetItem({ - QString(), bindset, slotname, typeName, name, dim, format, - }); - - node->setTag(tag); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - } - - if(bindType == BindType::ImageSampler) - { - if(descriptorBind == NULL || descriptorBind->sampler == ResourceId()) - { - samplerNode = new RDTreeWidgetItem({ - QString(), bindset, slotname, ToQStr(bindType), lit("-"), lit("-"), QString(), - }); - - setEmptyRow(node); - } - else - { - if(!samplers.contains(descriptorBind->sampler)) - { - samplerNode = new RDTreeWidgetItem(makeSampler(QString(), QString(), *descriptorBind)); - - if(!filledSlot) - setEmptyRow(samplerNode); - - if(!usedSlot) - setInactiveRow(samplerNode); - - SamplerData sampData; - sampData.node = samplerNode; - samplerNode->setTag(QVariant::fromValue(sampData)); - - samplers.insert(descriptorBind->sampler, sampData); - } - - if(node != NULL) - { - m_CombinedImageSamplers[node] = samplers[descriptorBind->sampler].node; - samplers[descriptorBind->sampler].images.push_back(node); - } - } - } - } - - if(descriptorBind && tex) - setViewDetails(node, *descriptorBind, tex); - else if(descriptorBind && buf) - setViewDetails(node, *descriptorBind, buf); - - parentNode->addChild(node); - - if(samplerNode) - parentNode->addChild(samplerNode); - } - } -} - -void VulkanPipelineStateViewer::addConstantBlockRow(ShaderReflection *shaderDetails, - const VKPipe::Shader &stage, int bindset, - int bind, const VKPipe::Pipeline &pipe, - RDTreeWidget *ubos) -{ - const ConstantBlock *cblock = NULL; - const BindpointMap *bindMap = NULL; - - uint32_t slot = ~0U; - if(shaderDetails != NULL) - { - for(slot = 0; slot < (uint)shaderDetails->ConstantBlocks.count; slot++) - { - ConstantBlock cb = shaderDetails->ConstantBlocks[slot]; - if(stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bindset == bindset && - stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bind == bind) - { - cblock = &cb; - bindMap = &stage.BindpointMapping.ConstantBlocks[cb.bindPoint]; - break; - } - } - - if(slot >= (uint)shaderDetails->ConstantBlocks.count) - slot = ~0U; - } - - const rdctype::array *slotBinds = NULL; - BindType bindType = BindType::ConstantBuffer; - ShaderStageMask stageBits = ShaderStageMask::Unknown; - - if(bindset < pipe.DescSets.count && bind < pipe.DescSets[bindset].bindings.count) - { - slotBinds = &pipe.DescSets[bindset].bindings[bind].binds; - bindType = pipe.DescSets[bindset].bindings[bind].type; - stageBits = pipe.DescSets[bindset].bindings[bind].stageFlags; - } - - bool usedSlot = bindMap != NULL && bindMap->used; - bool stageBitsIncluded = bool(stageBits & MaskForStage(stage.stage)); - - // skip descriptors that aren't for this shader stage - if(!usedSlot && !stageBitsIncluded) - return; - - if(bindType != BindType::ConstantBuffer) - return; - - // consider it filled if any array element is filled (or it's push constants) - bool filledSlot = cblock != NULL && !cblock->bufferBacked; - for(int idx = 0; slotBinds != NULL && idx < slotBinds->count; idx++) - filledSlot |= (*slotBinds)[idx].res != ResourceId(); - - // if it's masked out by stage bits, act as if it's not filled, so it's marked in red - if(!stageBitsIncluded) - filledSlot = false; - - if(showNode(usedSlot, filledSlot)) - { - RDTreeWidgetItem *parentNode = ubos->invisibleRootItem(); - - QString setname = QString::number(bindset); - - QString slotname = QString::number(bind); - if(cblock != NULL && cblock->name.count > 0) - slotname += lit(": ") + ToQStr(cblock->name); - - int arrayLength = 0; - if(slotBinds != NULL) - arrayLength = slotBinds->count; - else - arrayLength = (int)bindMap->arraySize; - - // for arrays, add a parent element that we add the real cbuffers below - if(arrayLength > 1) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {QString(), setname, slotname, tr("Array[%1]").arg(arrayLength), QString(), QString()}); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - - parentNode = node; - - ubos->showColumn(0); - } - - for(int idx = 0; idx < arrayLength; idx++) - { - const VKPipe::BindingElement *descriptorBind = NULL; - if(slotBinds != NULL) - descriptorBind = &(*slotBinds)[idx]; - - if(arrayLength > 1) - { - if(cblock != NULL && cblock->name.count > 0) - slotname = QFormatStr("%1[%2]: %3").arg(bind).arg(idx).arg(ToQStr(cblock->name)); - else - slotname = QFormatStr("%1[%2]").arg(bind).arg(idx); - } - - QString name = tr("Empty"); - uint64_t length = 0; - int numvars = cblock != NULL ? cblock->variables.count : 0; - uint64_t byteSize = cblock != NULL ? cblock->byteSize : 0; - - QString vecrange = lit("-"); - - if(filledSlot && descriptorBind != NULL) - { - name = QString(); - length = descriptorBind->size; - - BufferDescription *buf = m_Ctx.GetBuffer(descriptorBind->res); - if(buf) - { - name = ToQStr(buf->name); - if(length == UINT64_MAX) - length = buf->length - descriptorBind->offset; - } - - if(name == QString()) - name = lit("UBO ") + ToQStr(descriptorBind->res); - - vecrange = - QFormatStr("%1 - %2").arg(descriptorBind->offset).arg(descriptorBind->offset + length); - } - - QString sizestr; - - // push constants or specialization constants - if(cblock != NULL && !cblock->bufferBacked) - { - setname = QString(); - slotname = ToQStr(cblock->name); - name = tr("Push constants"); - vecrange = QString(); - sizestr = tr("%1 Variables").arg(numvars); - - // could maybe get range from ShaderVariable.reg if it's filled out - // from SPIR-V side. - } - else - { - if(length == byteSize) - sizestr = tr("%1 Variables, %2 bytes").arg(numvars).arg(length); - else - sizestr = - tr("%1 Variables, %2 bytes needed, %3 provided").arg(numvars).arg(byteSize).arg(length); - - if(length < byteSize) - filledSlot = false; - } - - RDTreeWidgetItem *node = - new RDTreeWidgetItem({QString(), setname, slotname, name, vecrange, sizestr}); - - node->setTag(QVariant::fromValue(VulkanCBufferTag(slot, (uint)idx))); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - - parentNode->addChild(node); - } - } -} - -void VulkanPipelineStateViewer::setShaderState(const VKPipe::Shader &stage, - const VKPipe::Pipeline &pipe, QLabel *shader, - RDTreeWidget *resources, RDTreeWidget *ubos) -{ - ShaderReflection *shaderDetails = stage.ShaderDetails; - - if(stage.Object == ResourceId()) - shader->setText(tr("Unbound Shader")); - else - shader->setText(ToQStr(stage.name)); - - if(shaderDetails != NULL) - { - QString entryFunc = ToQStr(shaderDetails->EntryPoint); - if(shaderDetails->DebugInfo.files.count > 0 || entryFunc != lit("main")) - shader->setText(entryFunc + lit("()")); - - if(shaderDetails->DebugInfo.files.count > 0) - shader->setText(entryFunc + lit("() - ") + - QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName()); - } - - int vs = 0; - - // hide the tree columns. The functions below will add it - // if any array bindings are present - resources->hideColumn(0); - ubos->hideColumn(0); - - vs = resources->verticalScrollBar()->value(); - resources->setUpdatesEnabled(false); - resources->clear(); - - QMap samplers; - - for(int bindset = 0; bindset < pipe.DescSets.count; bindset++) - { - for(int bind = 0; bind < pipe.DescSets[bindset].bindings.count; bind++) - { - addResourceRow(shaderDetails, stage, bindset, bind, pipe, resources, samplers); - } - - // if we have a shader bound, go through and add rows for any resources it wants for binds that - // aren't - // in this descriptor set (e.g. if layout mismatches) - if(shaderDetails != NULL) - { - for(int i = 0; i < shaderDetails->ReadOnlyResources.count; i++) - { - const ShaderResource &ro = shaderDetails->ReadOnlyResources[i]; - - if(stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bindset == bindset && - stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bind >= - pipe.DescSets[bindset].bindings.count) - { - addResourceRow(shaderDetails, stage, bindset, - stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bind, pipe, - resources, samplers); - } - } - - for(int i = 0; i < shaderDetails->ReadWriteResources.count; i++) - { - const ShaderResource &rw = shaderDetails->ReadWriteResources[i]; - - if(stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bindset == bindset && - stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bind >= - pipe.DescSets[bindset].bindings.count) - { - addResourceRow(shaderDetails, stage, bindset, - stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bind, pipe, - resources, samplers); - } - } - } - } - - // if we have a shader bound, go through and add rows for any resources it wants for descriptor - // sets that aren't - // bound at all - if(shaderDetails != NULL) - { - for(int i = 0; i < shaderDetails->ReadOnlyResources.count; i++) - { - const ShaderResource &ro = shaderDetails->ReadOnlyResources[i]; - - if(stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bindset >= pipe.DescSets.count) - { - addResourceRow( - shaderDetails, stage, stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bindset, - stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bind, pipe, resources, samplers); - } - } - - for(int i = 0; i < shaderDetails->ReadWriteResources.count; i++) - { - const ShaderResource &rw = shaderDetails->ReadWriteResources[i]; - - if(stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bindset >= pipe.DescSets.count) - { - addResourceRow( - shaderDetails, stage, stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bindset, - stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bind, pipe, resources, samplers); - } - } - } - - resources->clearSelection(); - resources->setUpdatesEnabled(true); - resources->verticalScrollBar()->setValue(vs); - - vs = ubos->verticalScrollBar()->value(); - ubos->setUpdatesEnabled(false); - ubos->clear(); - for(int bindset = 0; bindset < pipe.DescSets.count; bindset++) - { - for(int bind = 0; bind < pipe.DescSets[bindset].bindings.count; bind++) - { - addConstantBlockRow(shaderDetails, stage, bindset, bind, pipe, ubos); - } - - // if we have a shader bound, go through and add rows for any cblocks it wants for binds that - // aren't - // in this descriptor set (e.g. if layout mismatches) - if(shaderDetails != NULL) - { - for(int i = 0; i < shaderDetails->ConstantBlocks.count; i++) - { - ConstantBlock &cb = shaderDetails->ConstantBlocks[i]; - - if(stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bindset == bindset && - stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bind >= - pipe.DescSets[bindset].bindings.count) - { - addConstantBlockRow(shaderDetails, stage, bindset, - stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bind, pipe, ubos); - } - } - } - } - - // if we have a shader bound, go through and add rows for any resources it wants for descriptor - // sets that aren't - // bound at all - if(shaderDetails != NULL) - { - for(int i = 0; i < shaderDetails->ConstantBlocks.count; i++) - { - ConstantBlock &cb = shaderDetails->ConstantBlocks[i]; - - if(stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bindset >= pipe.DescSets.count && - cb.bufferBacked) - { - addConstantBlockRow(shaderDetails, stage, - stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bindset, - stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bind, pipe, ubos); - } - } - } - - // search for push constants and add them last - if(shaderDetails != NULL) - { - for(int cb = 0; cb < shaderDetails->ConstantBlocks.count; cb++) - { - ConstantBlock &cblock = shaderDetails->ConstantBlocks[cb]; - if(cblock.bufferBacked == false) - { - // could maybe get range from ShaderVariable.reg if it's filled out - // from SPIR-V side. - - RDTreeWidgetItem *node = - new RDTreeWidgetItem({QString(), QString(), ToQStr(cblock.name), tr("Push constants"), - QString(), tr("%1 Variables").arg(cblock.variables.count)}); - - node->setTag(QVariant::fromValue(VulkanCBufferTag(cb, 0))); - - ubos->addTopLevelItem(node); - } - } - } - ubos->clearSelection(); - ubos->setUpdatesEnabled(true); - ubos->verticalScrollBar()->setValue(vs); -} - -void VulkanPipelineStateViewer::setState() -{ - if(!m_Ctx.LogLoaded()) - { - clearState(); - return; - } - - m_CombinedImageSamplers.clear(); - - const VKPipe::State &state = m_Ctx.CurVulkanPipelineState(); - const DrawcallDescription *draw = m_Ctx.CurDrawcall(); - - bool showDisabled = ui->showDisabled->isChecked(); - bool showEmpty = ui->showEmpty->isChecked(); - - const QPixmap &tick = Pixmaps::tick(this); - const QPixmap &cross = Pixmaps::cross(this); - - bool usedBindings[128] = {}; - - //////////////////////////////////////////////// - // Vertex Input - - int vs = 0; - - vs = ui->viAttrs->verticalScrollBar()->value(); - ui->viAttrs->setUpdatesEnabled(false); - ui->viAttrs->clear(); - { - int i = 0; - for(const VKPipe::VertexAttribute &a : state.VI.attrs) - { - bool filledSlot = true; - bool usedSlot = false; - - QString name = tr("Attribute %1").arg(i); - - if(state.m_VS.Object != ResourceId()) - { - int attrib = -1; - if((int32_t)a.location < state.m_VS.BindpointMapping.InputAttributes.count) - attrib = state.m_VS.BindpointMapping.InputAttributes[a.location]; - - if(attrib >= 0 && attrib < state.m_VS.ShaderDetails->InputSig.count) - { - name = ToQStr(state.m_VS.ShaderDetails->InputSig[attrib].varName); - usedSlot = true; - } - } - - if(showNode(usedSlot, filledSlot)) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {i, name, a.location, a.binding, ToQStr(a.format.strname), a.byteoffset}); - - usedBindings[a.binding] = true; - - if(!usedSlot) - setInactiveRow(node); - - ui->viAttrs->addTopLevelItem(node); - } - - i++; - } - } - ui->viAttrs->clearSelection(); - ui->viAttrs->setUpdatesEnabled(true); - ui->viAttrs->verticalScrollBar()->setValue(vs); - - m_BindNodes.clear(); - - Topology topo = draw != NULL ? draw->topology : Topology::Unknown; - - int numCPs = PatchList_Count(topo); - if(numCPs > 0) - { - ui->topology->setText(tr("PatchList (%1 Control Points)").arg(numCPs)); - } - else - { - ui->topology->setText(ToQStr(topo)); - } - - m_Common.setTopologyDiagram(ui->topologyDiagram, topo); - - ui->primRestart->setVisible(state.IA.primitiveRestartEnable); - - vs = ui->viBuffers->verticalScrollBar()->value(); - ui->viBuffers->setUpdatesEnabled(false); - ui->viBuffers->clear(); - - bool ibufferUsed = draw != NULL && (draw->flags & DrawFlags::UseIBuffer); - - if(state.IA.ibuffer.buf != ResourceId()) - { - if(ibufferUsed || showDisabled) - { - QString name = tr("Buffer ") + ToQStr(state.IA.ibuffer.buf); - uint64_t length = 1; - - if(!ibufferUsed) - length = 0; - - BufferDescription *buf = m_Ctx.GetBuffer(state.IA.ibuffer.buf); - - if(buf) - { - name = ToQStr(buf->name); - length = buf->length; - } - - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {tr("Index"), name, tr("Index"), (qulonglong)state.IA.ibuffer.offs, - draw != NULL ? draw->indexByteWidth : 0, (qulonglong)length, QString()}); - - node->setTag(QVariant::fromValue( - VulkanVBIBTag(state.IA.ibuffer.buf, draw != NULL ? draw->indexOffset : 0))); - - if(!ibufferUsed) - setInactiveRow(node); - - if(state.IA.ibuffer.buf == ResourceId()) - setEmptyRow(node); - - ui->viBuffers->addTopLevelItem(node); - } - } - else - { - if(ibufferUsed || showEmpty) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {tr("Index"), tr("No Buffer Set"), tr("Index"), lit("-"), lit("-"), lit("-"), QString()}); - - node->setTag(QVariant::fromValue( - VulkanVBIBTag(state.IA.ibuffer.buf, draw != NULL ? draw->indexOffset : 0))); - - setEmptyRow(node); - - if(!ibufferUsed) - setInactiveRow(node); - - ui->viBuffers->addTopLevelItem(node); - } - } - - m_VBNodes.clear(); - - { - int i = 0; - for(; i < qMax(state.VI.vbuffers.count, state.VI.binds.count); i++) - { - const VKPipe::VB *vbuff = (i < state.VI.vbuffers.count ? &state.VI.vbuffers[i] : NULL); - const VKPipe::VertexBinding *bind = NULL; - - for(int b = 0; b < state.VI.binds.count; b++) - { - if(state.VI.binds[b].vbufferBinding == (uint32_t)i) - bind = &state.VI.binds[b]; - } - - bool filledSlot = ((vbuff != NULL && vbuff->buffer != ResourceId()) || bind != NULL); - bool usedSlot = (usedBindings[i]); - - if(showNode(usedSlot, filledSlot)) - { - QString name = tr("No Buffer"); - QString rate = lit("-"); - uint64_t length = 1; - uint64_t offset = 0; - uint32_t stride = 0; - - if(vbuff != NULL) - { - name = tr("Buffer ") + ToQStr(vbuff->buffer); - offset = vbuff->offset; - - BufferDescription *buf = m_Ctx.GetBuffer(vbuff->buffer); - if(buf) - { - name = ToQStr(buf->name); - length = buf->length; - } - } - - if(bind != NULL) - { - stride = bind->bytestride; - rate = bind->perInstance ? tr("Instance") : tr("Vertex"); - } - else - { - name += tr(", No Binding"); - } - - RDTreeWidgetItem *node = NULL; - - if(filledSlot) - node = new RDTreeWidgetItem( - {i, name, rate, (qulonglong)offset, stride, (qulonglong)length, QString()}); - else - node = new RDTreeWidgetItem( - {i, tr("No Binding"), lit("-"), lit("-"), lit("-"), lit("-"), QString()}); - - node->setTag(QVariant::fromValue(VulkanVBIBTag(vbuff != NULL ? vbuff->buffer : ResourceId(), - vbuff != NULL ? vbuff->offset : 0))); - - if(!filledSlot || bind == NULL || vbuff == NULL) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - - m_VBNodes.push_back(node); - - ui->viBuffers->addTopLevelItem(node); - } - } - - for(; i < (int)ARRAY_COUNT(usedBindings); i++) - { - if(usedBindings[i]) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {i, tr("No Binding"), lit("-"), lit("-"), lit("-"), lit("-"), QString()}); - - node->setTag(QVariant::fromValue(VulkanVBIBTag(ResourceId(), 0))); - - setEmptyRow(node); - - setInactiveRow(node); - - ui->viBuffers->addTopLevelItem(node); - - m_VBNodes.push_back(node); - } - } - } - ui->viBuffers->clearSelection(); - ui->viBuffers->setUpdatesEnabled(true); - ui->viBuffers->verticalScrollBar()->setValue(vs); - - setShaderState(state.m_VS, state.graphics, ui->vsShader, ui->vsResources, ui->vsUBOs); - setShaderState(state.m_GS, state.graphics, ui->gsShader, ui->gsResources, ui->gsUBOs); - setShaderState(state.m_TCS, state.graphics, ui->tcsShader, ui->tcsResources, ui->tcsUBOs); - setShaderState(state.m_TES, state.graphics, ui->tesShader, ui->tesResources, ui->tesUBOs); - setShaderState(state.m_FS, state.graphics, ui->fsShader, ui->fsResources, ui->fsUBOs); - setShaderState(state.m_CS, state.compute, ui->csShader, ui->csResources, ui->csUBOs); - - //////////////////////////////////////////////// - // Rasterizer - - vs = ui->viewports->verticalScrollBar()->value(); - ui->viewports->setUpdatesEnabled(false); - ui->viewports->clear(); - - int vs2 = ui->scissors->verticalScrollBar()->value(); - ui->scissors->setUpdatesEnabled(false); - ui->scissors->clear(); - - if(state.Pass.renderpass.obj != ResourceId()) - { - ui->scissors->addTopLevelItem( - new RDTreeWidgetItem({tr("Render Area"), state.Pass.renderArea.x, state.Pass.renderArea.y, - state.Pass.renderArea.width, state.Pass.renderArea.height})); - } - - { - int i = 0; - for(const VKPipe::ViewportScissor &v : state.VP.viewportScissors) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {i, v.vp.x, v.vp.y, v.vp.width, v.vp.height, v.vp.minDepth, v.vp.maxDepth}); - ui->viewports->addTopLevelItem(node); - - if(v.vp.width == 0 || v.vp.height == 0) - setEmptyRow(node); - - node = new RDTreeWidgetItem({i, v.scissor.x, v.scissor.y, v.scissor.width, v.scissor.height}); - ui->scissors->addTopLevelItem(node); - - if(v.scissor.width == 0 || v.scissor.height == 0) - setEmptyRow(node); - - i++; - } - } - - ui->viewports->verticalScrollBar()->setValue(vs); - ui->viewports->clearSelection(); - ui->scissors->clearSelection(); - ui->scissors->verticalScrollBar()->setValue(vs2); - - ui->viewports->setUpdatesEnabled(true); - ui->scissors->setUpdatesEnabled(true); - - ui->fillMode->setText(ToQStr(state.RS.fillMode)); - ui->cullMode->setText(ToQStr(state.RS.cullMode)); - ui->frontCCW->setPixmap(state.RS.FrontCCW ? tick : cross); - - ui->depthBias->setText(Formatter::Format(state.RS.depthBias)); - ui->depthBiasClamp->setText(Formatter::Format(state.RS.depthBiasClamp)); - ui->slopeScaledBias->setText(Formatter::Format(state.RS.slopeScaledDepthBias)); - - ui->depthClamp->setPixmap(state.RS.depthClampEnable ? tick : cross); - ui->rasterizerDiscard->setPixmap(state.RS.rasterizerDiscardEnable ? tick : cross); - ui->lineWidth->setText(Formatter::Format(state.RS.lineWidth)); - - ui->sampleCount->setText(QString::number(state.MSAA.rasterSamples)); - ui->sampleShading->setPixmap(state.MSAA.sampleShadingEnable ? tick : cross); - ui->minSampleShading->setText(Formatter::Format(state.MSAA.minSampleShading)); - ui->sampleMask->setText(Formatter::Format(state.MSAA.sampleMask, true)); - ui->alphaToOne->setPixmap(state.CB.alphaToOneEnable ? tick : cross); - ui->alphaToCoverage->setPixmap(state.CB.alphaToCoverageEnable ? tick : cross); - - //////////////////////////////////////////////// - // Output Merger - - bool targets[32] = {}; - - vs = ui->framebuffer->verticalScrollBar()->value(); - ui->framebuffer->setUpdatesEnabled(false); - ui->framebuffer->clear(); - { - int i = 0; - for(const VKPipe::Attachment &p : state.Pass.framebuffer.attachments) - { - int colIdx = -1; - for(int c = 0; c < state.Pass.renderpass.colorAttachments.count; c++) - { - if(state.Pass.renderpass.colorAttachments[c] == (uint)i) - { - colIdx = c; - break; - } - } - int resIdx = -1; - for(int c = 0; c < state.Pass.renderpass.resolveAttachments.count; c++) - { - if(state.Pass.renderpass.resolveAttachments[c] == (uint)i) - { - resIdx = c; - break; - } - } - - bool filledSlot = (p.img != ResourceId()); - bool usedSlot = - (colIdx >= 0 || resIdx >= 0 || state.Pass.renderpass.depthstencilAttachment == i); - - if(showNode(usedSlot, filledSlot)) - { - uint32_t w = 1, h = 1, d = 1; - uint32_t a = 1; - QString format = ToQStr(p.viewfmt.strname); - QString name = tr("Texture ") + ToQStr(p.img); - QString typeName = tr("Unknown"); - - if(p.img == ResourceId()) - { - name = tr("Empty"); - format = lit("-"); - typeName = lit("-"); - w = h = d = a = 0; - } - - TextureDescription *tex = m_Ctx.GetTexture(p.img); - if(tex) - { - w = tex->width; - h = tex->height; - d = tex->depth; - a = tex->arraysize; - name = ToQStr(tex->name); - typeName = ToQStr(tex->resType); - - if(!tex->customName && state.m_FS.ShaderDetails != NULL) - { - for(int s = 0; s < state.m_FS.ShaderDetails->OutputSig.count; s++) - { - if(state.m_FS.ShaderDetails->OutputSig[s].regIndex == (uint32_t)colIdx && - (state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::Undefined || - state.m_FS.ShaderDetails->OutputSig[s].systemValue == ShaderBuiltin::ColorOutput)) - { - name = QFormatStr("<%1>").arg(ToQStr(state.m_FS.ShaderDetails->OutputSig[s].varName)); - } - } - } - } - - if(p.swizzle[0] != TextureSwizzle::Red || p.swizzle[1] != TextureSwizzle::Green || - p.swizzle[2] != TextureSwizzle::Blue || p.swizzle[3] != TextureSwizzle::Alpha) - { - format += tr(" swizzle[%1%2%3%4]") - .arg(ToQStr(p.swizzle[0])) - .arg(ToQStr(p.swizzle[1])) - .arg(ToQStr(p.swizzle[2])) - .arg(ToQStr(p.swizzle[3])); - } - - QString slotname; - - if(colIdx >= 0) - slotname = QFormatStr("Color %1").arg(i); - else if(resIdx >= 0) - slotname = QFormatStr("Resolve %1").arg(i); - else - slotname = lit("Depth"); - - RDTreeWidgetItem *node = - new RDTreeWidgetItem({slotname, name, typeName, w, h, d, a, format, QString()}); - - if(tex) - node->setTag(QVariant::fromValue(p.img)); - - if(p.img == ResourceId()) - { - setEmptyRow(node); - } - else if(!usedSlot) - { - setInactiveRow(node); - } - else - { - targets[i] = true; - } - - setViewDetails(node, p, tex); - - ui->framebuffer->addTopLevelItem(node); - } - - i++; - } - } - - ui->framebuffer->clearSelection(); - ui->framebuffer->setUpdatesEnabled(true); - ui->framebuffer->verticalScrollBar()->setValue(vs); - - vs = ui->blends->verticalScrollBar()->value(); - ui->blends->setUpdatesEnabled(false); - ui->blends->clear(); - { - int i = 0; - for(const VKPipe::Blend &blend : state.CB.attachments) - { - bool filledSlot = true; - bool usedSlot = (targets[i]); - - if(showNode(usedSlot, filledSlot)) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {i, blend.blendEnable ? tr("True") : tr("False"), - - ToQStr(blend.blend.Source), ToQStr(blend.blend.Destination), - ToQStr(blend.blend.Operation), - - ToQStr(blend.alphaBlend.Source), ToQStr(blend.alphaBlend.Destination), - ToQStr(blend.alphaBlend.Operation), - - QFormatStr("%1%2%3%4") - .arg((blend.writeMask & 0x1) == 0 ? lit("_") : lit("R")) - .arg((blend.writeMask & 0x2) == 0 ? lit("_") : lit("G")) - .arg((blend.writeMask & 0x4) == 0 ? lit("_") : lit("B")) - .arg((blend.writeMask & 0x8) == 0 ? lit("_") : lit("A"))}); - - if(!filledSlot) - setEmptyRow(node); - - if(!usedSlot) - setInactiveRow(node); - - ui->blends->addTopLevelItem(node); - } - - i++; - } - } - ui->blends->clearSelection(); - ui->blends->setUpdatesEnabled(true); - ui->blends->verticalScrollBar()->setValue(vs); - - ui->blendFactor->setText(QFormatStr("%1, %2, %3, %4") - .arg(state.CB.blendConst[0], 0, 'f', 2) - .arg(state.CB.blendConst[1], 0, 'f', 2) - .arg(state.CB.blendConst[2], 0, 'f', 2) - .arg(state.CB.blendConst[3], 0, 'f', 2)); - ui->logicOp->setText(state.CB.logicOpEnable ? ToQStr(state.CB.logic) : lit("-")); - - ui->depthEnabled->setPixmap(state.DS.depthTestEnable ? tick : cross); - ui->depthFunc->setText(ToQStr(state.DS.depthCompareOp)); - ui->depthWrite->setPixmap(state.DS.depthWriteEnable ? tick : cross); - - if(state.DS.depthBoundsEnable) - { - ui->depthBounds->setText(Formatter::Format(state.DS.minDepthBounds) + lit("-") + - Formatter::Format(state.DS.maxDepthBounds)); - ui->depthBounds->setPixmap(QPixmap()); - } - else - { - ui->depthBounds->setText(QString()); - ui->depthBounds->setPixmap(cross); - } - - ui->stencils->setUpdatesEnabled(false); - ui->stencils->clear(); - if(state.DS.stencilTestEnable) - { - ui->stencils->addTopLevelItem(new RDTreeWidgetItem( - {tr("Front"), ToQStr(state.DS.front.Func), ToQStr(state.DS.front.FailOp), - ToQStr(state.DS.front.DepthFailOp), ToQStr(state.DS.front.PassOp), - Formatter::Format(state.DS.front.writeMask, true), - Formatter::Format(state.DS.front.compareMask, true), - Formatter::Format(state.DS.front.ref, true)})); - ui->stencils->addTopLevelItem( - new RDTreeWidgetItem({tr("Back"), ToQStr(state.DS.back.Func), ToQStr(state.DS.back.FailOp), - ToQStr(state.DS.back.DepthFailOp), ToQStr(state.DS.back.PassOp), - Formatter::Format(state.DS.back.writeMask, true), - Formatter::Format(state.DS.back.compareMask, true), - Formatter::Format(state.DS.back.ref, true)})); - } - else - { - ui->stencils->addTopLevelItem(new RDTreeWidgetItem( - {tr("Front"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-")})); - ui->stencils->addTopLevelItem(new RDTreeWidgetItem( - {tr("Back"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-")})); - } - ui->stencils->clearSelection(); - ui->stencils->setUpdatesEnabled(true); - - // highlight the appropriate stages in the flowchart - if(draw == NULL) - { - ui->pipeFlow->setStagesEnabled({true, true, true, true, true, true, true, true, true}); - } - else if(draw->flags & DrawFlags::Dispatch) - { - ui->pipeFlow->setStagesEnabled({false, false, false, false, false, false, false, false, true}); - } - else - { - ui->pipeFlow->setStagesEnabled( - {true, true, state.m_TCS.Object != ResourceId(), state.m_TES.Object != ResourceId(), - state.m_GS.Object != ResourceId(), true, state.m_FS.Object != ResourceId(), true, false}); - } -} - -QString VulkanPipelineStateViewer::formatMembers(int indent, const QString &nameprefix, - const rdctype::array &vars) -{ - QString indentstr(indent * 4, QLatin1Char(' ')); - - QString ret = QString(); - - int i = 0; - - for(const ShaderConstant &v : vars) - { - if(v.type.members.count > 0) - { - if(i > 0) - ret += lit("\n"); - ret += indentstr + lit("// struct %1\n").arg(ToQStr(v.type.descriptor.name)); - ret += indentstr + lit("{\n") + - formatMembers(indent + 1, ToQStr(v.name) + lit("_"), v.type.members) + indentstr + - lit("}\n"); - if(i < vars.count - 1) - ret += lit("\n"); - } - else - { - QString arr = QString(); - if(v.type.descriptor.elements > 1) - arr = QFormatStr("[%1]").arg(v.type.descriptor.elements); - ret += QFormatStr("%1%2 %3%4%5;\n") - .arg(indentstr) - .arg(ToQStr(v.type.descriptor.name)) - .arg(nameprefix) - .arg(ToQStr(v.name)) - .arg(arr); - } - - i++; - } - - return ret; -} - -void VulkanPipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, int column) -{ - const VKPipe::Shader *stage = stageForSender(item->treeWidget()); - - if(stage == NULL) - return; - - QVariant tag = item->tag(); - - if(tag.canConvert()) - { - TextureDescription *tex = m_Ctx.GetTexture(tag.value()); - - if(tex) - { - if(tex->resType == TextureDim::Buffer) - { - IBufferViewer *viewer = m_Ctx.ViewTextureAsBuffer(0, 0, tex->ID); - - m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); - } - else - { - if(!m_Ctx.HasTextureViewer()) - m_Ctx.ShowTextureViewer(); - ITextureViewer *viewer = m_Ctx.GetTextureViewer(); - viewer->ViewTexture(tex->ID, true); - } - - return; - } - } - else if(tag.canConvert()) - { - VulkanBufferTag buf = tag.value(); - - const ShaderResource &shaderRes = buf.rwRes - ? stage->ShaderDetails->ReadWriteResources[buf.bindPoint] - : stage->ShaderDetails->ReadOnlyResources[buf.bindPoint]; - - QString format = lit("// struct %1\n").arg(ToQStr(shaderRes.variableType.descriptor.name)); - - if(shaderRes.variableType.members.count > 1) - { - format += lit("// members skipped as they are fixed size:\n"); - for(int i = 0; i < shaderRes.variableType.members.count - 1; i++) - format += QFormatStr("%1 %2;\n") - .arg(ToQStr(shaderRes.variableType.members[i].type.descriptor.name)) - .arg(ToQStr(shaderRes.variableType.members[i].name)); - } - - if(shaderRes.variableType.members.count > 0) - { - format += lit("{\n") + - formatMembers(1, QString(), shaderRes.variableType.members.back().type.members) + - lit("}"); - } - else - { - const auto &desc = shaderRes.variableType.descriptor; - - format = QString(); - if(desc.rowMajorStorage) - format += lit("row_major "); - - format += ToQStr(desc.type); - if(desc.rows > 1 && desc.cols > 1) - format += QFormatStr("%1x%2").arg(desc.rows).arg(desc.cols); - else if(desc.cols > 1) - format += desc.cols; - - if(desc.name.count > 0) - format += lit(" ") + ToQStr(desc.name); - - if(desc.elements > 1) - format += QFormatStr("[%1]").arg(desc.elements); - } - - if(buf.ID != ResourceId()) - { - IBufferViewer *viewer = m_Ctx.ViewBuffer(buf.offset, buf.size, buf.ID, format); - - m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); - } - } -} - -void VulkanPipelineStateViewer::ubo_itemActivated(RDTreeWidgetItem *item, int column) -{ - const VKPipe::Shader *stage = stageForSender(item->treeWidget()); - - if(stage == NULL) - return; - - QVariant tag = item->tag(); - - if(!tag.canConvert()) - return; - - VulkanCBufferTag cb = tag.value(); - - IConstantBufferPreviewer *prev = m_Ctx.ViewConstantBuffer(stage->stage, cb.slotIdx, cb.arrayIdx); - - m_Ctx.AddDockWindow(prev->Widget(), DockReference::RightOf, this, 0.3f); -} - -void VulkanPipelineStateViewer::on_viAttrs_itemActivated(RDTreeWidgetItem *item, int column) -{ - on_meshView_clicked(); -} - -void VulkanPipelineStateViewer::on_viBuffers_itemActivated(RDTreeWidgetItem *item, int column) -{ - QVariant tag = item->tag(); - - if(tag.canConvert()) - { - VulkanVBIBTag buf = tag.value(); - - if(buf.id != ResourceId()) - { - IBufferViewer *viewer = m_Ctx.ViewBuffer(buf.offset, UINT64_MAX, buf.id); - - m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); - } - } -} - -void VulkanPipelineStateViewer::highlightIABind(int slot) -{ - int idx = ((slot + 1) * 21) % 32; // space neighbouring colours reasonably distinctly - - const VKPipe::VertexInput &VI = m_Ctx.CurVulkanPipelineState().VI; - - QColor col = QColor::fromHslF(float(idx) / 32.0f, 1.0f, - qBound(0.05, palette().color(QPalette::Base).lightnessF(), 0.95)); - - ui->viAttrs->beginUpdate(); - ui->viBuffers->beginUpdate(); - - if(slot < m_VBNodes.count()) - { - m_VBNodes[slot]->setBackgroundColor(col); - m_VBNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); - } - - if(slot < m_BindNodes.count()) - { - m_BindNodes[slot]->setBackgroundColor(col); - m_BindNodes[slot]->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); - } - - for(int i = 0; i < ui->viAttrs->topLevelItemCount(); i++) - { - RDTreeWidgetItem *item = ui->viAttrs->topLevelItem(i); - - if((int)VI.attrs[i].binding != slot) - { - item->setBackground(QBrush()); - item->setForeground(QBrush()); - } - else - { - item->setBackgroundColor(col); - item->setForegroundColor(contrastingColor(col, QColor(0, 0, 0))); - } - } - - ui->viAttrs->endUpdate(); - ui->viBuffers->endUpdate(); -} - -void VulkanPipelineStateViewer::on_viAttrs_mouseMove(QMouseEvent *e) -{ - if(!m_Ctx.LogLoaded()) - return; - - QModelIndex idx = ui->viAttrs->indexAt(e->pos()); - - vertex_leave(NULL); - - const VKPipe::VertexInput &VI = m_Ctx.CurVulkanPipelineState().VI; - - if(idx.isValid()) - { - if(idx.row() >= 0 && idx.row() < VI.attrs.count) - { - uint32_t binding = VI.attrs[idx.row()].binding; - - highlightIABind((int)binding); - } - } -} - -void VulkanPipelineStateViewer::on_viBuffers_mouseMove(QMouseEvent *e) -{ - if(!m_Ctx.LogLoaded()) - return; - - RDTreeWidgetItem *item = ui->viBuffers->itemAt(e->pos()); - - vertex_leave(NULL); - - if(item) - { - int idx = m_VBNodes.indexOf(item); - if(idx >= 0) - { - highlightIABind(idx); - } - else - { - item->setBackground(ui->viBuffers->palette().brush(QPalette::Window)); - item->setForeground(ui->viBuffers->palette().brush(QPalette::WindowText)); - } - } -} - -void VulkanPipelineStateViewer::vertex_leave(QEvent *e) -{ - ui->viAttrs->beginUpdate(); - ui->viBuffers->beginUpdate(); - - for(int i = 0; i < ui->viAttrs->topLevelItemCount(); i++) - { - ui->viAttrs->topLevelItem(i)->setBackground(QBrush()); - ui->viAttrs->topLevelItem(i)->setForeground(QBrush()); - } - - for(int i = 0; i < ui->viBuffers->topLevelItemCount(); i++) - { - ui->viBuffers->topLevelItem(i)->setBackground(QBrush()); - ui->viBuffers->topLevelItem(i)->setForeground(QBrush()); - } - - ui->viAttrs->endUpdate(); - ui->viBuffers->endUpdate(); -} - -void VulkanPipelineStateViewer::on_pipeFlow_stageSelected(int index) -{ - ui->stagesTabs->setCurrentIndex(index); -} - -void VulkanPipelineStateViewer::shaderView_clicked() -{ - const VKPipe::Shader *stage = stageForSender(qobject_cast(QObject::sender())); - - if(stage == NULL || stage->Object == ResourceId()) - return; - - ShaderReflection *shaderDetails = stage->ShaderDetails; - - IShaderViewer *shad = m_Ctx.ViewShader(&stage->BindpointMapping, shaderDetails, stage->stage); - - m_Ctx.AddDockWindow(shad->Widget(), DockReference::AddTo, this); -} - -void VulkanPipelineStateViewer::shaderLabel_clicked(QMouseEvent *event) -{ - // forward to shaderView_clicked, we only need this to handle the different parameter, and we - // can't use a lambda because then QObject::sender() is NULL - shaderView_clicked(); -} - -void VulkanPipelineStateViewer::shaderEdit_clicked() -{ - QWidget *sender = qobject_cast(QObject::sender()); - const VKPipe::Shader *stage = stageForSender(sender); - - if(!stage || stage->Object == ResourceId()) - return; - - const ShaderReflection *shaderDetails = stage->ShaderDetails; - - if(!shaderDetails) - return; - - QString entryFunc = lit("EditedShader%1S").arg(ToQStr(stage->stage, GraphicsAPI::Vulkan)[0]); - - QString mainfile; - - QStringMap files; - - bool hasOrigSource = m_Common.PrepareShaderEditing(shaderDetails, entryFunc, files, mainfile); - - if(hasOrigSource) - { - if(files.empty()) - return; - } - else - { - QString glsl; - - if(!m_Ctx.Config().SPIRVDisassemblers.isEmpty()) - glsl = disassembleSPIRV(shaderDetails); - - mainfile = lit("generated.glsl"); - - files[mainfile] = glsl; - - if(glsl.isEmpty()) - { - m_Ctx.Replay().AsyncInvoke( - [this, stage, shaderDetails, entryFunc, mainfile](IReplayController *r) { - rdctype::str disasm = r->DisassembleShader(shaderDetails, ""); - - GUIInvoke::call([this, stage, shaderDetails, entryFunc, mainfile, disasm]() { - QStringMap fileMap; - fileMap[mainfile] = ToQStr(disasm); - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, fileMap, - mainfile); - }); - }); - return; - } - } - - m_Common.EditShader(stage->stage, stage->Object, shaderDetails, entryFunc, files, mainfile); -} - -QString VulkanPipelineStateViewer::disassembleSPIRV(const ShaderReflection *shaderDetails) -{ - QString glsl; - - const SPIRVDisassembler &disasm = m_Ctx.Config().SPIRVDisassemblers[0]; - - if(disasm.executable.isEmpty()) - return QString(); - - QString spv_bin_file = QDir(QDir::tempPath()).absoluteFilePath(lit("spv_bin.spv")); - - QFile binHandle(spv_bin_file); - if(binHandle.open(QFile::WriteOnly | QIODevice::Truncate)) - { - binHandle.write( - QByteArray((const char *)shaderDetails->RawBytes.elems, shaderDetails->RawBytes.count)); - binHandle.close(); - } - else - { - RDDialog::critical(this, tr("Error writing temp file"), - tr("Couldn't write temporary SPIR-V file %1.").arg(spv_bin_file)); - return QString(); - } - - if(!disasm.args.contains(lit("{spv_bin}"))) - { - RDDialog::critical( - this, tr("Wrongly configured disassembler"), - tr("Please use {spv_bin} in the disassembler arguments to specify the input file.")); - return QString(); - } - - LambdaThread *thread = new LambdaThread([this, &glsl, &disasm, spv_bin_file]() { - QString spv_disas_file = QDir(QDir::tempPath()).absoluteFilePath(lit("spv_disas.txt")); - - QString args = disasm.args; - - bool writesToFile = disasm.args.contains(lit("{spv_disas}")); - - args.replace(lit("{spv_bin}"), spv_bin_file); - args.replace(lit("{spv_disas}"), spv_disas_file); - - QStringList argList = ParseArgsList(args); - - QProcess process; - process.start(disasm.executable, argList); - process.waitForFinished(); - - if(process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) - { - GUIInvoke::call([this]() { - RDDialog::critical(this, tr("Error running disassembler"), - tr("There was an error invoking the external SPIR-V disassembler.")); - }); - } - - if(writesToFile) - { - QFile outputHandle(spv_disas_file); - if(outputHandle.open(QFile::ReadOnly | QIODevice::Text)) - { - glsl = QString::fromUtf8(outputHandle.readAll()); - outputHandle.close(); - } - } - else - { - glsl = QString::fromUtf8(process.readAll()); - } - - QFile::remove(spv_bin_file); - QFile::remove(spv_disas_file); - }); - thread->start(); - - ShowProgressDialog(this, tr("Please wait - running external disassembler"), - [thread]() { return !thread->isRunning(); }); - - thread->deleteLater(); - - return glsl; -} - -void VulkanPipelineStateViewer::shaderSave_clicked() -{ - const VKPipe::Shader *stage = stageForSender(qobject_cast(QObject::sender())); - - if(stage == NULL) - return; - - ShaderReflection *shaderDetails = stage->ShaderDetails; - - if(stage->Object == ResourceId()) - return; - - m_Common.SaveShaderFile(shaderDetails); -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::VertexInput &vi) -{ - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Attributes")); - xml.writeEndElement(); - - QList rows; - - for(const VKPipe::VertexAttribute &attr : vi.attrs) - rows.push_back({attr.location, attr.binding, ToQStr(attr.format.strname), attr.byteoffset}); - - m_Common.exportHTMLTable(xml, {tr("Location"), tr("Binding"), tr("Format"), tr("Offset")}, rows); - } - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Bindings")); - xml.writeEndElement(); - - QList rows; - - for(const VKPipe::VertexBinding &attr : vi.binds) - rows.push_back({attr.vbufferBinding, attr.bytestride, - attr.perInstance ? tr("PER_INSTANCE") : tr("PER_VERTEX")}); - - m_Common.exportHTMLTable(xml, {tr("Binding"), tr("Byte Stride"), tr("Step Rate")}, rows); - } - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Vertex Buffers")); - xml.writeEndElement(); - - QList rows; - - int i = 0; - for(const VKPipe::VB &vb : vi.vbuffers) - { - QString name = tr("Buffer %1").arg(ToQStr(vb.buffer)); - uint64_t length = 0; - - if(vb.buffer == ResourceId()) - { - continue; - } - else - { - BufferDescription *buf = m_Ctx.GetBuffer(vb.buffer); - if(buf) - { - name = ToQStr(buf->name); - length = buf->length; - } - } - - rows.push_back({i, name, (qulonglong)vb.offset, (qulonglong)length}); - - i++; - } - - m_Common.exportHTMLTable(xml, {tr("Binding"), tr("Buffer"), tr("Offset"), tr("Byte Length")}, - rows); - } -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::InputAssembly &ia) -{ - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Index Buffer")); - xml.writeEndElement(); - - BufferDescription *ib = m_Ctx.GetBuffer(ia.ibuffer.buf); - - QString name = tr("Empty"); - uint64_t length = 0; - - if(ib) - { - name = ToQStr(ib->name); - length = ib->length; - } - - QString ifmt = lit("UNKNOWN"); - if(m_Ctx.CurDrawcall()->indexByteWidth == 2) - ifmt = lit("UINT16"); - if(m_Ctx.CurDrawcall()->indexByteWidth == 4) - ifmt = lit("UINT32"); - - m_Common.exportHTMLTable( - xml, {tr("Buffer"), tr("Format"), tr("Offset"), tr("Byte Length"), tr("Primitive Restart")}, - {name, ifmt, (qulonglong)ia.ibuffer.offs, (qulonglong)length, - ia.primitiveRestartEnable ? tr("Yes") : tr("No")}); - } - - xml.writeStartElement(lit("p")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("Primitive Topology"), tr("Tessellation Control Points")}, - {ToQStr(m_Ctx.CurDrawcall()->topology), m_Ctx.CurVulkanPipelineState().Tess.numControlPoints}); -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::Shader &sh) -{ - ShaderReflection *shaderDetails = sh.ShaderDetails; - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Shader")); - xml.writeEndElement(); - - QString shadername = tr("Unknown"); - - if(sh.Object == ResourceId()) - shadername = tr("Unbound"); - else - shadername = ToQStr(sh.name); - - if(shaderDetails) - { - QString entryFunc = ToQStr(shaderDetails->EntryPoint); - if(entryFunc != lit("main")) - shadername = QFormatStr("%1()").arg(entryFunc); - else if(shaderDetails->DebugInfo.files.count > 0) - shadername = QFormatStr("%1() - %2") - .arg(entryFunc) - .arg(QFileInfo(ToQStr(shaderDetails->DebugInfo.files[0].first)).fileName()); - } - - xml.writeStartElement(lit("p")); - xml.writeCharacters(shadername); - xml.writeEndElement(); - - if(sh.Object == ResourceId()) - return; - } - - const VKPipe::Pipeline &pipeline = - (sh.stage == ShaderStage::Compute ? m_Ctx.CurVulkanPipelineState().compute - : m_Ctx.CurVulkanPipelineState().graphics); - - if(shaderDetails && shaderDetails->ConstantBlocks.count > 0) - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("UBOs")); - xml.writeEndElement(); - - QList rows; - - for(int i = 0; i < shaderDetails->ConstantBlocks.count; i++) - { - const ConstantBlock &b = shaderDetails->ConstantBlocks[i]; - const BindpointMap &bindMap = sh.BindpointMapping.ConstantBlocks[i]; - - if(!bindMap.used) - continue; - - const VKPipe::DescriptorSet &set = - pipeline.DescSets[sh.BindpointMapping.ConstantBlocks[i].bindset]; - const VKPipe::DescriptorBinding &bind = - set.bindings[sh.BindpointMapping.ConstantBlocks[i].bind]; - - QString setname = QString::number(bindMap.bindset); - - QString slotname = QFormatStr("%1: %2").arg(bindMap.bind).arg(ToQStr(b.name)); - - for(uint32_t a = 0; a < bind.descriptorCount; a++) - { - const VKPipe::BindingElement &descriptorBind = bind.binds[a]; - - ResourceId id = bind.binds[a].res; - - if(bindMap.arraySize > 1) - slotname = QFormatStr("%1: %2[%3]").arg(bindMap.bind).arg(ToQStr(b.name)).arg(a); - - QString name; - uint64_t byteOffset = descriptorBind.offset; - uint64_t length = descriptorBind.size; - int numvars = b.variables.count; - - if(descriptorBind.res == ResourceId()) - { - name = tr("Empty"); - length = 0; - } - - BufferDescription *buf = m_Ctx.GetBuffer(id); - if(buf) - { - name = ToQStr(buf->name); - - if(length == UINT64_MAX) - length = buf->length - byteOffset; - } - - if(name.isEmpty()) - name = tr("UBO %1").arg(ToQStr(descriptorBind.res)); - - // push constants - if(!b.bufferBacked) - { - setname = QString(); - slotname = ToQStr(b.name); - name = tr("Push constants"); - byteOffset = 0; - length = 0; - - // could maybe get range/size from ShaderVariable.reg if it's filled out - // from SPIR-V side. - } - - rows.push_back({setname, slotname, name, (qulonglong)byteOffset, (qulonglong)length, - numvars, b.byteSize}); - } - } - - m_Common.exportHTMLTable(xml, {tr("Set"), tr("Bind"), tr("Buffer"), tr("Byte Offset"), - tr("Byte Size"), tr("Number of Variables"), tr("Bytes Needed")}, - rows); - } - - if(shaderDetails->ReadOnlyResources.count > 0) - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Read-only Resources")); - xml.writeEndElement(); - - QList rows; - - for(int i = 0; i < shaderDetails->ReadOnlyResources.count; i++) - { - const ShaderResource &b = shaderDetails->ReadOnlyResources[i]; - const BindpointMap &bindMap = sh.BindpointMapping.ReadOnlyResources[i]; - - if(!bindMap.used) - continue; - - const VKPipe::DescriptorSet &set = - pipeline.DescSets[sh.BindpointMapping.ReadOnlyResources[i].bindset]; - const VKPipe::DescriptorBinding &bind = - set.bindings[sh.BindpointMapping.ReadOnlyResources[i].bind]; - - QString setname = QString::number(bindMap.bindset); - - QString slotname = QFormatStr("%1: %2").arg(bindMap.bind).arg(ToQStr(b.name)); - - for(uint32_t a = 0; a < bind.descriptorCount; a++) - { - const VKPipe::BindingElement &descriptorBind = bind.binds[a]; - - ResourceId id = bind.binds[a].res; - - if(bindMap.arraySize > 1) - slotname = QFormatStr("%1: %2[%3]").arg(bindMap.bind).arg(ToQStr(b.name)).arg(a); - - QString name; - - if(descriptorBind.res == ResourceId()) - name = tr("Empty"); - - BufferDescription *buf = m_Ctx.GetBuffer(id); - if(buf) - name = ToQStr(buf->name); - - TextureDescription *tex = m_Ctx.GetTexture(id); - if(tex) - name = ToQStr(tex->name); - - if(name.isEmpty()) - name = tr("Resource %1").arg(ToQStr(descriptorBind.res)); - - uint64_t w = 1; - uint32_t h = 1, d = 1; - uint32_t arr = 0; - QString format = tr("Unknown"); - QString viewParams; - - if(tex) - { - w = tex->width; - h = tex->height; - d = tex->depth; - arr = tex->arraysize; - format = ToQStr(tex->format.strname); - name = ToQStr(tex->name); - - if(tex->mips > 1) - { - viewParams = tr("Mips: %1-%2") - .arg(descriptorBind.baseMip) - .arg(descriptorBind.baseMip + descriptorBind.numMip - 1); - } - - if(tex->arraysize > 1) - { - if(!viewParams.isEmpty()) - viewParams += lit(", "); - viewParams += tr("Layers: %1-%2") - .arg(descriptorBind.baseLayer) - .arg(descriptorBind.baseLayer + descriptorBind.numLayer - 1); - } - } - - if(buf) - { - w = buf->length; - h = 0; - d = 0; - a = 0; - format = lit("-"); - name = ToQStr(buf->name); - - uint64_t length = descriptorBind.size; - - if(length == UINT64_MAX) - length = buf->length - descriptorBind.offset; - - viewParams = - tr("Byte Range: %1 - %2").arg(descriptorBind.offset).arg(descriptorBind.offset + length); - } - - if(bind.type != BindType::Sampler) - rows.push_back({setname, slotname, name, ToQStr(bind.type), (qulonglong)w, h, d, arr, - format, viewParams}); - - if(bind.type == BindType::ImageSampler || bind.type == BindType::Sampler) - { - name = tr("Sampler %1").arg(ToQStr(descriptorBind.sampler)); - - if(bind.type == BindType::ImageSampler) - setname = slotname = QString(); - - QVariantList sampDetails = makeSampler(QString(), QString(), descriptorBind); - rows.push_back({setname, slotname, name, ToQStr(bind.type), QString(), QString(), - QString(), QString(), sampDetails[5], sampDetails[6]}); - } - } - } - - m_Common.exportHTMLTable( - xml, {tr("Set"), tr("Bind"), tr("Buffer"), tr("Resource Type"), tr("Width"), tr("Height"), - tr("Depth"), tr("Array Size"), tr("Resource Format"), tr("View Parameters")}, - rows); - } - - if(shaderDetails->ReadWriteResources.count > 0) - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Read-write Resources")); - xml.writeEndElement(); - - QList rows; - - for(int i = 0; i < shaderDetails->ReadWriteResources.count; i++) - { - const ShaderResource &b = shaderDetails->ReadWriteResources[i]; - const BindpointMap &bindMap = sh.BindpointMapping.ReadWriteResources[i]; - - if(!bindMap.used) - continue; - - const VKPipe::DescriptorSet &set = - pipeline.DescSets[sh.BindpointMapping.ReadWriteResources[i].bindset]; - const VKPipe::DescriptorBinding &bind = - set.bindings[sh.BindpointMapping.ReadWriteResources[i].bind]; - - QString setname = QString::number(bindMap.bindset); - - QString slotname = QFormatStr("%1: %2").arg(bindMap.bind).arg(ToQStr(b.name)); - - for(uint32_t a = 0; a < bind.descriptorCount; a++) - { - const VKPipe::BindingElement &descriptorBind = bind.binds[a]; - - ResourceId id = bind.binds[a].res; - - if(bindMap.arraySize > 1) - slotname = QFormatStr("%1: %2[%3]").arg(bindMap.bind).arg(ToQStr(b.name)).arg(a); - - QString name; - - if(descriptorBind.res == ResourceId()) - name = tr("Empty"); - - BufferDescription *buf = m_Ctx.GetBuffer(id); - if(buf) - name = ToQStr(buf->name); - - TextureDescription *tex = m_Ctx.GetTexture(id); - if(tex) - name = ToQStr(tex->name); - - if(name.isEmpty()) - name = tr("Resource %1").arg(ToQStr(descriptorBind.res)); - - uint64_t w = 1; - uint32_t h = 1, d = 1; - uint32_t arr = 0; - QString format = tr("Unknown"); - QString viewParams; - - if(tex) - { - w = tex->width; - h = tex->height; - d = tex->depth; - arr = tex->arraysize; - format = ToQStr(tex->format.strname); - name = ToQStr(tex->name); - - if(tex->mips > 1) - { - viewParams = tr("Mips: %1-%2") - .arg(descriptorBind.baseMip) - .arg(descriptorBind.baseMip + descriptorBind.numMip - 1); - } - - if(tex->arraysize > 1) - { - if(!viewParams.isEmpty()) - viewParams += lit(", "); - viewParams += tr("Layers: %1-%2") - .arg(descriptorBind.baseLayer) - .arg(descriptorBind.baseLayer + descriptorBind.numLayer - 1); - } - } - - if(buf) - { - w = buf->length; - h = 0; - d = 0; - a = 0; - format = lit("-"); - name = ToQStr(buf->name); - - uint64_t length = descriptorBind.size; - - if(length == UINT64_MAX) - length = buf->length - descriptorBind.offset; - - viewParams = - tr("Byte Range: %1 - %2").arg(descriptorBind.offset).arg(descriptorBind.offset + length); - } - - rows.push_back({setname, slotname, name, ToQStr(bind.type), (qulonglong)w, h, d, arr, - format, viewParams}); - } - } - - m_Common.exportHTMLTable( - xml, {tr("Set"), tr("Bind"), tr("Buffer"), tr("Resource Type"), tr("Width"), tr("Height"), - tr("Depth"), tr("Array Size"), tr("Resource Format"), tr("View Parameters")}, - rows); - } -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::Raster &rs) -{ - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Raster State")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("Fill Mode"), tr("Cull Mode"), tr("Front CCW")}, - {ToQStr(rs.fillMode), ToQStr(rs.cullMode), rs.FrontCCW ? tr("Yes") : tr("No")}); - - xml.writeStartElement(lit("p")); - xml.writeEndElement(); - - m_Common.exportHTMLTable(xml, {tr("Depth Clip Enable"), tr("Rasterizer Discard Enable")}, - {rs.depthClampEnable ? tr("Yes") : tr("No"), - rs.rasterizerDiscardEnable ? tr("Yes") : tr("No")}); - - xml.writeStartElement(lit("p")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("Depth Bias"), tr("Depth Bias Clamp"), tr("Slope Scaled Bias"), tr("Line Width")}, - {Formatter::Format(rs.depthBias), Formatter::Format(rs.depthBiasClamp), - Formatter::Format(rs.slopeScaledDepthBias), Formatter::Format(rs.lineWidth)}); - } - - VKPipe::MultiSample &msaa = m_Ctx.CurVulkanPipelineState().MSAA; - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Multisampling State")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("Raster Samples"), tr("Sample-rate shading"), tr("Min Sample Shading Rate"), - tr("Sample Mask")}, - {msaa.rasterSamples, msaa.sampleShadingEnable ? tr("Yes") : tr("No"), - Formatter::Format(msaa.minSampleShading), Formatter::Format(msaa.sampleMask, true)}); - } - - VKPipe::ViewState &vp = m_Ctx.CurVulkanPipelineState().VP; - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Viewports")); - xml.writeEndElement(); - - QList rows; - - int i = 0; - for(const VKPipe::ViewportScissor &vs : vp.viewportScissors) - { - const VKPipe::Viewport &v = vs.vp; - - rows.push_back({i, v.x, v.y, v.width, v.height, v.minDepth, v.maxDepth}); - - i++; - } - - m_Common.exportHTMLTable(xml, {tr("Slot"), tr("X"), tr("Y"), tr("Width"), tr("Height"), - tr("Min Depth"), tr("Max Depth")}, - rows); - } - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Scissors")); - xml.writeEndElement(); - - QList rows; - - int i = 0; - for(const VKPipe::ViewportScissor &vs : vp.viewportScissors) - { - const VKPipe::Scissor &s = vs.scissor; - - rows.push_back({i, s.x, s.y, s.width, s.height}); - - i++; - } - - m_Common.exportHTMLTable(xml, {tr("Slot"), tr("X"), tr("Y"), tr("Width"), tr("Height")}, rows); - } -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::ColorBlend &cb) -{ - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Color Blend State")); - xml.writeEndElement(); - - QString blendConst = QFormatStr("%1, %2, %3, %4") - .arg(cb.blendConst[0], 0, 'f', 2) - .arg(cb.blendConst[1], 0, 'f', 2) - .arg(cb.blendConst[2], 0, 'f', 2) - .arg(cb.blendConst[3], 0, 'f', 2); - - m_Common.exportHTMLTable( - xml, {tr("Alpha to Coverage"), tr("Alpha to One"), tr("Logic Op"), tr("Blend Constant")}, - { - cb.alphaToCoverageEnable ? tr("Yes") : tr("No"), - cb.alphaToOneEnable ? tr("Yes") : tr("No"), - cb.logicOpEnable ? ToQStr(cb.logic) : tr("Disabled"), blendConst, - }); - - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Attachment Blends")); - xml.writeEndElement(); - - QList rows; - - int i = 0; - for(const VKPipe::Blend &b : cb.attachments) - { - rows.push_back( - {i, b.blendEnable ? tr("Yes") : tr("No"), ToQStr(b.blend.Source), ToQStr(b.blend.Destination), - ToQStr(b.blend.Operation), ToQStr(b.alphaBlend.Source), ToQStr(b.alphaBlend.Destination), - ToQStr(b.alphaBlend.Operation), ((b.writeMask & 0x1) == 0 ? lit("_") : lit("R")) + - ((b.writeMask & 0x2) == 0 ? lit("_") : lit("G")) + - ((b.writeMask & 0x4) == 0 ? lit("_") : lit("B")) + - ((b.writeMask & 0x8) == 0 ? lit("_") : lit("A"))}); - - i++; - } - - m_Common.exportHTMLTable( - xml, - { - tr("Slot"), tr("Blend Enable"), tr("Blend Source"), tr("Blend Destination"), - tr("Blend Operation"), tr("Alpha Blend Source"), tr("Alpha Blend Destination"), - tr("Alpha Blend Operation"), tr("Write Mask"), - }, - rows); -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::DepthStencil &ds) -{ - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Depth State")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("Depth Test Enable"), tr("Depth Writes Enable"), tr("Depth Function"), - tr("Depth Bounds")}, - { - ds.depthTestEnable ? tr("Yes") : tr("No"), ds.depthWriteEnable ? tr("Yes") : tr("No"), - ToQStr(ds.depthCompareOp), ds.depthBoundsEnable - ? QFormatStr("%1 - %2") - .arg(Formatter::Format(ds.minDepthBounds)) - .arg(Formatter::Format(ds.maxDepthBounds)) - : tr("Disabled"), - }); - } - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Stencil State")); - xml.writeEndElement(); - - if(ds.stencilTestEnable) - { - QList rows; - - rows.push_back({ - tr("Front"), Formatter::Format(ds.front.ref, true), - Formatter::Format(ds.front.compareMask, true), - Formatter::Format(ds.front.writeMask, true), ToQStr(ds.front.Func), - ToQStr(ds.front.PassOp), ToQStr(ds.front.FailOp), ToQStr(ds.front.DepthFailOp), - }); - - rows.push_back({ - tr("back"), Formatter::Format(ds.back.ref, true), - Formatter::Format(ds.back.compareMask, true), Formatter::Format(ds.back.writeMask, true), - ToQStr(ds.back.Func), ToQStr(ds.back.PassOp), ToQStr(ds.back.FailOp), - ToQStr(ds.back.DepthFailOp), - }); - - m_Common.exportHTMLTable(xml, - {tr("Face"), tr("Ref"), tr("Compare Mask"), tr("Write Mask"), - tr("Function"), tr("Pass Op"), tr("Fail Op"), tr("Depth Fail Op")}, - rows); - } - else - { - xml.writeStartElement(lit("p")); - xml.writeCharacters(tr("Disabled")); - xml.writeEndElement(); - } - } -} - -void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, VKPipe::CurrentPass &pass) -{ - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Framebuffer")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("Width"), tr("Height"), tr("Layers")}, - {pass.framebuffer.width, pass.framebuffer.height, pass.framebuffer.layers}); - - QList rows; - - int i = 0; - for(const VKPipe::Attachment &a : pass.framebuffer.attachments) - { - TextureDescription *tex = m_Ctx.GetTexture(a.img); - - QString name = tr("Image %1").arg(ToQStr(a.img)); - - if(tex) - name = ToQStr(tex->name); - - rows.push_back({i, name, a.baseMip, a.numMip, a.baseLayer, a.numLayer}); - - i++; - } - - m_Common.exportHTMLTable(xml, - { - tr("Slot"), tr("Image"), tr("First mip"), tr("Number of mips"), - tr("First array layer"), tr("Number of layers"), - }, - rows); - } - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Render Pass")); - xml.writeEndElement(); - - if(pass.renderpass.inputAttachments.count > 0) - { - QList inputs; - - for(int i = 0; i < pass.renderpass.inputAttachments.count; i++) - inputs.push_back({pass.renderpass.inputAttachments[i]}); - - m_Common.exportHTMLTable(xml, - { - tr("Input Attachment"), - }, - inputs); - - xml.writeStartElement(lit("p")); - xml.writeEndElement(); - } - - if(pass.renderpass.colorAttachments.count > 0) - { - QList colors; - - for(int i = 0; i < pass.renderpass.colorAttachments.count; i++) - colors.push_back({pass.renderpass.colorAttachments[i]}); - - m_Common.exportHTMLTable(xml, - { - tr("Color Attachment"), - }, - colors); - - xml.writeStartElement(lit("p")); - xml.writeEndElement(); - } - - if(pass.renderpass.depthstencilAttachment >= 0) - { - xml.writeStartElement(lit("p")); - xml.writeCharacters( - tr("Depth-stencil Attachment: %1").arg(pass.renderpass.depthstencilAttachment)); - xml.writeEndElement(); - } - } - - { - xml.writeStartElement(lit("h3")); - xml.writeCharacters(tr("Render Area")); - xml.writeEndElement(); - - m_Common.exportHTMLTable( - xml, {tr("X"), tr("Y"), tr("Width"), tr("Height")}, - {pass.renderArea.x, pass.renderArea.y, pass.renderArea.width, pass.renderArea.height}); - } -} - -void VulkanPipelineStateViewer::on_exportHTML_clicked() -{ - QXmlStreamWriter *xmlptr = m_Common.beginHTMLExport(); - - if(xmlptr) - { - QXmlStreamWriter &xml = *xmlptr; - - const QStringList &stageNames = ui->pipeFlow->stageNames(); - const QStringList &stageAbbrevs = ui->pipeFlow->stageAbbreviations(); - - int stage = 0; - for(const QString &sn : stageNames) - { - xml.writeStartElement(lit("div")); - xml.writeStartElement(lit("a")); - xml.writeAttribute(lit("name"), stageAbbrevs[stage]); - xml.writeEndElement(); - xml.writeEndElement(); - - xml.writeStartElement(lit("div")); - xml.writeAttribute(lit("class"), lit("stage")); - - xml.writeStartElement(lit("h1")); - xml.writeCharacters(sn); - xml.writeEndElement(); - - switch(stage) - { - case 0: - // VTX - xml.writeStartElement(lit("h2")); - xml.writeCharacters(tr("Input Assembly")); - xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().IA); - - xml.writeStartElement(lit("h2")); - xml.writeCharacters(tr("Vertex Input")); - xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().VI); - break; - case 1: exportHTML(xml, m_Ctx.CurVulkanPipelineState().m_VS); break; - case 2: exportHTML(xml, m_Ctx.CurVulkanPipelineState().m_TCS); break; - case 3: exportHTML(xml, m_Ctx.CurVulkanPipelineState().m_TES); break; - case 4: exportHTML(xml, m_Ctx.CurVulkanPipelineState().m_GS); break; - case 5: exportHTML(xml, m_Ctx.CurVulkanPipelineState().RS); break; - case 6: exportHTML(xml, m_Ctx.CurVulkanPipelineState().m_FS); break; - case 7: - // FB - xml.writeStartElement(lit("h2")); - xml.writeCharacters(tr("Color Blend")); - xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().CB); - - xml.writeStartElement(lit("h2")); - xml.writeCharacters(tr("Depth Stencil")); - xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().DS); - - xml.writeStartElement(lit("h2")); - xml.writeCharacters(tr("Current Pass")); - xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().Pass); - break; - case 8: exportHTML(xml, m_Ctx.CurVulkanPipelineState().m_CS); break; - } - - xml.writeEndElement(); - - stage++; - } - - m_Common.endHTMLExport(xmlptr); - } -} - -void VulkanPipelineStateViewer::on_meshView_clicked() -{ - if(!m_Ctx.HasMeshPreview()) - m_Ctx.ShowMeshPreview(); - ToolWindowManager::raiseToolWindow(m_Ctx.GetMeshPreview()->Widget()); -} diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h deleted file mode 100644 index 18b6e3615..000000000 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.h +++ /dev/null @@ -1,135 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -namespace Ui -{ -class VulkanPipelineStateViewer; -} - -class QXmlStreamWriter; - -class RDTreeWidget; -class RDTreeWidgetItem; -class PipelineStateViewer; - -struct SamplerData -{ - SamplerData() : node(NULL) {} - QList images; - RDTreeWidgetItem *node; -}; - -class VulkanPipelineStateViewer : public QFrame, public ILogViewer -{ - Q_OBJECT - -public: - explicit VulkanPipelineStateViewer(ICaptureContext &ctx, PipelineStateViewer &common, - QWidget *parent = 0); - ~VulkanPipelineStateViewer(); - - void OnLogfileLoaded(); - void OnLogfileClosed(); - void OnSelectedEventChanged(uint32_t eventID) {} - void OnEventChanged(uint32_t eventID); - -private slots: - // automatic slots - void on_showDisabled_toggled(bool checked); - void on_showEmpty_toggled(bool checked); - void on_exportHTML_clicked(); - void on_meshView_clicked(); - void on_viAttrs_itemActivated(RDTreeWidgetItem *item, int column); - void on_viBuffers_itemActivated(RDTreeWidgetItem *item, int column); - void on_viAttrs_mouseMove(QMouseEvent *event); - void on_viBuffers_mouseMove(QMouseEvent *event); - void on_pipeFlow_stageSelected(int index); - - // manual slots - void shaderView_clicked(); - void shaderLabel_clicked(QMouseEvent *event); - void shaderEdit_clicked(); - - void shaderSave_clicked(); - void resource_itemActivated(RDTreeWidgetItem *item, int column); - void ubo_itemActivated(RDTreeWidgetItem *item, int column); - void vertex_leave(QEvent *e); - -private: - Ui::VulkanPipelineStateViewer *ui; - ICaptureContext &m_Ctx; - PipelineStateViewer &m_Common; - - QVariantList makeSampler(const QString &bindset, const QString &slotname, - const VKPipe::BindingElement &descriptor); - void addResourceRow(ShaderReflection *shaderDetails, const VKPipe::Shader &stage, int bindset, - int bind, const VKPipe::Pipeline &pipe, RDTreeWidget *resources, - QMap &samplers); - void addConstantBlockRow(ShaderReflection *shaderDetails, const VKPipe::Shader &stage, - int bindset, int bind, const VKPipe::Pipeline &pipe, RDTreeWidget *ubos); - - void setShaderState(const VKPipe::Shader &stage, const VKPipe::Pipeline &pipe, QLabel *shader, - RDTreeWidget *res, RDTreeWidget *ubo); - void clearShaderState(QLabel *shader, RDTreeWidget *res, RDTreeWidget *ubo); - void setState(); - void clearState(); - - void setInactiveRow(RDTreeWidgetItem *node); - void setEmptyRow(RDTreeWidgetItem *node); - void highlightIABind(int slot); - - QString formatMembers(int indent, const QString &nameprefix, - const rdctype::array &vars); - const VKPipe::Shader *stageForSender(QWidget *widget); - - QString disassembleSPIRV(const ShaderReflection *shaderDetails); - - template - void setViewDetails(RDTreeWidgetItem *node, const viewType &view, TextureDescription *tex); - - template - void setViewDetails(RDTreeWidgetItem *node, const viewType &view, BufferDescription *buf); - - bool showNode(bool usedSlot, bool filledSlot); - - void exportHTML(QXmlStreamWriter &xml, VKPipe::VertexInput &vi); - void exportHTML(QXmlStreamWriter &xml, VKPipe::InputAssembly &ia); - void exportHTML(QXmlStreamWriter &xml, VKPipe::Shader &sh); - void exportHTML(QXmlStreamWriter &xml, VKPipe::Raster &rs); - void exportHTML(QXmlStreamWriter &xml, VKPipe::ColorBlend &cb); - void exportHTML(QXmlStreamWriter &xml, VKPipe::DepthStencil &ds); - void exportHTML(QXmlStreamWriter &xml, VKPipe::CurrentPass &pass); - - // keep track of the VB nodes (we want to be able to highlight them easily on hover) - QList m_VBNodes; - QList m_BindNodes; - - // from an combined image to its sampler (since we de-duplicate) - QMap m_CombinedImageSamplers; -}; diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui deleted file mode 100644 index 1f714a7f6..000000000 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.ui +++ /dev/null @@ -1,3329 +0,0 @@ - - - VulkanPipelineStateViewer - - - - 0 - 0 - 911 - 566 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::Panel - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Display Controls - - - 4 - - - - - - - Qt::Vertical - - - - - - - Show Disabled Items - - - Show Disabled Items - - - - :/page_white_delete.png:/page_white_delete.png - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Show Empty Items - - - Show Empty Items - - - - :/page_white_database.png:/page_white_database.png - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Export the current pipeline state to an HTML file - - - Export - - - - :/save.png:/save.png - - - false - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 12 - - - - - - - - 0 - - - true - - - - Vertex Input - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 511 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Attributes - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - 0 - - - false - - - false - - - true - - - false - - - false - - - - - - - - - - - 0 - 0 - - - - Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - 0 - - - false - - - false - - - true - - - false - - - false - - - - - - - - - - - 0 - 0 - - - - Mesh View - - - - - - - 0 - 0 - - - - - 75 - 75 - - - - PointingHandCursor - - - View the mesh input data - - - :/wireframe_mesh.png - - - true - - - - - - - - - - - 0 - 0 - - - - Primitive Topology - - - - - - - 14 - - - - Triangle List - - - Qt::AlignHCenter|Qt::AlignTop - - - - - - - - 0 - 0 - - - - - 256 - 0 - - - - - - - :/topologies/topo_trilist.svg - - - Qt::AlignCenter - - - - - - - - 14 - - - - Primitive Restart Enabled - - - Qt::AlignBottom|Qt::AlignHCenter - - - - - - - - - - - - - - - Vertex Shader - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Shader - - - - 0 - - - 0 - - - 4 - - - - - - 250 - 0 - - - - PointingHandCursor - - - Open Shader Source - - - QFrame::Box - - - - - - - - - - PointingHandCursor - - - Open Shader Source - - - View - - - - :/action.png:/action.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Edit Shader - - - Edit - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save Shader SPIR-V - - - Save - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 576 - 20 - - - - - - - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 462 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Resources - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Uniform Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - - - - - Tess Control Shader - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Shader - - - - 0 - - - 0 - - - 4 - - - - - - 250 - 0 - - - - PointingHandCursor - - - Open Shader Source - - - QFrame::Box - - - - - - - - - - PointingHandCursor - - - Open Shader Source - - - View - - - - :/action.png:/action.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Edit Shader - - - Edit - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save Shader SPIR-V - - - Save - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 576 - 20 - - - - - - - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 462 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Resources - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Uniform Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - - - - - Tess Eval Shader - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Shader - - - - 0 - - - 0 - - - 4 - - - - - - 250 - 0 - - - - PointingHandCursor - - - Open Shader Source - - - QFrame::Box - - - - - - - - - - PointingHandCursor - - - Open Shader Source - - - View - - - - :/action.png:/action.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Edit Shader - - - Edit - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save Shader SPIR-V - - - Save - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 576 - 20 - - - - - - - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 462 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Resources - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Uniform Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - - - - - Geometry Shader - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Shader - - - - 0 - - - 0 - - - 4 - - - - - - 250 - 0 - - - - PointingHandCursor - - - Open Shader Source - - - QFrame::Box - - - - - - - - - - PointingHandCursor - - - Open Shader Source - - - View - - - - :/action.png:/action.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Edit Shader - - - Edit - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save Shader SPIR-V - - - Save - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 576 - 20 - - - - - - - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 462 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Resources - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Uniform Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - - - - - Rasterizer - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Rasterizer State - - - - 2 - - - 2 - - - 2 - - - 2 - - - 0 - - - - - Depth Bias Clamp: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Fill Mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0.00 - - - Qt::AlignCenter - - - 4 - - - - - - - Slope-Scaled Bias: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - Solid - - - Qt::AlignCenter - - - 4 - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Front CCW: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Cull Mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Depth Bias: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Line Width: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - None - - - Qt::AlignCenter - - - 4 - - - - - - - - 12 - - - - 0.00 - - - Qt::AlignCenter - - - 4 - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Rasterizer Discard: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Depth Clamp: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - - 12 - - - - 0.00 - - - Qt::AlignCenter - - - 4 - - - - - - - - 12 - - - - 0.00 - - - Qt::AlignCenter - - - 4 - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - QSizePolicy::Preferred - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - Scissor Regions - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - 0 - - - false - - - true - - - 50 - - - - - - - - - - - 0 - 0 - - - - Viewports - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - 0 - - - false - - - true - - - 50 - - - - - - - - - - Multisample State - - - - 2 - - - 2 - - - 2 - - - 2 - - - 0 - - - - - Min Sample Shading: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0 - - - Qt::AlignCenter - - - 4 - - - - - - - Sample Mask: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - Sample Shading: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0.00 - - - Qt::AlignCenter - - - 4 - - - - - - - Sample Count: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - FFFFFFFF - - - Qt::AlignCenter - - - 4 - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 0 - 0 - - - - - - - - Alpha to 1: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Alpha to Coverage: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - - - - - Fragment Shader - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Shader - - - - 0 - - - 0 - - - 4 - - - - - - 250 - 0 - - - - PointingHandCursor - - - Open Shader Source - - - QFrame::Box - - - - - - - - - - PointingHandCursor - - - Open Shader Source - - - View - - - - :/action.png:/action.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Edit Shader - - - Edit - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save Shader SPIR-V - - - Save - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 576 - 20 - - - - - - - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 462 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Resources - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Uniform Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - - - - - Framebuffer - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 511 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Framebuffer Attachments - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoEditTriggers - - - false - - - 0 - - - false - - - false - - - true - - - false - - - false - - - - - - - - - - - 0 - 0 - - - - Target Blends - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoEditTriggers - - - false - - - 0 - - - false - - - false - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Blend State - - - - 2 - - - 2 - - - 2 - - - 2 - - - 0 - - - - - Blend Factor: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0.00, 0.00, 0.00, 0.00 - - - Qt::AlignCenter - - - 4 - - - - - - - Logic Op: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - - - - - Qt::AlignCenter - - - 4 - - - - - - - - - - - 0 - 0 - - - - Depth State - - - - 2 - - - 2 - - - 2 - - - 2 - - - 0 - - - - - Enabled: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Bounds: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Write: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Func: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 12 - - - - GREATER_EQUAL - - - Qt::AlignCenter - - - 4 - - - - - - - - - - - 0 - 0 - - - - Stencil State - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - 0 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - 0 - 0 - - - - QFrame::Box - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAsNeeded - - - QAbstractScrollArea::AdjustToContents - - - QAbstractItemView::NoEditTriggers - - - false - - - QAbstractItemView::NoSelection - - - 0 - - - false - - - false - - - true - - - false - - - false - - - - - - - - - - - - - - - Compute Shader - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Shader - - - - 0 - - - 0 - - - 4 - - - - - - 250 - 0 - - - - PointingHandCursor - - - Open Shader Source - - - QFrame::Box - - - - - - - - - - PointingHandCursor - - - Open Shader Source - - - View - - - - :/action.png:/action.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Edit Shader - - - Edit - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save Shader SPIR-V - - - Save - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 576 - 20 - - - - - - - - - - - QFrame::NoFrame - - - true - - - - - 0 - 0 - 911 - 462 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Resources - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - 0 - 0 - - - - Uniform Buffers - - - - 2 - - - 2 - - - 2 - - - 2 - - - - - QFrame::Box - - - QFrame::Plain - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - true - - - false - - - - - - - - - - - - - - - - - - - RDLabel - QLabel -
Widgets/Extended/RDLabel.h
-
- - RDTreeWidget - QTreeView -
Widgets/Extended/RDTreeWidget.h
-
- - PipelineFlowChart - QFrame -
Widgets/PipelineFlowChart.h
- 1 -
-
- - - - -
diff --git a/qrenderdoc/Windows/PixelHistoryView.cpp b/qrenderdoc/Windows/PixelHistoryView.cpp deleted file mode 100644 index 16bf24464..000000000 --- a/qrenderdoc/Windows/PixelHistoryView.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "PixelHistoryView.h" -#include -#include -#include -#include -#include "3rdparty/toolwindowmanager/ToolWindowManager.h" -#include "ui_PixelHistoryView.h" - -struct EventTag -{ - uint32_t eventID = 0; - uint32_t primitive = ~0U; -}; - -Q_DECLARE_METATYPE(EventTag); - -class PixelHistoryItemModel : public QAbstractItemModel -{ -public: - PixelHistoryItemModel(ICaptureContext &ctx, ResourceId tex, const TextureDisplay &display, - QObject *parent) - : QAbstractItemModel(parent), m_Ctx(ctx) - { - m_Tex = m_Ctx.GetTexture(tex); - m_Display = display; - - CompType compType = m_Tex->format.compType; - - if(compType == CompType::Typeless) - compType = display.typeHint; - - m_IsUint = (compType == CompType::UInt); - m_IsSint = (compType == CompType::SInt); - m_IsFloat = (!m_IsUint && !m_IsSint); - - if(compType == CompType::Depth) - m_IsDepth = true; - - if(m_Tex->format.special) - { - switch(m_Tex->format.specialFormat) - { - case SpecialFormat::D16S8: - case SpecialFormat::D24S8: - case SpecialFormat::D32S8: - case SpecialFormat::S8: m_IsDepth = true; break; - default: break; - } - } - } - - void setHistory(const rdctype::array &history) - { - m_ModList.reserve(history.count); - for(const PixelModification &h : history) - m_ModList.push_back(h); - - m_Loading = false; - - emit beginResetModel(); - - setShowFailures(true); - - emit endResetModel(); - } - - void setShowFailures(bool show) - { - emit beginResetModel(); - - m_History.clear(); - m_History.reserve(m_ModList.count()); - for(const PixelModification &h : m_ModList) - { - if(!show && !h.passed()) - continue; - - if(m_History.isEmpty() || m_History.back().back().eventID != h.eventID) - m_History.push_back({h}); - else - m_History.back().push_back(h); - } - - emit endResetModel(); - } - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override - { - if(row < 0 || row >= rowCount(parent) || column < 0 || column >= columnCount()) - return QModelIndex(); - - return createIndex(row, column, makeTag(row, parent)); - } - - QModelIndex parent(const QModelIndex &index) const override - { - if(m_Loading || isEvent(index)) - return QModelIndex(); - - int eventRow = getEventRow(index); - - return createIndex(eventRow, 0, makeTag(eventRow, QModelIndex())); - } - int rowCount(const QModelIndex &parent = QModelIndex()) const override - { - if(m_Loading) - return parent.isValid() ? 0 : 1; - - if(!parent.isValid()) - return m_History.count(); - - if(isEvent(parent)) - { - const QList &mods = getMods(parent); - const DrawcallDescription *draw = m_Ctx.GetDrawcall(mods.front().eventID); - - if(draw && draw->flags & DrawFlags::Clear) - return 0; - - return mods.count(); - } - - return 0; - } - int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 5; } - Qt::ItemFlags flags(const QModelIndex &index) const override - { - if(!index.isValid()) - return 0; - - return QAbstractItemModel::flags(index); - } - - QVariant headerData(int section, Qt::Orientation orientation, int role) const override - { - if(orientation == Qt::Horizontal && role == Qt::DisplayRole && section == 0) - return lit("Event"); - - // sizes for the colour previews - if(orientation == Qt::Horizontal && role == Qt::SizeHintRole && (section == 2 || section == 4)) - return QSize(18, 0); - - return QVariant(); - } - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override - { - if(index.isValid()) - { - int col = index.column(); - - // preview columns - if(col == 2 || col == 4) - { - if(role == Qt::SizeHintRole) - return QSize(16, 0); - } - - if(m_Loading) - { - if(role == Qt::DisplayRole && col == 0) - return tr("Loading..."); - - return QVariant(); - } - - if(role == Qt::DisplayRole) - { - // main text - if(col == 0) - { - if(isEvent(index)) - { - const QList &mods = getMods(index); - const DrawcallDescription *drawcall = m_Ctx.GetDrawcall(mods.front().eventID); - if(!drawcall) - return QVariant(); - - QString ret; - QList drawstack; - const DrawcallDescription *parent = m_Ctx.GetDrawcall(drawcall->parent); - while(parent) - { - drawstack.push_back(parent); - parent = m_Ctx.GetDrawcall(parent->parent); - } - - if(!drawstack.isEmpty()) - { - ret += lit("> ") + ToQStr(drawstack.back()->name); - - if(drawstack.count() > 3) - ret += lit(" ..."); - - ret += lit("\n"); - - if(drawstack.count() > 2) - ret += lit("> ") + ToQStr(drawstack[1]->name) + lit("\n"); - if(drawstack.count() > 1) - ret += lit("> ") + ToQStr(drawstack[0]->name) + lit("\n"); - - ret += lit("\n"); - } - - bool passed = true; - bool uavnowrite = false; - - if(mods.front().directShaderWrite) - { - ret += tr("EID %1\n%2\nBound as UAV or copy - potential modification") - .arg(mods.front().eventID) - .arg(ToQStr(drawcall->name)); - - if(memcmp(mods[0].preMod.col.value_u, mods[0].postMod.col.value_u, - sizeof(uint32_t) * 4) == 0) - { - ret += tr("\nNo change in tex value"); - uavnowrite = true; - } - } - else - { - passed = false; - for(const PixelModification &m : mods) - passed |= m.passed(); - - QString failure = passed ? QString() : failureString(mods[0]); - - ret += tr("EID %1\n%2%3\n%4 Fragments touching pixel\n") - .arg(mods.front().eventID) - .arg(ToQStr(drawcall->name)) - .arg(failure) - .arg(mods.count()); - } - - return ret; - } - else - { - const PixelModification &mod = getMod(index); - - if(mod.directShaderWrite) - { - QString ret = tr("Potential UAV/Copy write"); - - if(mod.preMod.col.value_u[0] == mod.postMod.col.value_u[0] && - mod.preMod.col.value_u[1] == mod.postMod.col.value_u[1] && - mod.preMod.col.value_u[2] == mod.postMod.col.value_u[2] && - mod.preMod.col.value_u[3] == mod.postMod.col.value_u[3]) - { - ret += tr("\nNo change in tex value"); - } - - return ret; - } - else - { - QString ret = tr("Primitive %1\n").arg(mod.primitiveID); - - if(mod.shaderDiscarded) - ret += failureString(mod); - - return ret; - } - } - } - - // pre mod/shader out text - if(col == 1) - { - if(isEvent(index)) - { - return tr("Tex Before\n\n") + modString(getMods(index).first().preMod); - } - else - { - const PixelModification &mod = getMod(index); - if(mod.unboundPS) - return tr("No Pixel\nShader\nBound"); - if(mod.directShaderWrite) - return tr("Tex Before\n\n") + modString(mod.preMod); - return tr("Shader Out\n\n") + modString(mod.shaderOut); - } - } - - // post mod text - if(col == 3) - { - if(isEvent(index)) - return tr("Tex After\n\n") + modString(getMods(index).last().postMod); - else - return tr("Tex After\n\n") + modString(getMod(index).shaderOut); - } - } - - if(role == Qt::BackgroundRole && (m_IsDepth || m_IsFloat)) - { - // pre mod color - if(col == 2) - { - if(isEvent(index)) - return backgroundBrush(getMods(index).first().preMod); - else - return backgroundBrush(getMod(index).shaderOut); - } - else if(col == 4) - { - if(isEvent(index)) - return backgroundBrush(getMods(index).last().postMod); - else - return backgroundBrush(getMod(index).postMod); - } - } - - // text backgrounds marking pass/fail - if(role == Qt::BackgroundRole && (col == 0 || col == 1 || col == 3)) - { - // rest - if(isEvent(index)) - { - const QList &mods = getMods(index); - - bool passed = false; - for(const PixelModification &m : mods) - passed |= m.passed(); - - if(mods[0].directShaderWrite && - memcmp(mods[0].preMod.col.value_u, mods[0].postMod.col.value_u, sizeof(uint32_t) * 4) == - 0) - return QBrush(QColor::fromRgb(235, 235, 235)); - - return passed ? QBrush(QColor::fromRgb(235, 255, 235)) - : QBrush(QColor::fromRgb(255, 235, 235)); - } - else - { - if(getMod(index).shaderDiscarded) - return QBrush(QColor::fromRgb(255, 235, 235)); - } - } - - if(role == Qt::UserRole) - { - EventTag tag; - - if(isEvent(index)) - { - tag.eventID = getMods(index).first().eventID; - } - else - { - const PixelModification &mod = getMod(index); - - tag.eventID = mod.eventID; - if(!mod.directShaderWrite) - tag.primitive = mod.primitiveID; - } - - return QVariant::fromValue(tag); - } - } - - return QVariant(); - } - - const QVector &modifications() { return m_ModList; } - ResourceId texID() { return m_Tex->ID; } -private: - ICaptureContext &m_Ctx; - - const TextureDescription *m_Tex; - TextureDisplay m_Display; - bool m_IsDepth = false, m_IsUint = false, m_IsSint = false, m_IsFloat = true; - - bool m_Loading = true; - QVector> m_History; - QVector m_ModList; - - // mask for top bit of quintptr - static const quintptr eventTagMask = 1ULL << (Q_PROCESSOR_WORDSIZE * 8 - 1); - - // 1 byte on 32-bit, 2 bytes on 64-bit - static const quintptr modRowBits = Q_PROCESSOR_WORDSIZE * 2; - - // mask without top bit and however many bits we have for modification mask - static const quintptr eventRowMask = UINTPTR_MAX >> (1 + modRowBits); - - static const quintptr modRowMask = (1 << modRowBits) - 1; - - inline bool isEvent(QModelIndex parent) const { return parent.internalId() & eventTagMask; } - int getEventRow(QModelIndex index) const - { - if(isEvent(index)) - return index.row(); - else - return (index.internalId() & ~eventTagMask) >> modRowBits; - } - - int getModRow(QModelIndex index) const { return int(index.internalId() & modRowMask); } - const QList &getMods(QModelIndex index) const - { - return m_History[index.row()]; - } - - const PixelModification &getMod(QModelIndex index) const - { - return m_History[getEventRow(index)][getModRow(index)]; - } - - quintptr makeTag(int row, QModelIndex parent) const - { - if(!parent.isValid()) - { - // event - return eventTagMask | row; - } - else - { - // modification - if(quintptr(row) > modRowMask) - qCritical() << "Packing failure - more than 255 modifications in one event"; - - return ((parent.internalId() & eventRowMask) << modRowBits) | (quintptr(row) & modRowMask); - } - } - - QBrush backgroundBrush(const ModificationValue &val) const - { - float rangesize = (m_Display.rangemax - m_Display.rangemin); - - float r = val.col.value_f[0]; - float g = val.col.value_f[1]; - float b = val.col.value_f[2]; - - if(!m_Display.Red) - r = 0.0f; - if(!m_Display.Green) - g = 0.0f; - if(!m_Display.Blue) - b = 0.0f; - - if(m_Display.Red && !m_Display.Green && !m_Display.Blue && !m_Display.Alpha) - g = b = r; - if(!m_Display.Red && m_Display.Green && !m_Display.Blue && !m_Display.Alpha) - r = b = g; - if(!m_Display.Red && !m_Display.Green && m_Display.Blue && !m_Display.Alpha) - g = r = b; - if(!m_Display.Red && !m_Display.Green && !m_Display.Blue && m_Display.Alpha) - g = b = r = val.col.value_f[3]; - - r = qBound(0.0f, (r - m_Display.rangemin) / rangesize, 1.0f); - g = qBound(0.0f, (g - m_Display.rangemin) / rangesize, 1.0f); - b = qBound(0.0f, (b - m_Display.rangemin) / rangesize, 1.0f); - - if(m_IsDepth) - r = g = b = qBound(0.0f, (val.depth - m_Display.rangemin) / rangesize, 1.0f); - - { - r = (float)powf(r, 1.0f / 2.2f); - g = (float)powf(g, 1.0f / 2.2f); - b = (float)powf(b, 1.0f / 2.2f); - } - - return QBrush(QColor::fromRgb((int)(255.0f * r), (int)(255.0f * g), (int)(255.0f * b))); - } - - QString modString(const ModificationValue &val) const - { - QString s; - - int numComps = (int)(m_Tex->format.compCount); - - static const QString colourLetterPrefix[] = {lit("R: "), lit("G: "), lit("B: "), lit("A: ")}; - - if(!m_IsDepth) - { - if(m_IsUint) - { - for(int i = 0; i < numComps; i++) - s += colourLetterPrefix[i] + Formatter::Format(val.col.value_u[i]) + lit("\n"); - } - else if(m_IsSint) - { - for(int i = 0; i < numComps; i++) - s += colourLetterPrefix[i] + Formatter::Format(val.col.value_i[i]) + lit("\n"); - } - else - { - for(int i = 0; i < numComps; i++) - s += colourLetterPrefix[i] + Formatter::Format(val.col.value_f[i]) + lit("\n"); - } - } - - if(val.depth >= 0.0f) - s += lit("\nD: ") + Formatter::Format(val.depth); - else if(val.depth < -1.5f) - s += lit("\nD: ?"); - else - s += lit("\nD: -"); - - if(val.stencil >= 0) - s += lit("\nS: 0x") + Formatter::Format(uint8_t(val.stencil & 0xff), true); - else if(val.stencil == -2) - s += lit("\nS: ?"); - else - s += lit("\nS: -"); - - return s; - } - - QString failureString(const PixelModification &mod) const - { - QString s; - - if(mod.sampleMasked) - s += tr("\nMasked by SampleMask"); - if(mod.backfaceCulled) - s += tr("\nBackface culled"); - if(mod.depthClipped) - s += tr("\nDepth Clipped"); - if(mod.scissorClipped) - s += tr("\nScissor Clipped"); - if(mod.shaderDiscarded) - s += tr("\nShader executed a discard"); - if(mod.depthTestFailed) - s += tr("\nDepth test failed"); - if(mod.stencilTestFailed) - s += tr("\nStencil test failed"); - - return s; - } -}; - -PixelHistoryView::PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint point, - const TextureDisplay &display, QWidget *parent) - : QFrame(parent), ui(new Ui::PixelHistoryView), m_Ctx(ctx) -{ - ui->setupUi(this); - - ui->events->setFont(Formatter::PreferredFont()); - - m_Pixel = point; - m_Display = display; - - TextureDescription *tex = m_Ctx.GetTexture(id); - - QString title = - tr("Pixel History on %1 for (%2, %3)").arg(ToQStr(tex->name)).arg(point.x()).arg(point.y()); - if(tex->msSamp > 1) - title += tr(" @ Sample %1").arg(display.sampleIdx); - setWindowTitle(title); - - QString channelStr; - if(display.Red) - channelStr += lit("R"); - if(display.Green) - channelStr += lit("G"); - if(display.Blue) - channelStr += lit("B"); - - if(channelStr.length() > 1) - channelStr += tr(" channels"); - else - channelStr += tr(" channel"); - - if(!display.Red && !display.Green && !display.Blue && display.Alpha) - channelStr = lit("Alpha"); - - QString text; - text = tr("Preview colours displayed in visible range %1 - %2 with %3 visible.\n\n") - .arg(Formatter::Format(display.rangemin)) - .arg(Formatter::Format(display.rangemax)) - .arg(channelStr); - text += - tr("Double click to jump to an event.\n" - "Right click to debug an event, or hide failed events."); - - ui->label->setText(text); - - ui->eventsHidden->setVisible(false); - - m_Model = new PixelHistoryItemModel(ctx, id, display, this); - ui->events->setModel(m_Model); - - ui->events->hideBranches(); - - ui->events->header()->setSectionResizeMode(0, QHeaderView::Stretch); - ui->events->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - ui->events->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents); - ui->events->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents); - ui->events->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents); - - m_Ctx.AddLogViewer(this); -} - -PixelHistoryView::~PixelHistoryView() -{ - disableTimelineHighlight(); - - ui->events->setModel(NULL); - m_Ctx.RemoveLogViewer(this); - delete ui; -} - -void PixelHistoryView::enableTimelineHighlight() -{ - if(m_Ctx.HasTimelineBar()) - m_Ctx.GetTimelineBar()->HighlightHistory(m_Model->texID(), m_Model->modifications().toList()); -} - -void PixelHistoryView::disableTimelineHighlight() -{ - if(m_Ctx.HasTimelineBar()) - m_Ctx.GetTimelineBar()->HighlightHistory(ResourceId(), {}); -} - -void PixelHistoryView::enterEvent(QEvent *event) -{ - enableTimelineHighlight(); -} - -void PixelHistoryView::leaveEvent(QEvent *event) -{ - disableTimelineHighlight(); -} - -void PixelHistoryView::OnLogfileLoaded() -{ -} - -void PixelHistoryView::OnLogfileClosed() -{ - ToolWindowManager::closeToolWindow(this); -} - -void PixelHistoryView::SetHistory(const rdctype::array &history) -{ - m_Model->setHistory(history); - - enableTimelineHighlight(); -} - -void PixelHistoryView::startDebug(EventTag tag) -{ - m_Ctx.SetEventID({this}, tag.eventID, tag.eventID); - - ShaderDebugTrace *trace = NULL; - - m_Ctx.Replay().BlockInvoke([this, &trace](IReplayController *r) { - trace = r->DebugPixel((uint32_t)m_Pixel.x(), (uint32_t)m_Pixel.y(), m_Display.sampleIdx, ~0U); - }); - - if(trace->states.count == 0) - { - RDDialog::critical(this, tr("Debug Error"), tr("Error debugging pixel.")); - m_Ctx.Replay().AsyncInvoke([trace](IReplayController *r) { r->FreeTrace(trace); }); - return; - } - - GUIInvoke::call([this, trace]() { - QString debugContext = QFormatStr("Pixel %1,%2").arg(m_Pixel.x()).arg(m_Pixel.y()); - - const ShaderReflection *shaderDetails = - m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Pixel); - const ShaderBindpointMapping &bindMapping = - m_Ctx.CurPipelineState().GetBindpointMapping(ShaderStage::Pixel); - - // viewer takes ownership of the trace - IShaderViewer *s = - m_Ctx.DebugShader(&bindMapping, shaderDetails, ShaderStage::Pixel, trace, debugContext); - - m_Ctx.AddDockWindow(s->Widget(), DockReference::MainToolArea, NULL); - }); -} - -void PixelHistoryView::jumpToPrimitive(EventTag tag) -{ - m_Ctx.SetEventID({this}, tag.eventID, tag.eventID); - m_Ctx.ShowMeshPreview(); - - IBufferViewer *viewer = m_Ctx.GetMeshPreview(); - - const DrawcallDescription *draw = m_Ctx.CurDrawcall(); - - if(draw) - { - uint32_t vertIdx = RENDERDOC_VertexOffset(draw->topology, tag.primitive); - - if(vertIdx != ~0U) - viewer->ScrollToRow(vertIdx); - } -} - -void PixelHistoryView::on_events_customContextMenuRequested(const QPoint &pos) -{ - QModelIndex index = ui->events->indexAt(pos); - - QMenu contextMenu(this); - - QAction hideFailed(tr("&Show failed events"), this); - hideFailed.setCheckable(true); - hideFailed.setChecked(m_ShowFailures); - - contextMenu.addAction(&hideFailed); - - QObject::connect(&hideFailed, &QAction::toggled, [this](bool checked) { - m_Model->setShowFailures(m_ShowFailures = checked); - ui->eventsHidden->setVisible(!m_ShowFailures); - }); - - if(!index.isValid()) - { - RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos)); - return; - } - - EventTag tag = m_Model->data(index, Qt::UserRole).value(); - if(tag.eventID == 0) - { - RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos)); - return; - } - - QAction jumpAction(tr("&Go to primitive %1 at Event %2").arg(tag.primitive).arg(tag.eventID), this); - - QString debugText; - - if(tag.primitive == ~0U) - { - debugText = - tr("&Debug Pixel (%1, %2) at Event %3").arg(m_Pixel.x()).arg(m_Pixel.y()).arg(tag.eventID); - } - else - { - debugText = tr("&Debug Pixel (%1, %2) primitive %3 at Event %4") - .arg(m_Pixel.x()) - .arg(m_Pixel.y()) - .arg(tag.eventID) - .arg(tag.primitive); - - contextMenu.addAction(&jumpAction); - } - - QAction debugAction(debugText, this); - - contextMenu.addAction(&debugAction); - - QObject::connect(&jumpAction, &QAction::triggered, [this, tag]() { jumpToPrimitive(tag); }); - QObject::connect(&debugAction, &QAction::triggered, [this, tag]() { startDebug(tag); }); - - RDDialog::show(&contextMenu, ui->events->viewport()->mapToGlobal(pos)); -} - -void PixelHistoryView::on_events_doubleClicked(const QModelIndex &index) -{ - EventTag tag = m_Model->data(index, Qt::UserRole).value(); - if(tag.eventID > 0) - m_Ctx.SetEventID({this}, tag.eventID, tag.eventID); -} - -// TODO TimelineBar diff --git a/qrenderdoc/Windows/PixelHistoryView.h b/qrenderdoc/Windows/PixelHistoryView.h deleted file mode 100644 index 0c1f1842e..000000000 --- a/qrenderdoc/Windows/PixelHistoryView.h +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -namespace Ui -{ -class PixelHistoryView; -} - -class PixelHistoryItemModel; -struct EventTag; - -class PixelHistoryView : public QFrame, public IPixelHistoryView, public ILogViewer -{ - Q_OBJECT - -public: - explicit PixelHistoryView(ICaptureContext &ctx, ResourceId id, QPoint point, - const TextureDisplay &display, QWidget *parent = 0); - ~PixelHistoryView(); - - // IPixelHistoryView - QWidget *Widget() override { return this; } - void SetHistory(const rdctype::array &history) override; - - // ILogViewerForm - void OnLogfileLoaded() override; - void OnLogfileClosed() override; - void OnSelectedEventChanged(uint32_t eventID) override {} - void OnEventChanged(uint32_t eventID) override {} -private slots: - // automatic slots - void on_events_customContextMenuRequested(const QPoint &pos); - void on_events_doubleClicked(const QModelIndex &index); - -protected: - void enterEvent(QEvent *event) override; - void leaveEvent(QEvent *event) override; - -private: - void enableTimelineHighlight(); - void disableTimelineHighlight(); - - Ui::PixelHistoryView *ui; - ICaptureContext &m_Ctx; - - TextureDisplay m_Display; - QPoint m_Pixel; - PixelHistoryItemModel *m_Model; - bool m_ShowFailures = true; - void startDebug(EventTag tag); - void jumpToPrimitive(EventTag tag); -}; diff --git a/qrenderdoc/Windows/PixelHistoryView.ui b/qrenderdoc/Windows/PixelHistoryView.ui deleted file mode 100644 index 88a60b5f4..000000000 --- a/qrenderdoc/Windows/PixelHistoryView.ui +++ /dev/null @@ -1,109 +0,0 @@ - - - PixelHistoryView - - - - 0 - 0 - 662 - 569 - - - - Pixel History - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - ***code overwritten preview*** Preview colours displayed in visible range {min} - {max} with {red, blue, green} channels. - -Right click to debug an event, hide failed events, or jump to the modification's primitive in the mesh view. - - - true - - - - - - - - - - - - 200 - 0 - 0 - - - - - - - - - 200 - 0 - 0 - - - - - - - - - 106 - 104 - 100 - - - - - - - - Failed events are currently hidden - - - - - - - Qt::CustomContextMenu - - - 16 - - - false - - - - - - - - RDTreeView - QTreeView -
Widgets/Extended/RDTreeView.h
-
-
- - -
diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp deleted file mode 100644 index cf7f74df0..000000000 --- a/qrenderdoc/Windows/PythonShell.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "PythonShell.h" -#include -#include -#include -#include "3rdparty/scintilla/include/SciLexer.h" -#include "3rdparty/scintilla/include/qt/ScintillaEdit.h" -#include "Code/ScintillaSyntax.h" -#include "Code/pyrenderdoc/PythonContext.h" -#include "ui_PythonShell.h" - -// a forwarder that invokes onto the UI thread wherever necessary. -// Note this does NOT make CaptureContext thread safe. We just invoke for any potentially UI -// operations. All invokes are blocking, so there can't be any times when the UI thread waits -// on the python thread. -struct CaptureContextInvoker : ICaptureContext -{ - ICaptureContext &m_Ctx; - CaptureContextInvoker(ICaptureContext &ctx) : m_Ctx(ctx) {} - virtual ~CaptureContextInvoker() {} - // - /////////////////////////////////////////////////////////////////////// - // pass-through functions that don't need the UI thread - /////////////////////////////////////////////////////////////////////// - // - virtual QString ConfigFilePath(const QString &filename) override - { - return m_Ctx.ConfigFilePath(filename); - } - virtual QString TempLogFilename(QString appname) override - { - return m_Ctx.TempLogFilename(appname); - } - virtual IReplayManager &Replay() override { return m_Ctx.Replay(); } - virtual bool LogLoaded() override { return m_Ctx.LogLoaded(); } - virtual bool IsLogLocal() override { return m_Ctx.IsLogLocal(); } - virtual bool LogLoading() override { return m_Ctx.LogLoading(); } - virtual QString LogFilename() override { return m_Ctx.LogFilename(); } - virtual const FrameDescription &FrameInfo() override { return m_Ctx.FrameInfo(); } - virtual const APIProperties &APIProps() override { return m_Ctx.APIProps(); } - virtual uint32_t CurSelectedEvent() override { return m_Ctx.CurSelectedEvent(); } - virtual uint32_t CurEvent() override { return m_Ctx.CurEvent(); } - virtual const DrawcallDescription *CurSelectedDrawcall() override - { - return m_Ctx.CurSelectedDrawcall(); - } - virtual const DrawcallDescription *CurDrawcall() override { return m_Ctx.CurDrawcall(); } - virtual const DrawcallDescription *GetFirstDrawcall() override - { - return m_Ctx.GetFirstDrawcall(); - } - virtual const DrawcallDescription *GetLastDrawcall() override { return m_Ctx.GetLastDrawcall(); } - virtual const rdctype::array &CurDrawcalls() override - { - return m_Ctx.CurDrawcalls(); - } - virtual TextureDescription *GetTexture(ResourceId id) override { return m_Ctx.GetTexture(id); } - virtual const rdctype::array &GetTextures() override - { - return m_Ctx.GetTextures(); - } - virtual BufferDescription *GetBuffer(ResourceId id) override { return m_Ctx.GetBuffer(id); } - virtual const rdctype::array &GetBuffers() override - { - return m_Ctx.GetBuffers(); - } - virtual const DrawcallDescription *GetDrawcall(uint32_t eventID) override - { - return m_Ctx.GetDrawcall(eventID); - } - virtual WindowingSystem CurWindowingSystem() override { return m_Ctx.CurWindowingSystem(); } - virtual void *FillWindowingData(uintptr_t winId) override - { - return m_Ctx.FillWindowingData(winId); - } - virtual const QVector &DebugMessages() override { return m_Ctx.DebugMessages(); } - virtual int UnreadMessageCount() override { return m_Ctx.UnreadMessageCount(); } - virtual void MarkMessagesRead() override { return m_Ctx.MarkMessagesRead(); } - virtual D3D11Pipe::State &CurD3D11PipelineState() override - { - return m_Ctx.CurD3D11PipelineState(); - } - virtual D3D12Pipe::State &CurD3D12PipelineState() override - { - return m_Ctx.CurD3D12PipelineState(); - } - virtual GLPipe::State &CurGLPipelineState() override { return m_Ctx.CurGLPipelineState(); } - virtual VKPipe::State &CurVulkanPipelineState() override - { - return m_Ctx.CurVulkanPipelineState(); - } - virtual CommonPipelineState &CurPipelineState() override { return m_Ctx.CurPipelineState(); } - virtual PersistantConfig &Config() override { return m_Ctx.Config(); } - // - /////////////////////////////////////////////////////////////////////// - // functions that invoke onto the UI thread - /////////////////////////////////////////////////////////////////////// - // - template - void InvokeVoidFunction(F ptr, paramTypes... params) - { - if(!GUIInvoke::onUIThread()) - { - GUIInvoke::blockcall([this, ptr, params...]() { (m_Ctx.*ptr)(params...); }); - - return; - } - - (m_Ctx.*ptr)(params...); - } - - template - R InvokeRetFunction(F ptr, paramTypes... params) - { - if(!GUIInvoke::onUIThread()) - { - R ret; - GUIInvoke::blockcall([this, &ret, ptr, params...]() { ret = (m_Ctx.*ptr)(params...); }); - - return ret; - } - - return (m_Ctx.*ptr)(params...); - } - - virtual void LoadLogfile(const QString &logFile, const QString &origFilename, bool temporary, - bool local) override - { - InvokeVoidFunction(&ICaptureContext::LoadLogfile, logFile, origFilename, temporary, local); - } - virtual void CloseLogfile() override { InvokeVoidFunction(&ICaptureContext::CloseLogfile); } - virtual void SetEventID(const QVector &exclude, uint32_t selectedEventID, - uint32_t eventID, bool force = false) override - { - InvokeVoidFunction(&ICaptureContext::SetEventID, exclude, selectedEventID, eventID, force); - } - virtual void RefreshStatus() override { InvokeVoidFunction(&ICaptureContext::RefreshStatus); } - virtual void AddLogViewer(ILogViewer *viewer) override - { - InvokeVoidFunction(&ICaptureContext::AddLogViewer, viewer); - } - virtual void RemoveLogViewer(ILogViewer *viewer) override - { - InvokeVoidFunction(&ICaptureContext::RemoveLogViewer, viewer); - } - virtual void AddMessages(const rdctype::array &msgs) override - { - InvokeVoidFunction(&ICaptureContext::AddMessages, msgs); - } - virtual IMainWindow *GetMainWindow() override - { - return InvokeRetFunction(&ICaptureContext::GetMainWindow); - } - virtual IEventBrowser *GetEventBrowser() override - { - return InvokeRetFunction(&ICaptureContext::GetEventBrowser); - } - virtual IAPIInspector *GetAPIInspector() override - { - return InvokeRetFunction(&ICaptureContext::GetAPIInspector); - } - virtual ITextureViewer *GetTextureViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetTextureViewer); - } - virtual IBufferViewer *GetMeshPreview() override - { - return InvokeRetFunction(&ICaptureContext::GetMeshPreview); - } - virtual IPipelineStateViewer *GetPipelineViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetPipelineViewer); - } - virtual ICaptureDialog *GetCaptureDialog() override - { - return InvokeRetFunction(&ICaptureContext::GetCaptureDialog); - } - virtual IDebugMessageView *GetDebugMessageView() override - { - return InvokeRetFunction(&ICaptureContext::GetDebugMessageView); - } - virtual IStatisticsViewer *GetStatisticsViewer() override - { - return InvokeRetFunction(&ICaptureContext::GetStatisticsViewer); - } - virtual ITimelineBar *GetTimelineBar() override - { - return InvokeRetFunction(&ICaptureContext::GetTimelineBar); - } - virtual IPythonShell *GetPythonShell() override - { - return InvokeRetFunction(&ICaptureContext::GetPythonShell); - } - virtual bool HasEventBrowser() override - { - return InvokeRetFunction(&ICaptureContext::HasEventBrowser); - } - virtual bool HasAPIInspector() override - { - return InvokeRetFunction(&ICaptureContext::HasAPIInspector); - } - virtual bool HasTextureViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasTextureViewer); - } - virtual bool HasPipelineViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasPipelineViewer); - } - virtual bool HasMeshPreview() override - { - return InvokeRetFunction(&ICaptureContext::HasMeshPreview); - } - virtual bool HasCaptureDialog() override - { - return InvokeRetFunction(&ICaptureContext::HasCaptureDialog); - } - virtual bool HasDebugMessageView() override - { - return InvokeRetFunction(&ICaptureContext::HasDebugMessageView); - } - virtual bool HasStatisticsViewer() override - { - return InvokeRetFunction(&ICaptureContext::HasStatisticsViewer); - } - virtual bool HasTimelineBar() override - { - return InvokeRetFunction(&ICaptureContext::HasTimelineBar); - } - virtual bool HasPythonShell() override - { - return InvokeRetFunction(&ICaptureContext::HasPythonShell); - } - - virtual void ShowEventBrowser() override - { - InvokeVoidFunction(&ICaptureContext::ShowEventBrowser); - } - virtual void ShowAPIInspector() override - { - InvokeVoidFunction(&ICaptureContext::ShowAPIInspector); - } - virtual void ShowTextureViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowTextureViewer); - } - virtual void ShowMeshPreview() override { InvokeVoidFunction(&ICaptureContext::ShowMeshPreview); } - virtual void ShowPipelineViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowPipelineViewer); - } - virtual void ShowCaptureDialog() override - { - InvokeVoidFunction(&ICaptureContext::ShowCaptureDialog); - } - virtual void ShowDebugMessageView() override - { - InvokeVoidFunction(&ICaptureContext::ShowDebugMessageView); - } - virtual void ShowStatisticsViewer() override - { - InvokeVoidFunction(&ICaptureContext::ShowStatisticsViewer); - } - virtual void ShowTimelineBar() override { InvokeVoidFunction(&ICaptureContext::ShowTimelineBar); } - virtual void ShowPythonShell() override { InvokeVoidFunction(&ICaptureContext::ShowPythonShell); } - virtual IShaderViewer *EditShader(bool customShader, const QString &entryPoint, - const QStringMap &files, IShaderViewer::SaveCallback saveCallback, - IShaderViewer::CloseCallback closeCallback) override - { - return InvokeRetFunction(&ICaptureContext::EditShader, customShader, - entryPoint, files, saveCallback, closeCallback); - } - - virtual IShaderViewer *DebugShader(const ShaderBindpointMapping *bind, - const ShaderReflection *shader, ShaderStage stage, - ShaderDebugTrace *trace, const QString &debugContext) override - { - return InvokeRetFunction(&ICaptureContext::DebugShader, bind, shader, stage, - trace, debugContext); - } - - virtual IShaderViewer *ViewShader(const ShaderBindpointMapping *bind, - const ShaderReflection *shader, ShaderStage stage) override - { - return InvokeRetFunction(&ICaptureContext::ViewShader, bind, shader, stage); - } - - virtual IBufferViewer *ViewBuffer(uint64_t byteOffset, uint64_t byteSize, ResourceId id, - const QString &format = QString()) override - { - return InvokeRetFunction(&ICaptureContext::ViewBuffer, byteOffset, byteSize, - id, format); - } - - virtual IBufferViewer *ViewTextureAsBuffer(uint32_t arrayIdx, uint32_t mip, ResourceId id, - const QString &format = QString()) override - { - return InvokeRetFunction(&ICaptureContext::ViewTextureAsBuffer, arrayIdx, mip, - id, format); - } - - virtual IConstantBufferPreviewer *ViewConstantBuffer(ShaderStage stage, uint32_t slot, - uint32_t idx) override - { - return InvokeRetFunction(&ICaptureContext::ViewConstantBuffer, - stage, slot, idx); - } - - virtual IPixelHistoryView *ViewPixelHistory(ResourceId texID, int x, int y, - const TextureDisplay &display) override - { - return InvokeRetFunction(&ICaptureContext::ViewPixelHistory, texID, x, y, - display); - } - - virtual QWidget *CreateBuiltinWindow(const QString &objectName) override - { - return InvokeRetFunction(&ICaptureContext::CreateBuiltinWindow, objectName); - } - - virtual void BuiltinWindowClosed(QWidget *window) override - { - InvokeVoidFunction(&ICaptureContext::BuiltinWindowClosed, window); - } - - virtual void RaiseDockWindow(QWidget *dockWindow) override - { - InvokeVoidFunction(&ICaptureContext::RaiseDockWindow, dockWindow); - } - - virtual void AddDockWindow(QWidget *newWindow, DockReference ref, QWidget *refWindow, - float percentage = 0.5f) override - { - InvokeVoidFunction(&ICaptureContext::AddDockWindow, newWindow, ref, refWindow, percentage); - } -}; - -PythonShell::PythonShell(ICaptureContext &ctx, QWidget *parent) - : QFrame(parent), ui(new Ui::PythonShell), m_Ctx(ctx) -{ - ui->setupUi(this); - - m_ThreadCtx = new CaptureContextInvoker(m_Ctx); - - QObject::connect(ui->lineInput, &RDLineEdit::keyPress, this, &PythonShell::interactive_keypress); - - ui->lineInput->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - ui->interactiveOutput->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - ui->scriptOutput->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - - scriptEditor = new ScintillaEdit(this); - - scriptEditor->styleSetFont( - STYLE_DEFAULT, QFontDatabase::systemFont(QFontDatabase::FixedFont).family().toUtf8().data()); - - scriptEditor->setMarginLeft(4); - scriptEditor->setMarginWidthN(0, 32); - scriptEditor->setMarginWidthN(1, 0); - scriptEditor->setMarginWidthN(2, 16); - scriptEditor->setObjectName(lit("scriptEditor")); - - scriptEditor->markerSetBack(CURRENT_MARKER, SCINTILLA_COLOUR(240, 128, 128)); - scriptEditor->markerSetBack(CURRENT_MARKER + 1, SCINTILLA_COLOUR(240, 128, 128)); - scriptEditor->markerDefine(CURRENT_MARKER, SC_MARK_SHORTARROW); - scriptEditor->markerDefine(CURRENT_MARKER + 1, SC_MARK_BACKGROUND); - - ConfigureSyntax(scriptEditor, SCLEX_PYTHON); - - scriptEditor->setTabWidth(4); - - scriptEditor->setScrollWidth(1); - scriptEditor->setScrollWidthTracking(true); - - scriptEditor->colourise(0, -1); - - QObject::connect(scriptEditor, &ScintillaEdit::modified, [this](int type, int, int, int, - const QByteArray &, int, int, int) { - if(type & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT | SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) - { - scriptEditor->markerDeleteAll(CURRENT_MARKER); - scriptEditor->markerDeleteAll(CURRENT_MARKER + 1); - } - }); - - ui->scriptSplitter->insertWidget(0, scriptEditor); - int w = ui->scriptSplitter->rect().width(); - ui->scriptSplitter->setSizes({w * 2 / 3, w / 3}); - - ui->tabWidget->setCurrentIndex(0); - - interactiveContext = NULL; - - enableButtons(true); - - // reset output to default - on_clear_clicked(); - on_newScript_clicked(); -} - -PythonShell::~PythonShell() -{ - m_Ctx.BuiltinWindowClosed(this); - - interactiveContext->Finish(); - - delete m_ThreadCtx; - - delete ui; -} - -void PythonShell::on_execute_clicked() -{ - QString command = ui->lineInput->text(); - - appendText(ui->interactiveOutput, command + lit("\n")); - - if(command.trimmed().length() > 0) - interactiveContext->executeString(command, true); - - history.push_front(command); - historyidx = -1; - - ui->lineInput->clear(); - - appendText(ui->interactiveOutput, lit(">> ")); -} - -void PythonShell::on_clear_clicked() -{ - QString minidocHeader = scriptHeader(); - - minidocHeader += lit("\n\n>> "); - - ui->interactiveOutput->setText(minidocHeader); - - if(interactiveContext) - interactiveContext->Finish(); - - interactiveContext = newContext(); -} - -void PythonShell::on_newScript_clicked() -{ - QString minidocHeader = scriptHeader(); - - minidocHeader.replace(QLatin1Char('\n'), lit("\n# ")); - - minidocHeader = QFormatStr("# %1\n\n").arg(minidocHeader); - - scriptEditor->setText(minidocHeader.toUtf8().data()); - - scriptEditor->emptyUndoBuffer(); -} - -void PythonShell::on_openScript_clicked() -{ - QString filename = RDDialog::getOpenFileName(this, tr("Open Python Script"), QString(), - tr("Python scripts (*.py)")); - - if(!filename.isEmpty()) - { - QFile f(filename); - if(f.open(QIODevice::ReadOnly | QIODevice::Text)) - { - scriptEditor->setText(f.readAll().data()); - } - else - { - RDDialog::critical(this, tr("Error loading script"), - tr("Couldn't open path %1.").arg(filename)); - } - } -} - -void PythonShell::on_saveScript_clicked() -{ - QString filename = RDDialog::getSaveFileName(this, tr("Save Python Script"), QString(), - tr("Python scripts (*.py)")); - - if(!filename.isEmpty()) - { - QDir dirinfo = QFileInfo(filename).dir(); - if(dirinfo.exists()) - { - QFile f(filename); - if(f.open(QIODevice::WriteOnly | QIODevice::Truncate)) - { - f.write(scriptEditor->getText(scriptEditor->textLength() + 1)); - } - else - { - RDDialog::critical( - this, tr("Error saving script"), - tr("Couldn't open path %1 for write.\n%2").arg(filename).arg(f.errorString())); - } - } - else - { - RDDialog::critical(this, tr("Invalid directory"), - tr("Cannot find target directory to save to")); - } - } -} - -void PythonShell::on_runScript_clicked() -{ - PythonContext *context = newContext(); - - ui->scriptOutput->clear(); - - QString script = QString::fromUtf8(scriptEditor->getText(scriptEditor->textLength() + 1)); - - enableButtons(false); - - LambdaThread *thread = new LambdaThread([this, script, context]() { - - scriptContext = context; - context->executeString(lit("script.py"), script); - scriptContext = NULL; - - GUIInvoke::call([this, context]() { - context->Finish(); - enableButtons(true); - }); - }); - - thread->selfDelete(true); - thread->start(); -} - -void PythonShell::on_abortRun_clicked() -{ - if(scriptContext) - scriptContext->abort(); -} - -void PythonShell::traceLine(const QString &file, int line) -{ - if(QObject::sender() == (QObject *)interactiveContext) - return; - - scriptEditor->markerDeleteAll(CURRENT_MARKER); - scriptEditor->markerDeleteAll(CURRENT_MARKER + 1); - - scriptEditor->markerAdd(line > 0 ? line - 1 : 0, CURRENT_MARKER); - scriptEditor->markerAdd(line > 0 ? line - 1 : 0, CURRENT_MARKER + 1); -} - -void PythonShell::exception(const QString &type, const QString &value, int finalLine, - QList frames) -{ - QTextEdit *out = ui->scriptOutput; - if(QObject::sender() == (QObject *)interactiveContext) - out = ui->interactiveOutput; - - QString exString; - - if(finalLine >= 0) - traceLine(QString(), finalLine); - - if(!out->toPlainText().endsWith(QLatin1Char('\n'))) - exString = lit("\n"); - if(!frames.isEmpty()) - { - exString += tr("Traceback (most recent call last):\n"); - for(const QString &f : frames) - exString += QFormatStr(" %1\n").arg(f); - } - exString += QFormatStr("%1: %2\n").arg(type).arg(value); - - appendText(out, exString); -} - -void PythonShell::textOutput(bool isStdError, const QString &output) -{ - QTextEdit *out = ui->scriptOutput; - if(QObject::sender() == (QObject *)interactiveContext) - out = ui->interactiveOutput; - - appendText(out, output); -} - -void PythonShell::interactive_keypress(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) - on_execute_clicked(); - - bool moved = false; - - if(event->key() == Qt::Key_Down && historyidx > -1) - { - historyidx--; - - moved = true; - } - - QString workingtext; - - if(event->key() == Qt::Key_Up && historyidx + 1 < history.count()) - { - if(historyidx == -1) - workingtext = ui->lineInput->text(); - - historyidx++; - - moved = true; - } - - if(moved) - { - if(historyidx == -1) - ui->lineInput->setText(workingtext); - else - ui->lineInput->setText(history[historyidx]); - - ui->lineInput->deselect(); - } -} - -QString PythonShell::scriptHeader() -{ - return tr(R"(RenderDoc Python console, powered by python %1. -The 'pyrenderdoc' object is the current CaptureContext instance. -The 'renderdoc' and 'qrenderdoc' modules are available. -Documentation is available: https://renderdoc.org/docs/python_api/index.html)") - .arg(interactiveContext->versionString()); -} - -void PythonShell::appendText(QTextEdit *output, const QString &text) -{ - output->moveCursor(QTextCursor::End); - output->insertPlainText(text); - - // scroll to the bottom - QScrollBar *vscroll = output->verticalScrollBar(); - vscroll->setValue(vscroll->maximum()); -} - -void PythonShell::enableButtons(bool enable) -{ - ui->newScript->setEnabled(enable); - ui->openScript->setEnabled(enable); - ui->saveScript->setEnabled(enable); - ui->runScript->setEnabled(enable); - ui->abortRun->setEnabled(!enable); -} - -PythonContext *PythonShell::newContext() -{ - PythonContext *ret = new PythonContext(); - - QObject::connect(ret, &PythonContext::traceLine, this, &PythonShell::traceLine); - QObject::connect(ret, &PythonContext::exception, this, &PythonShell::exception); - QObject::connect(ret, &PythonContext::textOutput, this, &PythonShell::textOutput); - - ret->setGlobal("pyrenderdoc", (ICaptureContext *)m_ThreadCtx); - - return ret; -} diff --git a/qrenderdoc/Windows/PythonShell.h b/qrenderdoc/Windows/PythonShell.h deleted file mode 100644 index 48810c74c..000000000 --- a/qrenderdoc/Windows/PythonShell.h +++ /dev/null @@ -1,87 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -class PythonContext; -class ScintillaEdit; -class QTextEdit; - -namespace Ui -{ -class PythonShell; -} - -struct CaptureContextInvoker; - -class PythonShell : public QFrame, public IPythonShell -{ - Q_OBJECT - -public: - explicit PythonShell(ICaptureContext &ctx, QWidget *parent = 0); - - ~PythonShell(); - - // IPythonShell - QWidget *Widget() override { return this; } -private slots: - // automatic slots - void on_execute_clicked(); - void on_clear_clicked(); - void on_newScript_clicked(); - void on_openScript_clicked(); - void on_saveScript_clicked(); - void on_runScript_clicked(); - void on_abortRun_clicked(); - - // manual slots - void interactive_keypress(QKeyEvent *e); - void traceLine(const QString &file, int line); - void exception(const QString &type, const QString &value, int finalLine, QList frames); - void textOutput(bool isStdError, const QString &output); - -private: - Ui::PythonShell *ui; - ICaptureContext &m_Ctx; - CaptureContextInvoker *m_ThreadCtx = NULL; - - ScintillaEdit *scriptEditor; - - static const int CURRENT_MARKER = 0; - - PythonContext *interactiveContext, *scriptContext; - - QList history; - int historyidx = -1; - - PythonContext *newContext(); - - QString scriptHeader(); - void appendText(QTextEdit *output, const QString &text); - void enableButtons(bool enable); -}; diff --git a/qrenderdoc/Windows/PythonShell.ui b/qrenderdoc/Windows/PythonShell.ui deleted file mode 100644 index d201e42bd..000000000 --- a/qrenderdoc/Windows/PythonShell.ui +++ /dev/null @@ -1,315 +0,0 @@ - - - PythonShell - - - - 0 - 0 - 544 - 346 - - - - Interactive Python Shell - - - - 0 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 1 - - - - Interactive Shell - - - - 4 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - - - 6 - - - - - - - - Execute - - - - - - - Clear - - - - - - - - - - Run Scripts - - - - 4 - - - 2 - - - 2 - - - 2 - - - 2 - - - - - - 0 - 0 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Create a new blank script - - - New - - - - :/page_white_edit.png:/page_white_edit.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Open an existing python script - - - Open - - - - :/folder_page_white.png:/folder_page_white.png - - - QToolButton::InstantPopup - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Save the current script to disk - - - Save As - - - - :/save.png:/save.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Vertical - - - - - - - Begin running the script in python - - - Run - - - - :/arrow_right.png:/arrow_right.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Stop execution of the current script - - - Abort - - - - :/del.png:/del.png - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Qt::Horizontal - - - false - - - - Qt::ScrollBarAlwaysOn - - - true - - - - - - - - - - - - - RDLineEdit - QLineEdit -
Widgets/Extended/RDLineEdit.h
-
- - RDTextEdit - QTextEdit -
Widgets/Extended/RDTextEdit.h
-
-
- - - - -
diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp deleted file mode 100644 index d8c5e0132..000000000 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ /dev/null @@ -1,2448 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "ShaderViewer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "3rdparty/scintilla/include/SciLexer.h" -#include "3rdparty/scintilla/include/qt/ScintillaEdit.h" -#include "3rdparty/toolwindowmanager/ToolWindowManager.h" -#include "3rdparty/toolwindowmanager/ToolWindowManagerArea.h" -#include "Code/ScintillaSyntax.h" -#include "Widgets/FindReplace.h" -#include "ui_ShaderViewer.h" - -namespace -{ -struct VariableTag -{ - VariableTag() {} - VariableTag(VariableCategory c, int i, int a = 0) : cat(c), idx(i), arrayIdx(a) {} - VariableCategory cat = VariableCategory::Unknown; - int idx = 0; - int arrayIdx = 0; - - bool operator==(const VariableTag &o) - { - return cat == o.cat && idx == o.idx && arrayIdx == o.arrayIdx; - } -}; -}; - -Q_DECLARE_METATYPE(VariableTag); - -ShaderViewer::ShaderViewer(ICaptureContext &ctx, QWidget *parent) - : QFrame(parent), ui(new Ui::ShaderViewer), m_Ctx(ctx) -{ - ui->setupUi(this); - - ui->constants->setFont(Formatter::PreferredFont()); - ui->variables->setFont(Formatter::PreferredFont()); - ui->watch->setFont(Formatter::PreferredFont()); - ui->inputSig->setFont(Formatter::PreferredFont()); - ui->outputSig->setFont(Formatter::PreferredFont()); - - // we create this up front so its state stays persistent as much as possible. - m_FindReplace = new FindReplace(this); - - m_FindResults = MakeEditor(lit("findresults"), QString(), SCLEX_NULL); - m_FindResults->setReadOnly(true); - m_FindResults->setWindowTitle(lit("Find Results")); - - // remove margins - m_FindResults->setMarginWidthN(0, 0); - m_FindResults->setMarginWidthN(1, 0); - m_FindResults->setMarginWidthN(2, 0); - - QObject::connect(m_FindReplace, &FindReplace::performFind, this, &ShaderViewer::performFind); - QObject::connect(m_FindReplace, &FindReplace::performFindAll, this, &ShaderViewer::performFindAll); - QObject::connect(m_FindReplace, &FindReplace::performReplace, this, &ShaderViewer::performReplace); - QObject::connect(m_FindReplace, &FindReplace::performReplaceAll, this, - &ShaderViewer::performReplaceAll); - - ui->docking->addToolWindow(m_FindReplace, ToolWindowManager::NoArea); - ui->docking->setToolWindowProperties(m_FindReplace, ToolWindowManager::HideOnClose); - - ui->docking->addToolWindow(m_FindResults, ToolWindowManager::NoArea); - ui->docking->setToolWindowProperties(m_FindResults, ToolWindowManager::HideOnClose); - - { - m_DisassemblyView = - MakeEditor(lit("scintillaDisassem"), QString(), - m_Ctx.APIProps().pipelineType == GraphicsAPI::Vulkan ? SCLEX_GLSL : SCLEX_HLSL); - m_DisassemblyView->setReadOnly(true); - - QObject::connect(m_DisassemblyView, &ScintillaEdit::keyPressed, this, - &ShaderViewer::readonly_keyPressed); - - // C# LightCoral - m_DisassemblyView->markerSetBack(CURRENT_MARKER, SCINTILLA_COLOUR(240, 128, 128)); - m_DisassemblyView->markerSetBack(CURRENT_MARKER + 1, SCINTILLA_COLOUR(240, 128, 128)); - m_DisassemblyView->markerDefine(CURRENT_MARKER, SC_MARK_SHORTARROW); - m_DisassemblyView->markerDefine(CURRENT_MARKER + 1, SC_MARK_BACKGROUND); - - // C# LightSlateGray - m_DisassemblyView->markerSetBack(FINISHED_MARKER, SCINTILLA_COLOUR(119, 136, 153)); - m_DisassemblyView->markerSetBack(FINISHED_MARKER + 1, SCINTILLA_COLOUR(119, 136, 153)); - m_DisassemblyView->markerDefine(FINISHED_MARKER, SC_MARK_ROUNDRECT); - m_DisassemblyView->markerDefine(FINISHED_MARKER + 1, SC_MARK_BACKGROUND); - - // C# Red - m_DisassemblyView->markerSetBack(BREAKPOINT_MARKER, SCINTILLA_COLOUR(255, 0, 0)); - m_DisassemblyView->markerSetBack(BREAKPOINT_MARKER + 1, SCINTILLA_COLOUR(255, 0, 0)); - m_DisassemblyView->markerDefine(BREAKPOINT_MARKER, SC_MARK_CIRCLE); - m_DisassemblyView->markerDefine(BREAKPOINT_MARKER + 1, SC_MARK_BACKGROUND); - - m_Scintillas.push_back(m_DisassemblyView); - - m_DisassemblyFrame = new QWidget(this); - m_DisassemblyFrame->setWindowTitle(tr("Disassembly")); - - m_DisassemblyToolbar = new QFrame(this); - m_DisassemblyToolbar->setFrameShape(QFrame::Panel); - m_DisassemblyToolbar->setFrameShadow(QFrame::Raised); - - QHBoxLayout *toolbarlayout = new QHBoxLayout(m_DisassemblyToolbar); - toolbarlayout->setSpacing(2); - toolbarlayout->setContentsMargins(3, 3, 3, 3); - - m_DisassemblyType = new QComboBox(m_DisassemblyToolbar); - m_DisassemblyType->setMaxVisibleItems(12); - m_DisassemblyType->setSizeAdjustPolicy(QComboBox::AdjustToContents); - - toolbarlayout->addWidget(new QLabel(tr("Disassembly type:"), m_DisassemblyToolbar)); - toolbarlayout->addWidget(m_DisassemblyType); - toolbarlayout->addItem(new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); - - QVBoxLayout *framelayout = new QVBoxLayout(m_DisassemblyFrame); - framelayout->setSpacing(0); - framelayout->setMargin(0); - framelayout->addWidget(m_DisassemblyToolbar); - framelayout->addWidget(m_DisassemblyView); - - ui->docking->addToolWindow(m_DisassemblyFrame, ToolWindowManager::EmptySpace); - ui->docking->setToolWindowProperties(m_DisassemblyFrame, - ToolWindowManager::HideCloseButton | - ToolWindowManager::DisallowFloatWindow | - ToolWindowManager::AlwaysDisplayFullTabs); - } - - ui->docking->setAllowFloatingWindow(false); - - { - QMenu *snippetsMenu = new QMenu(this); - - QAction *dim = new QAction(tr("Texture Dimensions Global"), this); - QAction *mip = new QAction(tr("Selected Mip Global"), this); - QAction *slice = new QAction(tr("Seleted Array Slice / Cubemap Face Global"), this); - QAction *sample = new QAction(tr("Selected Sample Global"), this); - QAction *type = new QAction(tr("Texture Type Global"), this); - QAction *samplers = new QAction(tr("Point && Linear Samplers"), this); - QAction *resources = new QAction(tr("Texture Resources"), this); - - snippetsMenu->addAction(dim); - snippetsMenu->addAction(mip); - snippetsMenu->addAction(slice); - snippetsMenu->addAction(sample); - snippetsMenu->addAction(type); - snippetsMenu->addSeparator(); - snippetsMenu->addAction(samplers); - snippetsMenu->addAction(resources); - - QObject::connect(dim, &QAction::triggered, this, &ShaderViewer::snippet_textureDimensions); - QObject::connect(mip, &QAction::triggered, this, &ShaderViewer::snippet_selectedMip); - QObject::connect(slice, &QAction::triggered, this, &ShaderViewer::snippet_selectedSlice); - QObject::connect(sample, &QAction::triggered, this, &ShaderViewer::snippet_selectedSample); - QObject::connect(type, &QAction::triggered, this, &ShaderViewer::snippet_selectedType); - QObject::connect(samplers, &QAction::triggered, this, &ShaderViewer::snippet_samplers); - QObject::connect(resources, &QAction::triggered, this, &ShaderViewer::snippet_resources); - - ui->snippets->setMenu(snippetsMenu); - } - - QVBoxLayout *layout = new QVBoxLayout(this); - layout->setSpacing(0); - layout->setMargin(0); - layout->addWidget(ui->toolbar); - layout->addWidget(ui->docking); - - m_Ctx.AddLogViewer(this); -} - -void ShaderViewer::editShader(bool customShader, const QString &entryPoint, const QStringMap &files) -{ - m_Scintillas.removeOne(m_DisassemblyView); - ui->docking->removeToolWindow(m_DisassemblyFrame); - - // hide watch, constants, variables - ui->watch->hide(); - ui->variables->hide(); - ui->constants->hide(); - - ui->snippets->setVisible(customShader); - - // hide debugging toolbar buttons - ui->stepBack->hide(); - ui->stepNext->hide(); - ui->runToCursor->hide(); - ui->runToSample->hide(); - ui->runToNaNOrInf->hide(); - ui->regFormatSep->hide(); - ui->intView->hide(); - ui->floatView->hide(); - - // hide signatures - ui->inputSig->hide(); - ui->outputSig->hide(); - - QString title; - - QWidget *sel = NULL; - for(const QString &f : files.keys()) - { - QString name = QFileInfo(f).fileName(); - QString text = files[f]; - - ScintillaEdit *scintilla = AddFileScintilla(name, text); - - scintilla->setReadOnly(false); - QObject::connect(scintilla, &ScintillaEdit::keyPressed, this, &ShaderViewer::editable_keyPressed); - - QObject::connect(scintilla, &ScintillaEdit::modified, [this](int type, int, int, int, - const QByteArray &, int, int, int) { - if(type & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT | SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) - m_FindState = FindState(); - }); - - m_Ctx.GetMainWindow()->RegisterShortcut(QKeySequence(QKeySequence::Save).toString(), this, - [this]() { on_save_clicked(); }); - - QWidget *w = (QWidget *)scintilla; - w->setProperty("filename", f); - - if(text.contains(entryPoint)) - sel = scintilla; - - if(sel == scintilla || title.isEmpty()) - title = tr("%1 - Edit (%2)").arg(entryPoint).arg(name); - } - - if(sel != NULL) - ToolWindowManager::raiseToolWindow(sel); - - setWindowTitle(title); - - if(files.count() > 2) - addFileList(); - - m_Errors = MakeEditor(lit("errors"), QString(), SCLEX_NULL); - m_Errors->setReadOnly(true); - m_Errors->setWindowTitle(lit("Errors")); - - // remove margins - m_Errors->setMarginWidthN(0, 0); - m_Errors->setMarginWidthN(1, 0); - m_Errors->setMarginWidthN(2, 0); - - QObject::connect(m_Errors, &ScintillaEdit::keyPressed, this, &ShaderViewer::readonly_keyPressed); - - ui->docking->addToolWindow( - m_Errors, ToolWindowManager::AreaReference(ToolWindowManager::BottomOf, - ui->docking->areaOf(m_Scintillas.front()), 0.2f)); - ui->docking->setToolWindowProperties( - m_Errors, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); -} - -void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, - ShaderStage stage, ShaderDebugTrace *trace, - const QString &debugContext) -{ - m_Mapping = bind; - m_ShaderDetails = shader; - m_Trace = trace; - m_Stage = stage; - - // no replacing allowed, stay in find mode - m_FindReplace->allowUserModeChange(false); - - if(!shader || !bind) - m_Trace = NULL; - - if(trace) - setWindowTitle(QFormatStr("Debugging %1 - %2") - .arg(m_Ctx.CurPipelineState().GetShaderName(stage)) - .arg(debugContext)); - else - setWindowTitle(m_Ctx.CurPipelineState().GetShaderName(stage)); - - if(shader) - { - m_Ctx.Replay().AsyncInvoke([this](IReplayController *r) { - rdctype::array targets = r->GetDisassemblyTargets(); - - rdctype::str disasm = r->DisassembleShader(m_ShaderDetails, ""); - - GUIInvoke::call([this, targets, disasm]() { - QStringList targetNames; - for(const rdctype::str &t : targets) - targetNames << ToQStr(t); - - m_DisassemblyType->addItems(targetNames); - m_DisassemblyType->setCurrentIndex(0); - QObject::connect(m_DisassemblyType, OverloadedSlot::of(&QComboBox::currentIndexChanged), - this, &ShaderViewer::disassemble_typeChanged); - - // read-only applies to us too! - m_DisassemblyView->setReadOnly(false); - m_DisassemblyView->setText(disasm.c_str()); - m_DisassemblyView->setReadOnly(true); - - updateDebugging(); - }); - }); - } - - // we always want to highlight words/registers - QObject::connect(m_DisassemblyView, &ScintillaEdit::buttonReleased, this, - &ShaderViewer::disassembly_buttonReleased); - - // suppress the built-in context menu and hook up our own - if(trace) - { - m_DisassemblyView->usePopUp(SC_POPUP_NEVER); - - m_DisassemblyFrame->layout()->removeWidget(m_DisassemblyToolbar); - - m_DisassemblyView->setContextMenuPolicy(Qt::CustomContextMenu); - QObject::connect(m_DisassemblyView, &ScintillaEdit::customContextMenuRequested, this, - &ShaderViewer::disassembly_contextMenu); - - m_DisassemblyView->setMouseDwellTime(500); - - QObject::connect(m_DisassemblyView, &ScintillaEdit::dwellStart, this, - &ShaderViewer::disasm_tooltipShow); - QObject::connect(m_DisassemblyView, &ScintillaEdit::dwellEnd, this, - &ShaderViewer::disasm_tooltipHide); - } - - if(shader && shader->DebugInfo.files.count > 0) - { - if(trace) - setWindowTitle(QFormatStr("Debug %1() - %2").arg(ToQStr(shader->EntryPoint)).arg(debugContext)); - else - setWindowTitle(ToQStr(shader->EntryPoint)); - - int fileIdx = 0; - - QWidget *sel = NULL; - for(auto &f : shader->DebugInfo.files) - { - QString name = QFileInfo(ToQStr(f.first)).fileName(); - QString text = ToQStr(f.second); - - ScintillaEdit *scintilla = AddFileScintilla(name, text); - - if(sel == NULL) - sel = scintilla; - - fileIdx++; - } - - if(trace || sel == NULL) - sel = m_DisassemblyView; - - if(shader->DebugInfo.files.count > 2) - addFileList(); - - ToolWindowManager::raiseToolWindow(sel); - } - - ui->snippets->hide(); - - if(trace) - { - // hide signatures - ui->inputSig->hide(); - ui->outputSig->hide(); - - ui->variables->setColumns({tr("Name"), tr("Type"), tr("Value")}); - ui->variables->header()->setSectionResizeMode(0, QHeaderView::Stretch); - ui->variables->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - ui->variables->header()->setSectionResizeMode(2, QHeaderView::Stretch); - - ui->constants->setColumns({tr("Name"), tr("Type"), tr("Value")}); - ui->constants->header()->setSectionResizeMode(0, QHeaderView::Stretch); - ui->constants->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents); - ui->constants->header()->setSectionResizeMode(2, QHeaderView::Stretch); - - ui->watch->setWindowTitle(tr("Watch")); - ui->docking->addToolWindow( - ui->watch, ToolWindowManager::AreaReference(ToolWindowManager::BottomOf, - ui->docking->areaOf(m_DisassemblyFrame), 0.25f)); - ui->docking->setToolWindowProperties( - ui->watch, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); - - ui->variables->setWindowTitle(tr("Variables")); - ui->docking->addToolWindow( - ui->variables, - ToolWindowManager::AreaReference(ToolWindowManager::AddTo, ui->docking->areaOf(ui->watch))); - ui->docking->setToolWindowProperties( - ui->variables, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); - - ui->constants->setWindowTitle(tr("Constants && Resources")); - ui->docking->addToolWindow( - ui->constants, ToolWindowManager::AreaReference(ToolWindowManager::LeftOf, - ui->docking->areaOf(ui->variables), 0.5f)); - ui->docking->setToolWindowProperties( - ui->constants, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); - - m_DisassemblyView->setMarginWidthN(1, 20); - - // display current line in margin 2, distinct from breakpoint in margin 1 - sptr_t markMask = (1 << CURRENT_MARKER) | (1 << FINISHED_MARKER); - - m_DisassemblyView->setMarginMaskN(1, m_DisassemblyView->marginMaskN(1) & ~markMask); - m_DisassemblyView->setMarginMaskN(2, m_DisassemblyView->marginMaskN(2) | markMask); - - QObject::connect(ui->stepBack, &QToolButton::clicked, this, &ShaderViewer::stepBack); - QObject::connect(ui->stepNext, &QToolButton::clicked, this, &ShaderViewer::stepNext); - QObject::connect(ui->runBack, &QToolButton::clicked, this, &ShaderViewer::runBack); - QObject::connect(ui->run, &QToolButton::clicked, this, &ShaderViewer::run); - QObject::connect(ui->runToCursor, &QToolButton::clicked, this, &ShaderViewer::runToCursor); - QObject::connect(ui->runToSample, &QToolButton::clicked, this, &ShaderViewer::runToSample); - QObject::connect(ui->runToNaNOrInf, &QToolButton::clicked, this, &ShaderViewer::runToNanOrInf); - - QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10), m_DisassemblyView), - &QShortcut::activated, this, &ShaderViewer::stepNext); - QObject::connect(new QShortcut(QKeySequence(Qt::Key_F10 | Qt::ShiftModifier), m_DisassemblyView), - &QShortcut::activated, this, &ShaderViewer::stepBack); - QObject::connect( - new QShortcut(QKeySequence(Qt::Key_F10 | Qt::ControlModifier), m_DisassemblyView), - &QShortcut::activated, this, &ShaderViewer::runToCursor); - QObject::connect(new QShortcut(QKeySequence(Qt::Key_F5), m_DisassemblyView), - &QShortcut::activated, this, &ShaderViewer::run); - QObject::connect(new QShortcut(QKeySequence(Qt::Key_F5 | Qt::ShiftModifier), m_DisassemblyView), - &QShortcut::activated, this, &ShaderViewer::runBack); - QObject::connect(new QShortcut(QKeySequence(Qt::Key_F9), m_DisassemblyView), - &QShortcut::activated, [this]() { ToggleBreakpoint(); }); - - // event filter to pick up tooltip events - ui->constants->installEventFilter(this); - ui->variables->installEventFilter(this); - ui->watch->installEventFilter(this); - - SetCurrentStep(0); - - QObject::connect(ui->watch, &RDTableWidget::keyPress, this, &ShaderViewer::watch_keyPress); - - ui->watch->insertRow(0); - - for(int i = 0; i < ui->watch->columnCount(); i++) - { - QTableWidgetItem *item = new QTableWidgetItem(); - if(i > 0) - item->setFlags(item->flags() & ~Qt::ItemIsEditable); - ui->watch->setItem(0, i, item); - } - - ui->watch->resizeRowsToContents(); - } - else - { - // hide watch, constants, variables - ui->watch->hide(); - ui->variables->hide(); - ui->constants->hide(); - - // hide debugging toolbar buttons - ui->stepBack->hide(); - ui->stepNext->hide(); - ui->runToCursor->hide(); - ui->runToSample->hide(); - ui->runToNaNOrInf->hide(); - ui->regFormatSep->hide(); - ui->intView->hide(); - ui->floatView->hide(); - - // show input and output signatures - ui->inputSig->setColumns( - {tr("Name"), tr("Index"), tr("Reg"), tr("Type"), tr("SysValue"), tr("Mask"), tr("Used")}); - for(int i = 0; i < ui->inputSig->header()->count(); i++) - ui->inputSig->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); - - ui->outputSig->setColumns( - {tr("Name"), tr("Index"), tr("Reg"), tr("Type"), tr("SysValue"), tr("Mask"), tr("Used")}); - for(int i = 0; i < ui->outputSig->header()->count(); i++) - ui->outputSig->header()->setSectionResizeMode(i, QHeaderView::ResizeToContents); - - if(shader) - { - for(const SigParameter &s : shader->InputSig) - { - QString name = s.varName.count == 0 - ? ToQStr(s.semanticName) - : QFormatStr("%1 (%2)").arg(ToQStr(s.varName)).arg(ToQStr(s.semanticName)); - if(s.semanticName.count == 0) - name = ToQStr(s.varName); - - QString semIdx = s.needSemanticIndex ? QString::number(s.semanticIndex) : QString(); - - QString regIdx = - s.systemValue == ShaderBuiltin::Undefined ? QString::number(s.regIndex) : lit("-"); - - ui->inputSig->addTopLevelItem(new RDTreeWidgetItem( - {name, semIdx, QString::number(s.regIndex), TypeString(s), ToQStr(s.systemValue), - GetComponentString(s.regChannelMask), GetComponentString(s.channelUsedMask)})); - } - - bool multipleStreams = false; - for(const SigParameter &s : shader->OutputSig) - { - if(s.stream > 0) - { - multipleStreams = true; - break; - } - } - - for(const SigParameter &s : shader->OutputSig) - { - QString name = s.varName.count == 0 - ? ToQStr(s.semanticName) - : QFormatStr("%1 (%2)").arg(ToQStr(s.varName)).arg(ToQStr(s.semanticName)); - if(s.semanticName.count == 0) - name = ToQStr(s.varName); - - if(multipleStreams) - name = QFormatStr("Stream %1 : %2").arg(s.stream).arg(name); - - QString semIdx = s.needSemanticIndex ? QString::number(s.semanticIndex) : QString(); - - QString regIdx = - s.systemValue == ShaderBuiltin::Undefined ? QString::number(s.regIndex) : lit("-"); - - ui->outputSig->addTopLevelItem(new RDTreeWidgetItem( - {name, semIdx, regIdx, TypeString(s), ToQStr(s.systemValue), - GetComponentString(s.regChannelMask), GetComponentString(s.channelUsedMask)})); - } - } - - ui->inputSig->setWindowTitle(tr("Input Signature")); - ui->docking->addToolWindow(ui->inputSig, ToolWindowManager::AreaReference( - ToolWindowManager::BottomOf, - ui->docking->areaOf(m_DisassemblyFrame), 0.2f)); - ui->docking->setToolWindowProperties( - ui->inputSig, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); - - ui->outputSig->setWindowTitle(tr("Output Signature")); - ui->docking->addToolWindow( - ui->outputSig, ToolWindowManager::AreaReference(ToolWindowManager::RightOf, - ui->docking->areaOf(ui->inputSig), 0.5f)); - ui->docking->setToolWindowProperties( - ui->outputSig, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); - } -} - -ShaderViewer::~ShaderViewer() -{ - // don't want to async invoke while using 'this', so save the trace separately - ShaderDebugTrace *trace = m_Trace; - - m_Ctx.Replay().AsyncInvoke([trace](IReplayController *r) { r->FreeTrace(trace); }); - - if(m_CloseCallback) - m_CloseCallback(&m_Ctx); - - m_Ctx.RemoveLogViewer(this); - delete ui; -} - -void ShaderViewer::OnLogfileLoaded() -{ -} - -void ShaderViewer::OnLogfileClosed() -{ - ToolWindowManager::closeToolWindow(this); -} - -void ShaderViewer::OnEventChanged(uint32_t eventID) -{ -} - -ScintillaEdit *ShaderViewer::AddFileScintilla(const QString &name, const QString &text) -{ - ScintillaEdit *scintilla = MakeEditor( - lit("scintilla") + name, text, IsD3D(m_Ctx.APIProps().localRenderer) ? SCLEX_HLSL : SCLEX_GLSL); - scintilla->setReadOnly(true); - scintilla->setWindowTitle(name); - ((QWidget *)scintilla)->setProperty("name", name); - - QObject::connect(scintilla, &ScintillaEdit::keyPressed, this, &ShaderViewer::readonly_keyPressed); - - ToolWindowManager::AreaReference ref(ToolWindowManager::EmptySpace); - - if(!m_Scintillas.empty()) - ref = ToolWindowManager::AreaReference(ToolWindowManager::AddTo, - ui->docking->areaOf(m_Scintillas[0])); - - ui->docking->addToolWindow(scintilla, ref); - ui->docking->setToolWindowProperties(scintilla, ToolWindowManager::HideCloseButton | - ToolWindowManager::DisallowFloatWindow | - ToolWindowManager::AlwaysDisplayFullTabs); - - m_Scintillas.push_back(scintilla); - - return scintilla; -} - -ScintillaEdit *ShaderViewer::MakeEditor(const QString &name, const QString &text, int lang) -{ - ScintillaEdit *ret = new ScintillaEdit(this); - - ret->setText(text.toUtf8().data()); - - sptr_t numlines = ret->lineCount(); - - int margin0width = 30; - if(numlines > 1000) - margin0width += 6; - if(numlines > 10000) - margin0width += 6; - - ret->setMarginLeft(4); - ret->setMarginWidthN(0, margin0width); - ret->setMarginWidthN(1, 0); - ret->setMarginWidthN(2, 16); - ret->setObjectName(name); - - ret->styleSetFont(STYLE_DEFAULT, - QFontDatabase::systemFont(QFontDatabase::FixedFont).family().toUtf8().data()); - - // C# DarkGreen - ret->indicSetFore(INDICATOR_REGHIGHLIGHT, SCINTILLA_COLOUR(0, 100, 0)); - ret->indicSetStyle(INDICATOR_REGHIGHLIGHT, INDIC_ROUNDBOX); - - // set up find result highlight style - ret->indicSetFore(INDICATOR_FINDRESULT, SCINTILLA_COLOUR(200, 200, 127)); - ret->indicSetStyle(INDICATOR_FINDRESULT, INDIC_FULLBOX); - ret->indicSetAlpha(INDICATOR_FINDRESULT, 50); - ret->indicSetOutlineAlpha(INDICATOR_FINDRESULT, 80); - - ConfigureSyntax(ret, lang); - - ret->setTabWidth(4); - - ret->setScrollWidth(1); - ret->setScrollWidthTracking(true); - - ret->colourise(0, -1); - - ret->emptyUndoBuffer(); - - return ret; -} - -void ShaderViewer::readonly_keyPressed(QKeyEvent *event) -{ - if(event->key() == Qt::Key_F && (event->modifiers() & Qt::ControlModifier)) - { - m_FindReplace->setReplaceMode(false); - on_findReplace_clicked(); - } - - if(event->key() == Qt::Key_F3) - { - find((event->modifiers() & Qt::ShiftModifier) == 0); - } -} - -void ShaderViewer::editable_keyPressed(QKeyEvent *event) -{ - if(event->key() == Qt::Key_H && (event->modifiers() & Qt::ControlModifier)) - { - m_FindReplace->setReplaceMode(true); - on_findReplace_clicked(); - } -} - -void ShaderViewer::disassembly_contextMenu(const QPoint &pos) -{ - int scintillaPos = m_DisassemblyView->positionFromPoint(pos.x(), pos.y()); - - QMenu contextMenu(this); - - QAction intDisplay(tr("Integer register display"), this); - QAction floatDisplay(tr("Float register display"), this); - - intDisplay.setCheckable(true); - floatDisplay.setCheckable(true); - - intDisplay.setChecked(ui->intView->isChecked()); - floatDisplay.setChecked(ui->floatView->isChecked()); - - QObject::connect(&intDisplay, &QAction::triggered, this, &ShaderViewer::on_intView_clicked); - QObject::connect(&floatDisplay, &QAction::triggered, this, &ShaderViewer::on_floatView_clicked); - - contextMenu.addAction(&intDisplay); - contextMenu.addAction(&floatDisplay); - contextMenu.addSeparator(); - - QAction addBreakpoint(tr("Toggle breakpoint here"), this); - QAction runCursor(tr("Run to Cursor"), this); - - QObject::connect(&addBreakpoint, &QAction::triggered, [this, scintillaPos] { - m_DisassemblyView->setSelection(scintillaPos, scintillaPos); - ToggleBreakpoint(); - }); - QObject::connect(&runCursor, &QAction::triggered, [this, scintillaPos] { - m_DisassemblyView->setSelection(scintillaPos, scintillaPos); - runToCursor(); - }); - - contextMenu.addAction(&addBreakpoint); - contextMenu.addAction(&runCursor); - contextMenu.addSeparator(); - - QAction copyText(tr("Copy"), this); - QAction selectAll(tr("Select All"), this); - - copyText.setEnabled(!m_DisassemblyView->selectionEmpty()); - - QObject::connect(©Text, &QAction::triggered, [this] { - m_DisassemblyView->copyRange(m_DisassemblyView->selectionStart(), - m_DisassemblyView->selectionEnd()); - }); - QObject::connect(&selectAll, &QAction::triggered, [this] { m_DisassemblyView->selectAll(); }); - - contextMenu.addAction(©Text); - contextMenu.addAction(&selectAll); - contextMenu.addSeparator(); - - RDDialog::show(&contextMenu, m_DisassemblyView->viewport()->mapToGlobal(pos)); -} - -void ShaderViewer::disassembly_buttonReleased(QMouseEvent *event) -{ - if(event->button() == Qt::LeftButton) - { - sptr_t scintillaPos = m_DisassemblyView->positionFromPoint(event->x(), event->y()); - - sptr_t start = m_DisassemblyView->wordStartPosition(scintillaPos, true); - sptr_t end = m_DisassemblyView->wordEndPosition(scintillaPos, true); - - QString text = QString::fromUtf8(m_DisassemblyView->textRange(start, end)); - - if(!text.isEmpty()) - { - VariableTag tag; - getRegisterFromWord(text, tag.cat, tag.idx, tag.arrayIdx); - - // for now since we don't have friendly naming, only highlight registers - if(tag.cat != VariableCategory::Unknown) - { - start = 0; - end = m_DisassemblyView->length(); - - for(int i = 0; i < ui->variables->topLevelItemCount(); i++) - { - RDTreeWidgetItem *item = ui->variables->topLevelItem(i); - if(item->tag().value() == tag) - item->setBackgroundColor(QColor::fromHslF( - 0.333f, 1.0f, qBound(0.25, palette().color(QPalette::Base).lightnessF(), 0.85))); - else - item->setBackground(QBrush()); - } - - for(int i = 0; i < ui->constants->topLevelItemCount(); i++) - { - RDTreeWidgetItem *item = ui->constants->topLevelItem(i); - if(item->tag().value() == tag) - item->setBackgroundColor(QColor::fromHslF( - 0.333f, 1.0f, qBound(0.25, palette().color(QPalette::Base).lightnessF(), 0.85))); - else - item->setBackground(QBrush()); - } - - m_DisassemblyView->setIndicatorCurrent(INDICATOR_REGHIGHLIGHT); - m_DisassemblyView->indicatorClearRange(start, end); - - sptr_t flags = SCFIND_MATCHCASE | SCFIND_WHOLEWORD; - - if(tag.cat != VariableCategory::Unknown) - { - flags |= SCFIND_REGEXP | SCFIND_POSIX; - text += lit("\\.[xyzwrgba]+"); - } - - QByteArray findUtf8 = text.toUtf8(); - - QPair result; - - do - { - result = m_DisassemblyView->findText(flags, findUtf8.data(), start, end); - - if(result.first >= 0) - m_DisassemblyView->indicatorFillRange(result.first, result.second - result.first); - - start = result.second; - - } while(result.first >= 0); - } - } - } -} - -void ShaderViewer::disassemble_typeChanged(int index) -{ - if(m_ShaderDetails == NULL) - return; - - QByteArray target = m_DisassemblyType->currentText().toUtf8(); - - m_Ctx.Replay().AsyncInvoke([this, target](IReplayController *r) { - rdctype::str disasm = r->DisassembleShader(m_ShaderDetails, target.data()); - - GUIInvoke::call([this, disasm]() { - m_DisassemblyView->setReadOnly(false); - m_DisassemblyView->setText(disasm.c_str()); - m_DisassemblyView->setReadOnly(true); - m_DisassemblyView->emptyUndoBuffer(); - }); - }); -} - -void ShaderViewer::watch_keyPress(QKeyEvent *event) -{ - if(event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace) - { - QList items = ui->watch->selectedItems(); - if(!items.isEmpty() && items.back()->row() < ui->watch->rowCount() - 1) - ui->watch->removeRow(items.back()->row()); - } -} - -void ShaderViewer::on_watch_itemChanged(QTableWidgetItem *item) -{ - // ignore changes to the type/value columns. Only look at name changes, which must be by the user - if(item->column() != 0) - return; - - static bool recurse = false; - - if(recurse) - return; - - recurse = true; - - // if the item is now empty, remove it - if(item->text().isEmpty()) - ui->watch->removeRow(item->row()); - - // ensure we have a trailing row for adding new watch items. - - if(ui->watch->rowCount() == 0 || ui->watch->item(ui->watch->rowCount() - 1, 0) == NULL || - !ui->watch->item(ui->watch->rowCount() - 1, 0)->text().isEmpty()) - { - // add a new row if needed - if(ui->watch->rowCount() == 0 || ui->watch->item(ui->watch->rowCount() - 1, 0) != NULL) - ui->watch->insertRow(ui->watch->rowCount()); - - for(int i = 0; i < ui->watch->columnCount(); i++) - { - QTableWidgetItem *newItem = new QTableWidgetItem(); - if(i > 0) - newItem->setFlags(newItem->flags() & ~Qt::ItemIsEditable); - ui->watch->setItem(ui->watch->rowCount() - 1, i, newItem); - } - } - - ui->watch->resizeRowsToContents(); - - recurse = false; - - updateDebugging(); -} - -bool ShaderViewer::stepBack() -{ - if(!m_Trace) - return false; - - if(CurrentStep() == 0) - return false; - - SetCurrentStep(CurrentStep() - 1); - - return true; -} - -bool ShaderViewer::stepNext() -{ - if(!m_Trace) - return false; - - if(CurrentStep() + 1 >= m_Trace->states.count) - return false; - - SetCurrentStep(CurrentStep() + 1); - - return true; -} - -void ShaderViewer::runToCursor() -{ - if(!m_Trace) - return; - - sptr_t i = m_DisassemblyView->lineFromPosition(m_DisassemblyView->currentPos()); - - for(; i < m_DisassemblyView->lineCount(); i++) - { - int line = instructionForLine(i); - if(line >= 0) - { - runTo(line, true); - break; - } - } -} - -int ShaderViewer::instructionForLine(sptr_t line) -{ - QString trimmed = QString::fromUtf8(m_DisassemblyView->getLine(line).trimmed()); - - int colon = trimmed.indexOf(QLatin1Char(':')); - - if(colon > 0) - { - trimmed.truncate(colon); - - bool ok = false; - int instruction = trimmed.toInt(&ok); - - if(ok && instruction >= 0) - return instruction; - } - - return -1; -} - -void ShaderViewer::runToSample() -{ - runTo(-1, true, ShaderEvents::SampleLoadGather); -} - -void ShaderViewer::runToNanOrInf() -{ - runTo(-1, true, ShaderEvents::GeneratedNanOrInf); -} - -void ShaderViewer::runBack() -{ - runTo(-1, false); -} - -void ShaderViewer::run() -{ - runTo(-1, true); -} - -void ShaderViewer::runTo(int runToInstruction, bool forward, ShaderEvents condition) -{ - if(!m_Trace) - return; - - int step = CurrentStep(); - - int inc = forward ? 1 : -1; - - bool firstStep = true; - - while(step < m_Trace->states.count) - { - if(runToInstruction >= 0 && m_Trace->states[step].nextInstruction == (uint32_t)runToInstruction) - break; - - if(!firstStep && (m_Trace->states[step + inc].flags & condition)) - break; - - if(!firstStep && m_Breakpoints.contains((int)m_Trace->states[step].nextInstruction)) - break; - - firstStep = false; - - if(step + inc < 0 || step + inc >= m_Trace->states.count) - break; - - step += inc; - } - - SetCurrentStep(step); -} - -QString ShaderViewer::stringRep(const ShaderVariable &var, bool useType) -{ - if(ui->intView->isChecked() || (useType && var.type == VarType::Int)) - return RowString(var, 0, VarType::Int); - - if(useType && var.type == VarType::UInt) - return RowString(var, 0, VarType::UInt); - - return RowString(var, 0, VarType::Float); -} - -RDTreeWidgetItem *ShaderViewer::makeResourceRegister(const BindpointMap &bind, uint32_t idx, - const BoundResource &bound, - const ShaderResource &res) -{ - QString name = QFormatStr(" (%1)").arg(ToQStr(res.name)); - - const TextureDescription *tex = m_Ctx.GetTexture(bound.Id); - const BufferDescription *buf = m_Ctx.GetBuffer(bound.Id); - - if(res.IsSampler) - return NULL; - - QChar regChar(QLatin1Char('u')); - - if(res.IsReadOnly) - regChar = QLatin1Char('t'); - - QString regname; - - if(m_Ctx.APIProps().pipelineType == GraphicsAPI::D3D12) - { - if(bind.arraySize == 1) - regname = QFormatStr("%1%2:%3").arg(regChar).arg(bind.bindset).arg(bind.bind); - else - regname = QFormatStr("%1%2:%3[%4]").arg(regChar).arg(bind.bindset).arg(bind.bind).arg(idx); - } - else - { - regname = QFormatStr("%1%2").arg(regChar).arg(bind.bind); - } - - if(tex) - { - QString type = QFormatStr("%1x%2x%3[%4] @ %5 - %6") - .arg(tex->width) - .arg(tex->height) - .arg(tex->depth > 1 ? tex->depth : tex->arraysize) - .arg(tex->mips) - .arg(ToQStr(tex->format.strname)) - .arg(ToQStr(tex->name)); - - return new RDTreeWidgetItem({regname + name, lit("Texture"), type}); - } - else if(buf) - { - QString type = QFormatStr("%1 - %2").arg(buf->length).arg(ToQStr(buf->name)); - - return new RDTreeWidgetItem({regname + name, lit("Buffer"), type}); - } - else - { - return new RDTreeWidgetItem({regname + name, lit("Resource"), lit("unknown")}); - } -} - -void ShaderViewer::addFileList() -{ - QListWidget *list = new QListWidget(this); - list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - list->setSelectionMode(QAbstractItemView::SingleSelection); - QObject::connect(list, &QListWidget::currentRowChanged, - [this](int idx) { ToolWindowManager::raiseToolWindow(m_Scintillas[idx]); }); - list->setWindowTitle(tr("File List")); - - for(ScintillaEdit *s : m_Scintillas) - list->addItem(s->windowTitle()); - - ui->docking->addToolWindow( - list, ToolWindowManager::AreaReference(ToolWindowManager::LeftOf, - ui->docking->areaOf(m_Scintillas.front()), 0.2f)); - ui->docking->setToolWindowProperties( - list, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow); -} - -void ShaderViewer::updateDebugging() -{ - if(!m_Trace || m_CurrentStep < 0 || m_CurrentStep >= m_Trace->states.count) - return; - - const ShaderDebugState &state = m_Trace->states[m_CurrentStep]; - - uint32_t nextInst = state.nextInstruction; - bool done = false; - - if(m_CurrentStep == m_Trace->states.count - 1) - { - nextInst--; - done = true; - } - - // add current instruction marker - m_DisassemblyView->markerDeleteAll(CURRENT_MARKER); - m_DisassemblyView->markerDeleteAll(CURRENT_MARKER + 1); - m_DisassemblyView->markerDeleteAll(FINISHED_MARKER); - m_DisassemblyView->markerDeleteAll(FINISHED_MARKER + 1); - - for(sptr_t i = 0; i < m_DisassemblyView->lineCount(); i++) - { - if(QString::fromUtf8(m_DisassemblyView->getLine(i).trimmed()) - .startsWith(QFormatStr("%1:").arg(nextInst))) - { - m_DisassemblyView->markerAdd(i, done ? FINISHED_MARKER : CURRENT_MARKER); - m_DisassemblyView->markerAdd(i, done ? FINISHED_MARKER + 1 : CURRENT_MARKER + 1); - - int pos = m_DisassemblyView->positionFromLine(i); - m_DisassemblyView->setSelection(pos, pos); - - ensureLineScrolled(m_DisassemblyView, i); - break; - } - } - - if(ui->constants->topLevelItemCount() == 0) - { - for(int i = 0; i < m_Trace->cbuffers.count; i++) - { - for(int j = 0; j < m_Trace->cbuffers[i].count; j++) - { - if(m_Trace->cbuffers[i][j].rows > 0 || m_Trace->cbuffers[i][j].columns > 0) - { - RDTreeWidgetItem *node = - new RDTreeWidgetItem({ToQStr(m_Trace->cbuffers[i][j].name), lit("cbuffer"), - stringRep(m_Trace->cbuffers[i][j], false)}); - node->setTag(QVariant::fromValue(VariableTag(VariableCategory::Constants, j, i))); - - ui->constants->addTopLevelItem(node); - } - } - } - - for(int i = 0; i < m_Trace->inputs.count; i++) - { - const ShaderVariable &input = m_Trace->inputs[i]; - - if(input.rows > 0 || input.columns > 0) - { - RDTreeWidgetItem *node = new RDTreeWidgetItem( - {ToQStr(input.name), ToQStr(input.type) + lit(" input"), stringRep(input, true)}); - node->setTag(QVariant::fromValue(VariableTag(VariableCategory::Inputs, i))); - - ui->constants->addTopLevelItem(node); - } - } - - QMap> rw = - m_Ctx.CurPipelineState().GetReadWriteResources(m_Stage); - QMap> ro = - m_Ctx.CurPipelineState().GetReadOnlyResources(m_Stage); - - bool tree = false; - - for(int i = 0; - i < m_Mapping->ReadWriteResources.count && i < m_ShaderDetails->ReadWriteResources.count; i++) - { - BindpointMap bind = m_Mapping->ReadWriteResources[i]; - - if(!bind.used) - continue; - - if(bind.arraySize == 1) - { - RDTreeWidgetItem *node = - makeResourceRegister(bind, 0, rw[bind][0], m_ShaderDetails->ReadWriteResources[i]); - if(node) - ui->constants->addTopLevelItem(node); - } - else - { - RDTreeWidgetItem *node = - new RDTreeWidgetItem({ToQStr(m_ShaderDetails->ReadWriteResources[i].name), - QFormatStr("[%1]").arg(bind.arraySize), QString()}); - - for(uint32_t a = 0; a < bind.arraySize; a++) - node->addChild( - makeResourceRegister(bind, a, rw[bind][a], m_ShaderDetails->ReadWriteResources[i])); - - tree = true; - - ui->constants->addTopLevelItem(node); - } - } - - for(int i = 0; - i < m_Mapping->ReadOnlyResources.count && i < m_ShaderDetails->ReadOnlyResources.count; i++) - { - BindpointMap bind = m_Mapping->ReadOnlyResources[i]; - - if(!bind.used) - continue; - - if(bind.arraySize == 1) - { - RDTreeWidgetItem *node = - makeResourceRegister(bind, 0, ro[bind][0], m_ShaderDetails->ReadOnlyResources[i]); - if(node) - ui->constants->addTopLevelItem(node); - } - else - { - RDTreeWidgetItem *node = - new RDTreeWidgetItem({ToQStr(m_ShaderDetails->ReadOnlyResources[i].name), - QFormatStr("[%1]").arg(bind.arraySize), QString()}); - - for(uint32_t a = 0; a < bind.arraySize; a++) - node->addChild( - makeResourceRegister(bind, a, ro[bind][a], m_ShaderDetails->ReadOnlyResources[i])); - - tree = true; - - ui->constants->addTopLevelItem(node); - } - } - - if(tree) - { - ui->constants->setIndentation(20); - ui->constants->setRootIsDecorated(true); - } - } - - if(ui->variables->topLevelItemCount() == 0) - { - for(int i = 0; i < state.registers.count; i++) - ui->variables->addTopLevelItem( - new RDTreeWidgetItem({ToQStr(state.registers[i].name), lit("temporary"), QString()})); - - for(int i = 0; i < state.indexableTemps.count; i++) - { - RDTreeWidgetItem *node = - new RDTreeWidgetItem({QFormatStr("x%1").arg(i), lit("indexable"), QString()}); - for(int t = 0; t < state.indexableTemps[i].count; t++) - node->addChild(new RDTreeWidgetItem( - {ToQStr(state.indexableTemps[i][t].name), lit("indexable"), QString()})); - ui->variables->addTopLevelItem(node); - } - - for(int i = 0; i < state.outputs.count; i++) - ui->variables->addTopLevelItem( - new RDTreeWidgetItem({ToQStr(state.outputs[i].name), lit("output"), QString()})); - } - - ui->variables->setUpdatesEnabled(false); - - int v = 0; - - for(int i = 0; i < state.registers.count; i++) - { - RDTreeWidgetItem *node = ui->variables->topLevelItem(v++); - - node->setText(2, stringRep(state.registers[i], false)); - node->setTag(QVariant::fromValue(VariableTag(VariableCategory::Temporaries, i))); - } - - for(int i = 0; i < state.indexableTemps.count; i++) - { - RDTreeWidgetItem *node = ui->variables->topLevelItem(v++); - - for(int t = 0; t < state.indexableTemps[i].count; t++) - { - RDTreeWidgetItem *child = node->child(t); - - child->setText(2, stringRep(state.indexableTemps[i][t], false)); - child->setTag(QVariant::fromValue(VariableTag(VariableCategory::IndexTemporaries, t, i))); - } - } - - for(int i = 0; i < state.outputs.count; i++) - { - RDTreeWidgetItem *node = ui->variables->topLevelItem(v++); - - node->setText(2, stringRep(state.outputs[i], false)); - node->setTag(QVariant::fromValue(VariableTag(VariableCategory::Outputs, i))); - } - - ui->variables->setUpdatesEnabled(true); - - ui->watch->setUpdatesEnabled(false); - - for(int i = 0; i < ui->watch->rowCount() - 1; i++) - { - QTableWidgetItem *item = ui->watch->item(i, 0); - ui->watch->setItem(i, 1, new QTableWidgetItem(tr("register", "watch type"))); - - QString reg = item->text().trimmed(); - - QRegularExpression regexp(lit("^([rvo])([0-9]+)(\\.[xyzwrgba]+)?(,[xfiudb])?$")); - - QRegularExpressionMatch match = regexp.match(reg); - - // try indexable temps - if(!match.hasMatch()) - { - regexp = QRegularExpression(lit("^(x[0-9]+)\\[([0-9]+)\\](\\.[xyzwrgba]+)?(,[xfiudb])?$")); - - match = regexp.match(reg); - } - - if(match.hasMatch()) - { - QString regtype = match.captured(1); - QString regidx = match.captured(2); - QString swizzle = match.captured(3).replace(QLatin1Char('.'), QString()); - QString regcast = match.captured(4).replace(QLatin1Char(','), QString()); - - if(regcast.isEmpty()) - { - if(ui->intView->isChecked()) - regcast = lit("i"); - else - regcast = lit("f"); - } - - VariableCategory varCat = VariableCategory::Unknown; - int arrIndex = -1; - - bool ok = false; - - if(regtype == lit("r")) - { - varCat = VariableCategory::Temporaries; - } - else if(regtype == lit("v")) - { - varCat = VariableCategory::Inputs; - } - else if(regtype == lit("o")) - { - varCat = VariableCategory::Outputs; - } - else if(regtype[0] == QLatin1Char('x')) - { - varCat = VariableCategory::IndexTemporaries; - QString tempArrayIndexStr = regtype.mid(1); - arrIndex = tempArrayIndexStr.toInt(&ok); - - if(!ok) - arrIndex = -1; - } - - const rdctype::array *vars = GetVariableList(varCat, arrIndex); - - ok = false; - int regindex = regidx.toInt(&ok); - - if(vars && ok && regindex >= 0 && regindex < vars->count) - { - const ShaderVariable &vr = vars->elems[regindex]; - - if(swizzle.isEmpty()) - { - swizzle = lit("xyzw").left((int)vr.columns); - - if(regcast == lit("d") && swizzle.count() > 2) - swizzle = lit("xy"); - } - - QString val; - - for(int s = 0; s < swizzle.count(); s++) - { - QChar swiz = swizzle[s]; - - int elindex = 0; - if(swiz == QLatin1Char('x') || swiz == QLatin1Char('r')) - elindex = 0; - if(swiz == QLatin1Char('y') || swiz == QLatin1Char('g')) - elindex = 1; - if(swiz == QLatin1Char('z') || swiz == QLatin1Char('b')) - elindex = 2; - if(swiz == QLatin1Char('w') || swiz == QLatin1Char('a')) - elindex = 3; - - if(regcast == lit("i")) - { - val += Formatter::Format(vr.value.iv[elindex]); - } - else if(regcast == lit("f")) - { - val += Formatter::Format(vr.value.fv[elindex]); - } - else if(regcast == lit("u")) - { - val += Formatter::Format(vr.value.uv[elindex]); - } - else if(regcast == lit("x")) - { - val += Formatter::Format(vr.value.uv[elindex], true); - } - else if(regcast == lit("b")) - { - val += QFormatStr("%1").arg(vr.value.uv[elindex], 32, 2, QLatin1Char('0')); - } - else if(regcast == lit("d")) - { - if(elindex < 2) - val += Formatter::Format(vr.value.dv[elindex]); - else - val += lit("-"); - } - - if(s < swizzle.count() - 1) - val += lit(", "); - } - - item = new QTableWidgetItem(val); - item->setData(Qt::UserRole, QVariant::fromValue(VariableTag(varCat, regindex, arrIndex))); - - ui->watch->setItem(i, 2, item); - - continue; - } - } - - ui->watch->setItem(i, 2, new QTableWidgetItem(tr("Error evaluating expression"))); - } - - ui->watch->setUpdatesEnabled(true); - - updateVariableTooltip(); -} - -void ShaderViewer::ensureLineScrolled(ScintillaEdit *s, int line) -{ - int firstLine = s->firstVisibleLine(); - int linesVisible = s->linesOnScreen(); - - if(s->isVisible() && (line < firstLine || line > (firstLine + linesVisible))) - s->scrollCaret(); -} - -int ShaderViewer::CurrentStep() -{ - return m_CurrentStep; -} - -void ShaderViewer::SetCurrentStep(int step) -{ - if(m_Trace && !m_Trace->states.empty()) - m_CurrentStep = qBound(0, step, m_Trace->states.count - 1); - else - m_CurrentStep = 0; - - updateDebugging(); -} - -void ShaderViewer::ToggleBreakpoint(int instruction) -{ - sptr_t instLine = -1; - - if(instruction == -1) - { - // search forward for an instruction - instLine = m_DisassemblyView->lineFromPosition(m_DisassemblyView->currentPos()); - - for(; instLine < m_DisassemblyView->lineCount(); instLine++) - { - instruction = instructionForLine(instLine); - - if(instruction >= 0) - break; - } - } - - if(instruction < 0 || instruction >= m_DisassemblyView->lineCount()) - return; - - if(instLine == -1) - { - // find line for this instruction - for(instLine = 0; instLine < m_DisassemblyView->lineCount(); instLine++) - { - int inst = instructionForLine(instLine); - - if(instruction == inst) - break; - } - - if(instLine >= m_DisassemblyView->lineCount()) - instLine = -1; - } - - if(m_Breakpoints.contains(instruction)) - { - if(instLine >= 0) - { - m_DisassemblyView->markerDelete(instLine, BREAKPOINT_MARKER); - m_DisassemblyView->markerDelete(instLine, BREAKPOINT_MARKER + 1); - } - m_Breakpoints.removeOne(instruction); - } - else - { - if(instLine >= 0) - { - m_DisassemblyView->markerAdd(instLine, BREAKPOINT_MARKER); - m_DisassemblyView->markerAdd(instLine, BREAKPOINT_MARKER + 1); - } - m_Breakpoints.push_back(instruction); - } -} - -void ShaderViewer::ShowErrors(const QString &errors) -{ - if(m_Errors) - { - m_Errors->setReadOnly(false); - m_Errors->setText(errors.toUtf8().data()); - m_Errors->setReadOnly(true); - } -} - -int ShaderViewer::snippetPos() -{ - if(IsD3D(m_Ctx.APIProps().pipelineType)) - return 0; - - if(m_Scintillas.isEmpty()) - return 0; - - QPair ver = - m_Scintillas[0]->findText(SCFIND_REGEXP, "#version.*", 0, m_Scintillas[0]->length()); - - if(ver.first < 0) - return 0; - - return ver.second + 1; -} - -void ShaderViewer::insertVulkanUBO() -{ - if(m_Scintillas.isEmpty()) - return; - - m_Scintillas[0]->insertText(snippetPos(), - "layout(binding = 0, std140) uniform RENDERDOC_Uniforms\n" - "{\n" - " uvec4 TexDim;\n" - " uint SelectedMip;\n" - " int TextureType;\n" - " uint SelectedSliceFace;\n" - " int SelectedSample;\n" - "} RENDERDOC;\n\n"); -} - -void ShaderViewer::snippet_textureDimensions() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText(snippetPos(), - "// xyz == width, height, depth. w == # mips\n" - "uint4 RENDERDOC_TexDim; \n\n"); - } - else if(api == GraphicsAPI::OpenGL) - { - m_Scintillas[0]->insertText(snippetPos(), - "// xyz == width, height, depth. w == # mips\n" - "uniform uvec4 RENDERDOC_TexDim;\n\n"); - } - else if(api == GraphicsAPI::Vulkan) - { - insertVulkanUBO(); - } - - m_Scintillas[0]->setSelection(0, 0); -} - -void ShaderViewer::snippet_selectedMip() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText(snippetPos(), - "// selected mip in UI\n" - "uint RENDERDOC_SelectedMip;\n\n"); - } - else if(api == GraphicsAPI::OpenGL) - { - m_Scintillas[0]->insertText(snippetPos(), - "// selected mip in UI\n" - "uniform uint RENDERDOC_SelectedMip;\n\n"); - } - else if(api == GraphicsAPI::Vulkan) - { - insertVulkanUBO(); - } - - m_Scintillas[0]->setSelection(0, 0); -} - -void ShaderViewer::snippet_selectedSlice() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText(snippetPos(), - "// selected array slice or cubemap face in UI\n" - "uint RENDERDOC_SelectedSliceFace;\n\n"); - } - else if(api == GraphicsAPI::OpenGL) - { - m_Scintillas[0]->insertText(snippetPos(), - "// selected array slice or cubemap face in UI\n" - "uniform uint RENDERDOC_SelectedSliceFace;\n\n"); - } - else if(api == GraphicsAPI::Vulkan) - { - insertVulkanUBO(); - } - - m_Scintillas[0]->setSelection(0, 0); -} - -void ShaderViewer::snippet_selectedSample() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText(snippetPos(), - "// selected MSAA sample or -numSamples for resolve. See docs\n" - "int RENDERDOC_SelectedSample;\n\n"); - } - else if(api == GraphicsAPI::OpenGL) - { - m_Scintillas[0]->insertText(snippetPos(), - "// selected MSAA sample or -numSamples for resolve. See docs\n" - "uniform int RENDERDOC_SelectedSample;\n\n"); - } - else if(api == GraphicsAPI::Vulkan) - { - insertVulkanUBO(); - } - - m_Scintillas[0]->setSelection(0, 0); -} - -void ShaderViewer::snippet_selectedType() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText(snippetPos(), - "// 1 = 1D, 2 = 2D, 3 = 3D, 4 = Depth, 5 = Depth + Stencil\n" - "// 6 = Depth (MS), 7 = Depth + Stencil (MS)\n" - "uint RENDERDOC_TextureType;\n\n"); - } - else if(api == GraphicsAPI::OpenGL) - { - m_Scintillas[0]->insertText(snippetPos(), - "// 1 = 1D, 2 = 2D, 3 = 3D, 4 = Cube\n" - "// 5 = 1DArray, 6 = 2DArray, 7 = CubeArray\n" - "// 8 = Rect, 9 = Buffer, 10 = 2DMS\n" - "uniform uint RENDERDOC_TextureType;\n\n"); - } - else if(api == GraphicsAPI::Vulkan) - { - insertVulkanUBO(); - } - - m_Scintillas[0]->setSelection(0, 0); -} - -void ShaderViewer::snippet_samplers() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText(snippetPos(), - "// Samplers\n" - "SamplerState pointSampler : register(s0);\n" - "SamplerState linearSampler : register(s1);\n" - "// End Samplers\n\n"); - - m_Scintillas[0]->setSelection(0, 0); - } -} - -void ShaderViewer::snippet_resources() -{ - if(m_Scintillas.isEmpty()) - return; - - GraphicsAPI api = m_Ctx.APIProps().pipelineType; - - if(IsD3D(api)) - { - m_Scintillas[0]->insertText( - snippetPos(), - "// Textures\n" - "Texture1DArray texDisplayTex1DArray : register(t1);\n" - "Texture2DArray texDisplayTex2DArray : register(t2);\n" - "Texture3D texDisplayTex3D : register(t3);\n" - "Texture2DArray texDisplayTexDepthArray : register(t4);\n" - "Texture2DArray texDisplayTexStencilArray : register(t5);\n" - "Texture2DMSArray texDisplayTexDepthMSArray : register(t6);\n" - "Texture2DMSArray texDisplayTexStencilMSArray : register(t7);\n" - "Texture2DMSArray texDisplayTex2DMSArray : register(t9);\n" - "\n" - "Texture1DArray texDisplayUIntTex1DArray : register(t11);\n" - "Texture2DArray texDisplayUIntTex2DArray : register(t12);\n" - "Texture3D texDisplayUIntTex3D : register(t13);\n" - "Texture2DMSArray texDisplayUIntTex2DMSArray : register(t19);\n" - "\n" - "Texture1DArray texDisplayIntTex1DArray : register(t21);\n" - "Texture2DArray texDisplayIntTex2DArray : register(t22);\n" - "Texture3D texDisplayIntTex3D : register(t23);\n" - "Texture2DMSArray texDisplayIntTex2DMSArray : register(t29);\n" - "// End Textures\n\n\n"); - } - else if(api == GraphicsAPI::OpenGL) - { - m_Scintillas[0]->insertText(snippetPos(), - "// Textures\n" - "// Unsigned int samplers\n" - "layout (binding = 1) uniform usampler1D texUInt1D;\n" - "layout (binding = 2) uniform usampler2D texUInt2D;\n" - "layout (binding = 3) uniform usampler3D texUInt3D;\n" - "// cube = 4\n" - "layout (binding = 5) uniform usampler1DArray texUInt1DArray;\n" - "layout (binding = 6) uniform usampler2DArray texUInt2DArray;\n" - "// cube array = 7\n" - "layout (binding = 8) uniform usampler2DRect texUInt2DRect;\n" - "layout (binding = 9) uniform usamplerBuffer texUIntBuffer;\n" - "layout (binding = 10) uniform usampler2DMS texUInt2DMS;\n" - "\n" - "// Int samplers\n" - "layout (binding = 1) uniform isampler1D texSInt1D;\n" - "layout (binding = 2) uniform isampler2D texSInt2D;\n" - "layout (binding = 3) uniform isampler3D texSInt3D;\n" - "// cube = 4\n" - "layout (binding = 5) uniform isampler1DArray texSInt1DArray;\n" - "layout (binding = 6) uniform isampler2DArray texSInt2DArray;\n" - "// cube array = 7\n" - "layout (binding = 8) uniform isampler2DRect texSInt2DRect;\n" - "layout (binding = 9) uniform isamplerBuffer texSIntBuffer;\n" - "layout (binding = 10) uniform isampler2DMS texSInt2DMS;\n" - "\n" - "// Floating point samplers\n" - "layout (binding = 1) uniform sampler1D tex1D;\n" - "layout (binding = 2) uniform sampler2D tex2D;\n" - "layout (binding = 3) uniform sampler3D tex3D;\n" - "layout (binding = 4) uniform samplerCube texCube;\n" - "layout (binding = 5) uniform sampler1DArray tex1DArray;\n" - "layout (binding = 6) uniform sampler2DArray tex2DArray;\n" - "layout (binding = 7) uniform samplerCubeArray texCubeArray;\n" - "layout (binding = 8) uniform sampler2DRect tex2DRect;\n" - "layout (binding = 9) uniform samplerBuffer texBuffer;\n" - "layout (binding = 10) uniform sampler2DMS tex2DMS;\n" - "// End Textures\n\n\n"); - } - else if(api == GraphicsAPI::Vulkan) - { - m_Scintillas[0]->insertText(snippetPos(), - "// Textures\n" - "// Floating point samplers\n" - "layout(binding = 6) uniform sampler1DArray tex1DArray;\n" - "layout(binding = 7) uniform sampler2DArray tex2DArray;\n" - "layout(binding = 8) uniform sampler3D tex3D;\n" - "layout(binding = 9) uniform sampler2DMS tex2DMS;\n" - "\n" - "// Unsigned int samplers\n" - "layout(binding = 11) uniform usampler1DArray texUInt1DArray;\n" - "layout(binding = 12) uniform usampler2DArray texUInt2DArray;\n" - "layout(binding = 13) uniform usampler3D texUInt3D;\n" - "layout(binding = 14) uniform usampler2DMS texUInt2DMS;\n" - "\n" - "// Int samplers\n" - "layout(binding = 16) uniform isampler1DArray texSInt1DArray;\n" - "layout(binding = 17) uniform isampler2DArray texSInt2DArray;\n" - "layout(binding = 18) uniform isampler3D texSInt3D;\n" - "layout(binding = 19) uniform isampler2DMS texSInt2DMS;\n" - "// End Textures\n\n\n"); - } - - m_Scintillas[0]->setSelection(0, 0); -} - -bool ShaderViewer::eventFilter(QObject *watched, QEvent *event) -{ - if(event->type() == QEvent::ToolTip) - { - QHelpEvent *he = (QHelpEvent *)event; - - RDTreeWidget *tree = qobject_cast(watched); - if(tree) - { - RDTreeWidgetItem *item = tree->itemAt(tree->viewport()->mapFromGlobal(QCursor::pos())); - if(item) - { - VariableTag tag = item->tag().value(); - showVariableTooltip(tag.cat, tag.idx, tag.arrayIdx); - } - } - - RDTableWidget *table = qobject_cast(watched); - if(table) - { - QTableWidgetItem *item = table->itemAt(table->viewport()->mapFromGlobal(QCursor::pos())); - if(item) - { - item = table->item(item->row(), 2); - VariableTag tag = item->data(Qt::UserRole).value(); - showVariableTooltip(tag.cat, tag.idx, tag.arrayIdx); - } - } - } - if(event->type() == QEvent::MouseMove || event->type() == QEvent::Leave) - { - hideVariableTooltip(); - } - - return QFrame::eventFilter(watched, event); -} - -void ShaderViewer::disasm_tooltipShow(int x, int y) -{ - // do nothing if there's no trace - if(!m_Trace || m_CurrentStep < 0 || m_CurrentStep >= m_Trace->states.count) - return; - - // ignore any messages if we're already outside the viewport - if(!m_DisassemblyView->rect().contains(m_DisassemblyView->mapFromGlobal(QCursor::pos()))) - return; - - if(m_DisassemblyView->isVisible()) - { - sptr_t scintillaPos = m_DisassemblyView->positionFromPoint(x, y); - - sptr_t start = m_DisassemblyView->wordStartPosition(scintillaPos, true); - sptr_t end = m_DisassemblyView->wordEndPosition(scintillaPos, true); - - QString text = QString::fromUtf8(m_DisassemblyView->textRange(start, end)); - - if(!text.isEmpty()) - { - VariableTag tag; - getRegisterFromWord(text, tag.cat, tag.idx, tag.arrayIdx); - - if(tag.cat != VariableCategory::Unknown && tag.idx >= 0 && tag.arrayIdx >= 0) - showVariableTooltip(tag.cat, tag.idx, tag.arrayIdx); - } - } -} - -void ShaderViewer::disasm_tooltipHide(int x, int y) -{ - hideVariableTooltip(); -} - -void ShaderViewer::showVariableTooltip(VariableCategory varCat, int varIdx, int arrayIdx) -{ - const rdctype::array *vars = GetVariableList(varCat, arrayIdx); - - if(!vars || varIdx < 0 || varIdx >= vars->count) - { - m_TooltipVarIdx = -1; - return; - } - - m_TooltipVarCat = varCat; - m_TooltipVarIdx = varIdx; - m_TooltipArrayIdx = arrayIdx; - m_TooltipPos = QCursor::pos(); - - updateVariableTooltip(); -} - -const rdctype::array *ShaderViewer::GetVariableList(VariableCategory varCat, - int arrayIdx) -{ - const rdctype::array *vars = NULL; - - if(!m_Trace || m_CurrentStep < 0 || m_CurrentStep >= m_Trace->states.count) - return vars; - - const ShaderDebugState &state = m_Trace->states[m_CurrentStep]; - - arrayIdx = qMax(0, arrayIdx); - - switch(varCat) - { - case VariableCategory::Unknown: vars = NULL; break; - case VariableCategory::Temporaries: vars = &state.registers; break; - case VariableCategory::IndexTemporaries: - vars = arrayIdx < state.indexableTemps.count ? &state.indexableTemps[arrayIdx] : NULL; - break; - case VariableCategory::Inputs: vars = &m_Trace->inputs; break; - case VariableCategory::Constants: - vars = arrayIdx < m_Trace->cbuffers.count ? &m_Trace->cbuffers[arrayIdx] : NULL; - break; - case VariableCategory::Outputs: vars = &state.outputs; break; - } - - return vars; -} - -void ShaderViewer::getRegisterFromWord(const QString &text, VariableCategory &varCat, int &varIdx, - int &arrayIdx) -{ - QChar regtype = text[0]; - QString regidx = text.mid(1); - - varCat = VariableCategory::Unknown; - varIdx = -1; - arrayIdx = 0; - - if(regtype == QLatin1Char('r')) - varCat = VariableCategory::Temporaries; - else if(regtype == QLatin1Char('v')) - varCat = VariableCategory::Inputs; - else if(regtype == QLatin1Char('o')) - varCat = VariableCategory::Outputs; - else - return; - - bool ok = false; - varIdx = regidx.toInt(&ok); - - // if we have a list of registers and the index is in range, and we matched the whole word - // (i.e. v0foo is not the same as v0), then show the tooltip - if(QFormatStr("%1%2").arg(regtype).arg(varIdx) != text) - { - varCat = VariableCategory::Unknown; - varIdx = -1; - } -} - -void ShaderViewer::updateVariableTooltip() -{ - if(m_TooltipVarIdx < 0) - return; - - const rdctype::array *vars = GetVariableList(m_TooltipVarCat, m_TooltipArrayIdx); - const ShaderVariable &var = vars->elems[m_TooltipVarIdx]; - - QString text = QFormatStr("
%1\n").arg(ToQStr(var.name));
-  text +=
-      lit("                 X          Y          Z          W \n"
-          "----------------------------------------------------\n");
-
-  text += QFormatStr("float | %1 %2 %3 %4\n")
-              .arg(Formatter::Format(var.value.fv[0]), 10)
-              .arg(Formatter::Format(var.value.fv[1]), 10)
-              .arg(Formatter::Format(var.value.fv[2]), 10)
-              .arg(Formatter::Format(var.value.fv[3]), 10);
-  text += QFormatStr("uint  | %1 %2 %3 %4\n")
-              .arg(var.value.uv[0], 10, 10, QLatin1Char(' '))
-              .arg(var.value.uv[1], 10, 10, QLatin1Char(' '))
-              .arg(var.value.uv[2], 10, 10, QLatin1Char(' '))
-              .arg(var.value.uv[3], 10, 10, QLatin1Char(' '));
-  text += QFormatStr("int   | %1 %2 %3 %4\n")
-              .arg(var.value.iv[0], 10, 10, QLatin1Char(' '))
-              .arg(var.value.iv[1], 10, 10, QLatin1Char(' '))
-              .arg(var.value.iv[2], 10, 10, QLatin1Char(' '))
-              .arg(var.value.iv[3], 10, 10, QLatin1Char(' '));
-  text += QFormatStr("hex   |   %1   %2   %3   %4")
-              .arg(Formatter::HexFormat(var.value.uv[0], 4))
-              .arg(Formatter::HexFormat(var.value.uv[1], 4))
-              .arg(Formatter::HexFormat(var.value.uv[2], 4))
-              .arg(Formatter::HexFormat(var.value.uv[3], 4));
-
-  text += lit("
"); - - QToolTip::showText(m_TooltipPos, text); -} - -void ShaderViewer::hideVariableTooltip() -{ - QToolTip::hideText(); - m_TooltipVarIdx = -1; -} - -void ShaderViewer::on_findReplace_clicked() -{ - if(m_FindReplace->isVisible()) - { - ToolWindowManager::raiseToolWindow(m_FindReplace); - } - else - { - ui->docking->moveToolWindow( - m_FindReplace, ToolWindowManager::AreaReference(ToolWindowManager::NewFloatingArea)); - ui->docking->setToolWindowProperties(m_FindReplace, ToolWindowManager::HideOnClose); - } - ui->docking->areaOf(m_FindReplace)->parentWidget()->activateWindow(); - m_FindReplace->takeFocus(); -} - -void ShaderViewer::on_save_clicked() -{ - if(m_Trace) - { - m_Ctx.GetPipelineViewer()->SaveShaderFile(m_ShaderDetails); - return; - } - - if(m_SaveCallback) - { - QMap files; - for(ScintillaEdit *s : m_Scintillas) - { - QWidget *w = (QWidget *)s; - files[w->property("filename").toString()] = QString::fromUtf8(s->getText(s->textLength() + 1)); - } - m_SaveCallback(&m_Ctx, this, files); - } -} - -void ShaderViewer::on_intView_clicked() -{ - ui->intView->setChecked(true); - ui->floatView->setChecked(false); - - updateDebugging(); -} - -void ShaderViewer::on_floatView_clicked() -{ - ui->floatView->setChecked(true); - ui->intView->setChecked(false); - - updateDebugging(); -} - -ScintillaEdit *ShaderViewer::currentScintilla() -{ - ScintillaEdit *cur = qobject_cast(QApplication::focusWidget()); - - if(cur == NULL) - { - for(ScintillaEdit *s : m_Scintillas) - { - if(s->isVisible()) - { - cur = s; - break; - } - } - } - - return cur; -} - -ScintillaEdit *ShaderViewer::nextScintilla(ScintillaEdit *cur) -{ - for(int i = 0; i < m_Scintillas.count(); i++) - { - if(m_Scintillas[i] == cur) - { - if(i + 1 < m_Scintillas.count()) - return m_Scintillas[i + 1]; - - return m_Scintillas[0]; - } - } - - if(!m_Scintillas.isEmpty()) - return m_Scintillas[0]; - - return NULL; -} - -void ShaderViewer::find(bool down) -{ - ScintillaEdit *cur = currentScintilla(); - - if(!cur) - return; - - QString find = m_FindReplace->findText(); - - sptr_t flags = 0; - - if(m_FindReplace->matchCase()) - flags |= SCFIND_MATCHCASE; - if(m_FindReplace->matchWord()) - flags |= SCFIND_WHOLEWORD; - if(m_FindReplace->regexp()) - flags |= SCFIND_REGEXP | SCFIND_POSIX; - - FindReplace::SearchContext context = m_FindReplace->context(); - - QString findHash = QFormatStr("%1%2%3").arg(find).arg(flags).arg((int)context); - - if(findHash != m_FindState.hash) - { - m_FindState.hash = findHash; - m_FindState.start = 0; - m_FindState.end = cur->length(); - m_FindState.offset = cur->currentPos(); - } - - int start = m_FindState.start + m_FindState.offset; - int end = m_FindState.end; - - if(!down) - end = m_FindState.start; - - QPair result = cur->findText(flags, find.toUtf8().data(), start, end); - - m_FindState.prevResult = result; - - if(result.first == -1) - { - sptr_t maxOffset = down ? 0 : m_FindState.end; - - // if we're at offset 0 searching down, there are no results. Same for offset max and searching - // up - if(m_FindState.offset == maxOffset) - return; - - // otherwise, we can wrap the search around - - if(context == FindReplace::AllFiles) - { - cur = nextScintilla(cur); - ToolWindowManager::raiseToolWindow(cur); - cur->activateWindow(); - cur->QWidget::setFocus(); - } - - m_FindState.offset = maxOffset; - - start = m_FindState.start + m_FindState.offset; - end = m_FindState.end; - - if(!down) - end = m_FindState.start; - - result = cur->findText(flags, find.toUtf8().data(), start, end); - - m_FindState.prevResult = result; - - if(result.first == -1) - return; - } - - cur->setSelection(result.first, result.second); - - ensureLineScrolled(cur, cur->lineFromPosition(result.first)); - - if(down) - m_FindState.offset = result.second - m_FindState.start; - else - m_FindState.offset = result.first - m_FindState.start; -} - -void ShaderViewer::performFind() -{ - find(m_FindReplace->direction() == FindReplace::Down); -} - -void ShaderViewer::performFindAll() -{ - ScintillaEdit *cur = currentScintilla(); - - if(!cur) - return; - - QString find = m_FindReplace->findText(); - - sptr_t flags = 0; - - QString results = tr("Find all \"%1\"").arg(find); - - if(m_FindReplace->matchCase()) - { - flags |= SCFIND_MATCHCASE; - results += tr(", Match case"); - } - - if(m_FindReplace->matchWord()) - { - flags |= SCFIND_WHOLEWORD; - results += tr(", Match whole word"); - } - - if(m_FindReplace->regexp()) - { - flags |= SCFIND_REGEXP | SCFIND_POSIX; - results += tr(", with Regular Expressions"); - } - - FindReplace::SearchContext context = m_FindReplace->context(); - - if(context == FindReplace::File) - results += tr(", in current file\n"); - else - results += tr(", in all files\n"); - - // trash the find state for any incremental finds - m_FindState = FindState(); - - QList scintillas = m_Scintillas; - - if(context == FindReplace::File) - scintillas = {cur}; - - QList> resultList; - - QByteArray findUtf8 = find.toUtf8(); - - for(ScintillaEdit *s : scintillas) - { - sptr_t start = 0; - sptr_t end = s->length(); - - s->setIndicatorCurrent(INDICATOR_FINDRESULT); - s->indicatorClearRange(start, end); - - if(findUtf8.isEmpty()) - continue; - - QPair result; - - do - { - result = s->findText(flags, findUtf8.data(), start, end); - - if(result.first >= 0) - { - int line = s->lineFromPosition(result.first); - sptr_t lineStart = s->positionFromLine(line); - sptr_t lineEnd = s->lineEndPosition(line); - - s->indicatorFillRange(result.first, result.second - result.first); - - QString lineText = QString::fromUtf8(s->textRange(lineStart, lineEnd)); - - results += QFormatStr(" %1(%2): ").arg(s->windowTitle()).arg(line, 4); - int startPos = results.length(); - - results += lineText; - results += lit("\n"); - - resultList.push_back( - qMakePair(result.first - lineStart + startPos, result.second - lineStart + startPos)); - } - - start = result.second; - - } while(result.first >= 0); - } - - if(findUtf8.isEmpty()) - return; - - results += tr("Matching lines: %1").arg(resultList.count()); - - m_FindResults->setReadOnly(false); - m_FindResults->setText(results.toUtf8().data()); - - m_FindResults->setIndicatorCurrent(INDICATOR_FINDRESULT); - - for(QPair r : resultList) - m_FindResults->indicatorFillRange(r.first, r.second - r.first); - - m_FindResults->setReadOnly(true); - - if(m_FindResults->isVisible()) - { - ToolWindowManager::raiseToolWindow(m_FindResults); - } - else - { - ui->docking->moveToolWindow(m_FindResults, - ToolWindowManager::AreaReference(ToolWindowManager::BottomOf, - ui->docking->areaOf(cur), 0.2f)); - ui->docking->setToolWindowProperties(m_FindResults, ToolWindowManager::HideOnClose); - } -} - -void ShaderViewer::performReplace() -{ - ScintillaEdit *cur = currentScintilla(); - - if(!cur) - return; - - QString find = m_FindReplace->findText(); - - if(find.isEmpty()) - return; - - sptr_t flags = 0; - - if(m_FindReplace->matchCase()) - flags |= SCFIND_MATCHCASE; - if(m_FindReplace->matchWord()) - flags |= SCFIND_WHOLEWORD; - if(m_FindReplace->regexp()) - flags |= SCFIND_REGEXP | SCFIND_POSIX; - - FindReplace::SearchContext context = m_FindReplace->context(); - - QString findHash = QFormatStr("%1%2%3").arg(find).arg(flags).arg((int)context); - - // if we didn't have a valid previous find, just do a find and bail - if(findHash != m_FindState.hash) - { - performFind(); - return; - } - - if(m_FindState.prevResult.first == -1) - return; - - cur->setTargetRange(m_FindState.prevResult.first, m_FindState.prevResult.second); - - FindState save = m_FindState; - - QString replaceText = m_FindReplace->replaceText(); - - // otherwise we have a valid previous find. Do the replace now - // note this will invalidate the find state (as most user operations would), so we save/restore - // the state - if(m_FindReplace->regexp()) - cur->replaceTargetRE(-1, replaceText.toUtf8().data()); - else - cur->replaceTarget(-1, replaceText.toUtf8().data()); - - m_FindState = save; - - // adjust the offset if we replaced text and it went up or down in size - m_FindState.offset += (replaceText.count() - find.count()); - - // move to the next result - performFind(); -} - -void ShaderViewer::performReplaceAll() -{ - ScintillaEdit *cur = currentScintilla(); - - if(!cur) - return; - - QString find = m_FindReplace->findText(); - QString replace = m_FindReplace->replaceText(); - - if(find.isEmpty()) - return; - - sptr_t flags = 0; - - if(m_FindReplace->matchCase()) - flags |= SCFIND_MATCHCASE; - if(m_FindReplace->matchWord()) - flags |= SCFIND_WHOLEWORD; - if(m_FindReplace->regexp()) - flags |= SCFIND_REGEXP | SCFIND_POSIX; - - FindReplace::SearchContext context = m_FindReplace->context(); - - (void)context; - - // trash the find state for any incremental finds - m_FindState = FindState(); - - QList scintillas = m_Scintillas; - - if(context == FindReplace::File) - scintillas = {cur}; - - int numReplacements = 1; - - for(ScintillaEdit *s : scintillas) - { - sptr_t start = 0; - sptr_t end = s->length(); - - QPair result; - - QByteArray findUtf8 = find.toUtf8(); - QByteArray replaceUtf8 = replace.toUtf8(); - - do - { - result = s->findText(flags, findUtf8.data(), start, end); - - if(result.first >= 0) - { - s->setTargetRange(result.first, result.second); - - if(m_FindReplace->regexp()) - s->replaceTargetRE(-1, replaceUtf8.data()); - else - s->replaceTarget(-1, replaceUtf8.data()); - - numReplacements++; - } - - start = result.second + (replaceUtf8.count() - findUtf8.count()); - - } while(result.first >= 0); - } - - RDDialog::information( - this, tr("Replace all"), - tr("%1 replacements made in %2 files").arg(numReplacements).arg(scintillas.count())); -} diff --git a/qrenderdoc/Windows/ShaderViewer.h b/qrenderdoc/Windows/ShaderViewer.h deleted file mode 100644 index 136171fdd..000000000 --- a/qrenderdoc/Windows/ShaderViewer.h +++ /dev/null @@ -1,237 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -namespace Ui -{ -class ShaderViewer; -} - -class RDTreeWidgetItem; -struct ShaderDebugTrace; -struct ShaderReflection; -class ScintillaEdit; -class FindReplace; -class QTableWidgetItem; -class QKeyEvent; -class QMouseEvent; -class QComboBox; - -// from Scintilla -typedef intptr_t sptr_t; - -enum class VariableCategory -{ - Unknown, - Inputs, - Constants, - IndexTemporaries, - Temporaries, - Outputs, -}; - -class ShaderViewer : public QFrame, public IShaderViewer, public ILogViewer -{ - Q_OBJECT - -public: - static IShaderViewer *EditShader(ICaptureContext &ctx, bool customShader, const QString &entryPoint, - const QStringMap &files, IShaderViewer::SaveCallback saveCallback, - IShaderViewer::CloseCallback closeCallback, QWidget *parent) - { - ShaderViewer *ret = new ShaderViewer(ctx, parent); - ret->m_SaveCallback = saveCallback; - ret->m_CloseCallback = closeCallback; - ret->editShader(customShader, entryPoint, files); - return ret; - } - - static IShaderViewer *DebugShader(ICaptureContext &ctx, const ShaderBindpointMapping *bind, - const ShaderReflection *shader, ShaderStage stage, - ShaderDebugTrace *trace, const QString &debugContext, - QWidget *parent) - { - ShaderViewer *ret = new ShaderViewer(ctx, parent); - ret->debugShader(bind, shader, stage, trace, debugContext); - return ret; - } - - static IShaderViewer *ViewShader(ICaptureContext &ctx, const ShaderBindpointMapping *bind, - const ShaderReflection *shader, ShaderStage stage, QWidget *parent) - { - return DebugShader(ctx, bind, shader, stage, NULL, QString(), parent); - } - - ~ShaderViewer(); - - // IShaderViewer - virtual QWidget *Widget() override { return this; } - virtual int CurrentStep() override; - virtual void SetCurrentStep(int step) override; - - virtual void ToggleBreakpoint(int instruction = -1) override; - - virtual void ShowErrors(const QString &errors) override; - - // ILogViewerForm - void OnLogfileLoaded() override; - void OnLogfileClosed() override; - void OnSelectedEventChanged(uint32_t eventID) override {} - void OnEventChanged(uint32_t eventID) override; - -private slots: - // automatic slots - void on_findReplace_clicked(); - void on_save_clicked(); - void on_intView_clicked(); - void on_floatView_clicked(); - - void on_watch_itemChanged(QTableWidgetItem *item); - - // manual slots - void readonly_keyPressed(QKeyEvent *event); - void editable_keyPressed(QKeyEvent *event); - void disassembly_contextMenu(const QPoint &pos); - void disassembly_buttonReleased(QMouseEvent *event); - void disassemble_typeChanged(int index); - void watch_keyPress(QKeyEvent *event); - void performFind(); - void performFindAll(); - void performReplace(); - void performReplaceAll(); - - void snippet_textureDimensions(); - void snippet_selectedMip(); - void snippet_selectedSlice(); - void snippet_selectedSample(); - void snippet_selectedType(); - void snippet_samplers(); - void snippet_resources(); - - void disasm_tooltipShow(int x, int y); - void disasm_tooltipHide(int x, int y); - -public slots: - bool stepBack(); - bool stepNext(); - void runToCursor(); - void runToSample(); - void runToNanOrInf(); - void runBack(); - void run(); - -private: - explicit ShaderViewer(ICaptureContext &ctx, QWidget *parent = 0); - void editShader(bool customShader, const QString &entryPoint, const QStringMap &files); - void debugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader, - ShaderStage stage, ShaderDebugTrace *trace, const QString &debugContext); - - bool eventFilter(QObject *watched, QEvent *event) override; - - const rdctype::array *GetVariableList(VariableCategory varCat, int arrayIdx); - void getRegisterFromWord(const QString &text, VariableCategory &varCat, int &varIdx, int &arrayIdx); - - void showVariableTooltip(VariableCategory varCat, int varIdx, int arrayIdx); - void updateVariableTooltip(); - void hideVariableTooltip(); - - VariableCategory m_TooltipVarCat = VariableCategory::Temporaries; - int m_TooltipVarIdx = -1; - int m_TooltipArrayIdx = -1; - QPoint m_TooltipPos; - - Ui::ShaderViewer *ui; - ICaptureContext &m_Ctx; - const ShaderBindpointMapping *m_Mapping = NULL; - const ShaderReflection *m_ShaderDetails = NULL; - ShaderStage m_Stage; - ScintillaEdit *m_DisassemblyView = NULL; - QFrame *m_DisassemblyToolbar = NULL; - QWidget *m_DisassemblyFrame = NULL; - QComboBox *m_DisassemblyType = NULL; - ScintillaEdit *m_Errors = NULL; - ScintillaEdit *m_FindResults = NULL; - QList m_Scintillas; - - FindReplace *m_FindReplace; - - struct FindState - { - // hash identifies when the search has changed - QString hash; - - // the range identified when the search first occurred (for incremental find/replace) - sptr_t start = 0; - sptr_t end = 0; - - // the current offset where to search from next time, relative to above range - sptr_t offset = 0; - - // the last result - QPair prevResult; - } m_FindState; - - SaveCallback m_SaveCallback; - CloseCallback m_CloseCallback; - - ShaderDebugTrace *m_Trace = NULL; - int m_CurrentStep; - QList m_Breakpoints; - - static const int CURRENT_MARKER = 0; - static const int BREAKPOINT_MARKER = 2; - static const int FINISHED_MARKER = 4; - - static const int INDICATOR_FINDRESULT = 0; - static const int INDICATOR_REGHIGHLIGHT = 1; - - void addFileList(); - - ScintillaEdit *MakeEditor(const QString &name, const QString &text, int lang); - ScintillaEdit *AddFileScintilla(const QString &name, const QString &text); - - ScintillaEdit *currentScintilla(); - ScintillaEdit *nextScintilla(ScintillaEdit *cur); - - int snippetPos(); - void insertVulkanUBO(); - - int instructionForLine(sptr_t line); - - void updateDebugging(); - - void ensureLineScrolled(ScintillaEdit *s, int i); - - void find(bool down); - - void runTo(int runToInstruction, bool forward, ShaderEvents condition = ShaderEvents::NoEvent); - - QString stringRep(const ShaderVariable &var, bool useType); - RDTreeWidgetItem *makeResourceRegister(const BindpointMap &bind, uint32_t idx, - const BoundResource &ro, const ShaderResource &resources); -}; diff --git a/qrenderdoc/Windows/ShaderViewer.ui b/qrenderdoc/Windows/ShaderViewer.ui deleted file mode 100644 index e3d2ddf04..000000000 --- a/qrenderdoc/Windows/ShaderViewer.ui +++ /dev/null @@ -1,521 +0,0 @@ - - - ShaderViewer - - - - 0 - 0 - 963 - 574 - - - - Form - - - - - 80 - 90 - 351 - 301 - - - - - - - 570 - 160 - 256 - 192 - - - - QFrame::Panel - - - QFrame::Sunken - - - QAbstractItemView::NoEditTriggers - - - false - - - false - - - 0 - - - false - - - false - - - true - - - false - - - - - - 590 - 360 - 256 - 192 - - - - QFrame::Panel - - - QFrame::Sunken - - - QAbstractItemView::NoEditTriggers - - - false - - - false - - - 0 - - - false - - - false - - - true - - - false - - - - - - 20 - 310 - 256 - 192 - - - - Qt::PreventContextMenu - - - 0 - - - false - - - false - - - true - - - - - - 310 - 310 - 256 - 192 - - - - 0 - - - false - - - false - - - true - - - - - - 40 - 10 - 388 - 28 - - - - - 0 - 0 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Find & Replace - - - - - - - :/find.png:/find.png - - - true - - - - - - - Qt::Vertical - - - - - - - Compile & Save changes - - - - - - - :/save.png:/save.png - - - true - - - - - - - Insert built-in snippets - - - - - - - :/plugin_add.png:/plugin_add.png - - - QToolButton::InstantPopup - - - true - - - - - - - Qt::Vertical - - - - - - - Run backwards (Shift-F5) - - - - - - - :/control_start_blue.png:/control_start_blue.png - - - true - - - - - - - Step Back (Shift-F10) - - - - - - - :/control_reverse_blue.png:/control_reverse_blue.png - - - true - - - - - - - Step Next (F10) - - - - - - - :/control_play_blue.png:/control_play_blue.png - - - true - - - - - - - Run forwards (F5) - - - - - - - :/control_end_blue.png:/control_end_blue.png - - - true - - - - - - - Qt::Vertical - - - - - - - - 23 - 22 - - - - Run to Cursor (Ctrl-F10) - - - - :/control_cursor_blue.png:/control_cursor_blue.png - - - true - - - - - - - - 23 - 22 - - - - Run to Sample/Load/Gather - - - - :/control_sample_blue.png:/control_sample_blue.png - - - true - - - - - - - - 23 - 22 - - - - Run to NaN or Inf - - - - :/control_nan_blue.png:/control_nan_blue.png - - - true - - - - - - - Qt::Vertical - - - - - - - int - - - true - - - false - - - true - - - - - - - float - - - true - - - true - - - true - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 710 - 20 - 151 - 131 - - - - QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed|QAbstractItemView::SelectedClicked - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - false - - - false - - - true - - - false - - - - Name - - - - - Type - - - - - Value - - - - - - - RDTreeWidget - QTreeView -
Widgets/Extended/RDTreeWidget.h
-
- - ToolWindowManager - QWidget -
3rdparty/toolwindowmanager/ToolWindowManager.h
-
- - RDTableWidget - QTableWidget -
Widgets/Extended/RDTableWidget.h
-
-
- - - - -
diff --git a/qrenderdoc/Windows/StatisticsViewer.cpp b/qrenderdoc/Windows/StatisticsViewer.cpp deleted file mode 100644 index bb1f67d27..000000000 --- a/qrenderdoc/Windows/StatisticsViewer.cpp +++ /dev/null @@ -1,835 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "StatisticsViewer.h" -#include -#include "ui_StatisticsViewer.h" - -static const int HistogramWidth = 128; -static const QString Stars = QString(HistogramWidth, QLatin1Char('*')); - -QString Pow2IndexAsReadable(int index) -{ - uint64_t value = 1ULL << index; - - if(value >= (1024 * 1024)) - { - float slice = (float)value / (1024 * 1024); - return QFormatStr("%1MB").arg(Formatter::Format(slice)); - } - else if(value >= 1024) - { - float slice = (float)value / 1024; - return QFormatStr("%1KB").arg(Formatter::Format(slice)); - } - else - { - return QFormatStr("%1B").arg(Formatter::Format((float)value)); - } -} - -int SliceForString(const QString &s, uint32_t value, uint32_t maximum) -{ - if(value == 0 || maximum == 0) - return 0; - - float ratio = (float)value / maximum; - int slice = (int)(ratio * s.length()); - return qMax(1, slice); -} - -QString CountOrEmpty(uint32_t count) -{ - if(count == 0) - return QString(); - else - return QFormatStr("(%1)").arg(count); -} - -QString CreateSimpleIntegerHistogram(const QString &legend, const rdctype::array &array) -{ - uint32_t maxCount = 0; - int maxWithValue = 0; - - for(int o = 0; o < array.count; o++) - { - uint32_t value = array[o]; - if(value > 0) - maxWithValue = o; - maxCount = qMax(maxCount, value); - } - - QString text = QFormatStr("\n%1:\n").arg(legend); - - for(int o = 0; o <= maxWithValue; o++) - { - uint32_t count = array[o]; - int slice = SliceForString(Stars, count, maxCount); - text += QFormatStr("%1: %2 %3\n").arg(o, 4).arg(Stars.left(slice)).arg(CountOrEmpty(count)); - } - - return text; -} - -void StatisticsViewer::AppendDrawStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - // #mivance see AppendConstantBindStatistics - const DrawcallStats &draws = frameInfo.stats.draws; - - m_Report.append(tr("\n*** Draw Statistics ***\n\n")); - - m_Report.append(tr("Total calls: %1, instanced: %2, indirect: %3\n") - .arg(draws.calls) - .arg(draws.instanced) - .arg(draws.indirect)); - - if(draws.instanced > 0) - { - m_Report.append(tr("\nInstance counts:\n")); - uint32_t maxCount = 0; - int maxWithValue = 0; - int maximum = draws.counts.count; - for(int s = 1; s < maximum; s++) - { - uint32_t value = draws.counts[s]; - if(value > 0) - maxWithValue = s; - maxCount = qMax(maxCount, value); - } - - for(int s = 1; s <= maxWithValue; s++) - { - uint32_t count = draws.counts[s]; - int slice = SliceForString(Stars, count, maxCount); - m_Report.append(QFormatStr("%1%2: %3 %4\n") - .arg((s == maximum - 1) ? lit(">=") : lit(" ")) - .arg(s, 2) - .arg(Stars.left(slice)) - .arg(CountOrEmpty(count))); - } - } -} - -void StatisticsViewer::AppendDispatchStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - m_Report.append(tr("\n*** Dispatch Statistics ***\n\n")); - m_Report.append(tr("Total calls: %1, indirect: %2\n") - .arg(frameInfo.stats.dispatches.calls) - .arg(frameInfo.stats.dispatches.indirect)); -} - -void StatisticsViewer::AppendInputAssemblerStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - const IndexBindStats &indices = frameInfo.stats.indices; - const LayoutBindStats &layouts = frameInfo.stats.layouts; - - const VertexBindStats &vertices = frameInfo.stats.vertices; - - m_Report.append(tr("\n*** Input Assembler Statistics ***\n\n")); - - m_Report.append(tr("Total index calls: %1, non-null index sets: %2, null index sets: %3\n") - .arg(indices.calls) - .arg(indices.sets) - .arg(indices.nulls)); - m_Report.append(tr("Total layout calls: %1, non-null layout sets: %2, null layout sets: %3\n") - .arg(layouts.calls) - .arg(layouts.sets) - .arg(layouts.nulls)); - m_Report.append(tr("Total vertex calls: %1, non-null vertex sets: %2, null vertex sets: %3\n") - .arg(vertices.calls) - .arg(vertices.sets) - .arg(vertices.nulls)); - - m_Report.append(CreateSimpleIntegerHistogram(tr("Aggregate vertex slot counts per invocation"), - vertices.bindslots)); -} - -void StatisticsViewer::AppendShaderStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - const ShaderChangeStats *shaders = frameInfo.stats.shaders; - ShaderChangeStats totalShadersPerStage; - memset(&totalShadersPerStage, 0, sizeof(totalShadersPerStage)); - for(auto s : indices()) - { - totalShadersPerStage.calls += shaders[s].calls; - totalShadersPerStage.sets += shaders[s].sets; - totalShadersPerStage.nulls += shaders[s].nulls; - totalShadersPerStage.redundants += shaders[s].redundants; - } - - m_Report.append(tr("\n*** Shader Set Statistics ***\n\n")); - - for(auto s : indices()) - { - m_Report.append(tr("%1 calls: %2, non-null shader sets: %3, null shader sets: %4, " - "redundant shader sets: %5\n") - .arg(m_Ctx.CurPipelineState().Abbrev(StageFromIndex(s))) - .arg(shaders[s].calls) - .arg(shaders[s].sets) - .arg(shaders[s].nulls) - .arg(shaders[s].redundants)); - } - - m_Report.append(tr("Total calls: %1, non-null shader sets: %2, null shader sets: %3, " - "reundant shader sets: %4\n") - .arg(totalShadersPerStage.calls) - .arg(totalShadersPerStage.sets) - .arg(totalShadersPerStage.nulls) - .arg(totalShadersPerStage.redundants)); -} - -void StatisticsViewer::AppendConstantBindStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - // #mivance C++-side we guarantee all stages will have the same slots - // and sizes count, so pattern off of the first frame's first stage - const ConstantBindStats &reference = frameInfo.stats.constants[0]; - - // #mivance there is probably a way to iterate the fields via - // GetType()/GetField() and build a sort of dynamic min/max/average - // structure for a given type with known integral types (or arrays - // thereof), but given we're heading for a Qt/C++ rewrite of the UI - // perhaps best not to dwell too long on that - ConstantBindStats totalConstantsPerStage[ENUM_ARRAY_SIZE(ShaderStage)]; - memset(&totalConstantsPerStage, 0, sizeof(totalConstantsPerStage)); - for(auto s : indices()) - { - totalConstantsPerStage[s].bindslots.create(reference.bindslots.count); - totalConstantsPerStage[s].sizes.create(reference.sizes.count); - } - - { - const ConstantBindStats *constants = frameInfo.stats.constants; - for(auto s : indices()) - { - totalConstantsPerStage[s].calls += constants[s].calls; - totalConstantsPerStage[s].sets += constants[s].sets; - totalConstantsPerStage[s].nulls += constants[s].nulls; - - for(int l = 0; l < constants[s].bindslots.count; l++) - totalConstantsPerStage[s].bindslots[l] += constants[s].bindslots[l]; - - for(int z = 0; z < constants[s].sizes.count; z++) - totalConstantsPerStage[s].sizes[z] += constants[s].sizes[z]; - } - } - - ConstantBindStats totalConstantsForAllStages; - memset(&totalConstantsForAllStages, 0, sizeof(totalConstantsForAllStages)); - totalConstantsForAllStages.bindslots.create(totalConstantsPerStage[0].bindslots.count); - totalConstantsForAllStages.sizes.create(totalConstantsPerStage[0].sizes.count); - - for(auto s : indices()) - { - const ConstantBindStats &perStage = totalConstantsPerStage[s]; - totalConstantsForAllStages.calls += perStage.calls; - totalConstantsForAllStages.sets += perStage.sets; - totalConstantsForAllStages.nulls += perStage.nulls; - - for(int l = 0; l < perStage.bindslots.count; l++) - totalConstantsForAllStages.bindslots[l] += perStage.bindslots[l]; - - for(int z = 0; z < perStage.sizes.count; z++) - totalConstantsForAllStages.sizes[z] += perStage.sizes[z]; - } - - m_Report.append(tr("\n*** Constant Bind Statistics ***\n\n")); - - for(auto s : indices()) - { - m_Report.append(tr("%1 calls: %2, non-null buffer sets: %3, null buffer sets: %4\n") - .arg(m_Ctx.CurPipelineState().Abbrev(StageFromIndex(s))) - .arg(totalConstantsPerStage[s].calls) - .arg(totalConstantsPerStage[s].sets) - .arg(totalConstantsPerStage[s].nulls)); - } - - m_Report.append(tr("Total calls: %1, non-null buffer sets: %2, null buffer sets: %3\n") - .arg(totalConstantsForAllStages.calls) - .arg(totalConstantsForAllStages.sets) - .arg(totalConstantsForAllStages.nulls)); - - m_Report.append( - CreateSimpleIntegerHistogram(tr("Aggregate slot counts per invocation across all stages"), - totalConstantsForAllStages.bindslots)); - - m_Report.append(tr("\nAggregate constant buffer sizes across all stages:\n")); - uint32_t maxCount = 0; - int maxWithValue = 0; - for(int s = 0; s < totalConstantsForAllStages.sizes.count; s++) - { - uint32_t value = totalConstantsForAllStages.sizes[s]; - if(value > 0) - maxWithValue = s; - maxCount = qMax(maxCount, value); - } - - for(int s = 0; s <= maxWithValue; s++) - { - uint32_t count = totalConstantsForAllStages.sizes[s]; - int slice = SliceForString(Stars, count, maxCount); - m_Report.append(QFormatStr("%1: %2 %3\n") - .arg(Pow2IndexAsReadable(s), 8) - .arg(Stars.left(slice)) - .arg(CountOrEmpty(count))); - } -} - -void StatisticsViewer::AppendSamplerBindStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - // #mivance see AppendConstantBindStatistics - const SamplerBindStats &reference = frameInfo.stats.samplers[0]; - - SamplerBindStats totalSamplersPerStage[ENUM_ARRAY_SIZE(ShaderStage)]; - memset(&totalSamplersPerStage, 0, sizeof(totalSamplersPerStage)); - for(auto s : indices()) - { - totalSamplersPerStage[s].bindslots.create(reference.bindslots.count); - } - - { - const SamplerBindStats *samplers = frameInfo.stats.samplers; - for(auto s : indices()) - { - totalSamplersPerStage[s].calls += samplers[s].calls; - totalSamplersPerStage[s].sets += samplers[s].sets; - totalSamplersPerStage[s].nulls += samplers[s].nulls; - - for(int l = 0; l < samplers[s].bindslots.count; l++) - { - totalSamplersPerStage[s].bindslots[l] += samplers[s].bindslots[l]; - } - } - } - - SamplerBindStats totalSamplersForAllStages; - memset(&totalSamplersForAllStages, 0, sizeof(totalSamplersForAllStages)); - totalSamplersForAllStages.bindslots.create(totalSamplersPerStage[0].bindslots.count); - - for(auto s : indices()) - { - SamplerBindStats perStage = totalSamplersPerStage[s]; - totalSamplersForAllStages.calls += perStage.calls; - totalSamplersForAllStages.sets += perStage.sets; - totalSamplersForAllStages.nulls += perStage.nulls; - for(int l = 0; l < perStage.bindslots.count; l++) - { - totalSamplersForAllStages.bindslots[l] += perStage.bindslots[l]; - } - } - - m_Report.append(tr("\n*** Sampler Bind Statistics ***\n\n")); - - for(auto s : indices()) - { - m_Report.append(tr("%1 calls: %2, non-null sampler sets: %3, null sampler sets: %4\n") - .arg(m_Ctx.CurPipelineState().Abbrev(StageFromIndex(s))) - .arg(totalSamplersPerStage[s].calls) - .arg(totalSamplersPerStage[s].sets) - .arg(totalSamplersPerStage[s].nulls)); - } - - m_Report.append(tr("Total calls: %1, non-null sampler sets: %2, null sampler sets: %3\n") - .arg(totalSamplersForAllStages.calls) - .arg(totalSamplersForAllStages.sets) - .arg(totalSamplersForAllStages.nulls)); - - m_Report.append( - CreateSimpleIntegerHistogram(tr("Aggregate slot counts per invocation across all stages"), - totalSamplersForAllStages.bindslots)); -} - -void StatisticsViewer::AppendResourceBindStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - // #mivance see AppendConstantBindStatistics - const ResourceBindStats &reference = frameInfo.stats.resources[0]; - - ResourceBindStats totalResourcesPerStage[ENUM_ARRAY_SIZE(ShaderStage)]; - memset(&totalResourcesPerStage, 0, sizeof(totalResourcesPerStage)); - for(auto s : indices()) - { - totalResourcesPerStage[s].types.create(reference.types.count); - totalResourcesPerStage[s].bindslots.create(reference.bindslots.count); - } - - { - const ResourceBindStats *resources = frameInfo.stats.resources; - for(auto s : indices()) - { - totalResourcesPerStage[s].calls += resources[s].calls; - totalResourcesPerStage[s].sets += resources[s].sets; - totalResourcesPerStage[s].nulls += resources[s].nulls; - - for(int z = 0; z < resources[s].types.count; z++) - { - totalResourcesPerStage[s].types[z] += resources[s].types[z]; - } - - for(int l = 0; l < resources[s].bindslots.count; l++) - { - totalResourcesPerStage[s].bindslots[l] += resources[s].bindslots[l]; - } - } - } - - ResourceBindStats totalResourcesForAllStages; - memset(&totalResourcesForAllStages, 0, sizeof(totalResourcesForAllStages)); - totalResourcesForAllStages.types.create(totalResourcesPerStage[0].types.count); - totalResourcesForAllStages.bindslots.create(totalResourcesPerStage[0].bindslots.count); - - for(auto s : indices()) - { - ResourceBindStats perStage = totalResourcesPerStage[s]; - totalResourcesForAllStages.calls += perStage.calls; - totalResourcesForAllStages.sets += perStage.sets; - totalResourcesForAllStages.nulls += perStage.nulls; - for(int t = 0; t < perStage.types.count; t++) - { - totalResourcesForAllStages.types[t] += perStage.types[t]; - } - for(int l = 0; l < perStage.bindslots.count; l++) - { - totalResourcesForAllStages.bindslots[l] += perStage.bindslots[l]; - } - } - - m_Report.append(tr("\n*** Resource Bind Statistics ***\n\n")); - - for(auto s : indices()) - { - m_Report.append(tr("%1 calls: %2 non-null resource sets: %3 null resource sets: %4\n") - .arg(m_Ctx.CurPipelineState().Abbrev(StageFromIndex(s))) - .arg(totalResourcesPerStage[s].calls) - .arg(totalResourcesPerStage[s].sets) - .arg(totalResourcesPerStage[s].nulls)); - } - - m_Report.append(tr("Total calls: %1 non-null resource sets: %2 null resource sets: %3\n") - .arg(totalResourcesForAllStages.calls) - .arg(totalResourcesForAllStages.sets) - .arg(totalResourcesForAllStages.nulls)); - - uint32_t maxCount = 0; - int maxWithCount = 0; - - m_Report.append(tr("\nResource types across all stages:\n")); - for(int s = 0; s < totalResourcesForAllStages.types.count; s++) - { - uint32_t count = totalResourcesForAllStages.types[s]; - if(count > 0) - maxWithCount = s; - maxCount = qMax(maxCount, count); - } - - for(int s = 0; s <= maxWithCount; s++) - { - uint32_t count = totalResourcesForAllStages.types[s]; - int slice = SliceForString(Stars, count, maxCount); - TextureDim type = (TextureDim)s; - m_Report.append( - QFormatStr("%1: %2 %3\n").arg(ToQStr(type), 20).arg(Stars.left(slice)).arg(CountOrEmpty(count))); - } - - m_Report.append( - CreateSimpleIntegerHistogram(tr("Aggregate slot counts per invocation across all stages"), - totalResourcesForAllStages.bindslots)); -} - -void StatisticsViewer::AppendUpdateStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - // #mivance see AppendConstantBindStatistics - const ResourceUpdateStats &reference = frameInfo.stats.updates; - - ResourceUpdateStats totalUpdates; - memset(&totalUpdates, 0, sizeof(totalUpdates)); - totalUpdates.types.create(reference.types.count); - totalUpdates.sizes.create(reference.sizes.count); - - { - ResourceUpdateStats updates = frameInfo.stats.updates; - - totalUpdates.calls += updates.calls; - totalUpdates.clients += updates.clients; - totalUpdates.servers += updates.servers; - - for(int t = 0; t < updates.types.count; t++) - totalUpdates.types[t] += updates.types[t]; - - for(int t = 0; t < updates.sizes.count; t++) - totalUpdates.sizes[t] += updates.sizes[t]; - } - - m_Report.append(tr("\n*** Resource Update Statistics ***\n\n")); - - m_Report.append(tr("Total calls: %1, client-updated memory: %2, server-updated memory: %3\n") - .arg(totalUpdates.calls) - .arg(totalUpdates.clients) - .arg(totalUpdates.servers)); - - m_Report.append(tr("\nUpdated resource types:\n")); - uint32_t maxCount = 0; - int maxWithValue = 0; - for(int s = 1; s < totalUpdates.types.count; s++) - { - uint32_t value = totalUpdates.types[s]; - if(value > 0) - maxWithValue = s; - maxCount = qMax(maxCount, value); - } - - for(int s = 1; s <= maxWithValue; s++) - { - uint32_t count = totalUpdates.types[s]; - int slice = SliceForString(Stars, count, maxCount); - TextureDim type = (TextureDim)s; - m_Report.append( - QFormatStr("%1: %2 %3\n").arg(ToQStr(type), 20).arg(Stars.left(slice)).arg(CountOrEmpty(count))); - } - - m_Report.append(tr("\nUpdated resource sizes:\n")); - maxCount = 0; - maxWithValue = 0; - for(int s = 0; s < totalUpdates.sizes.count; s++) - { - uint32_t value = totalUpdates.sizes[s]; - if(value > 0) - maxWithValue = s; - maxCount = qMax(maxCount, value); - } - - for(int s = 0; s <= maxWithValue; s++) - { - uint32_t count = totalUpdates.sizes[s]; - int slice = SliceForString(Stars, count, maxCount); - m_Report.append(QFormatStr("%1: %2 %3\n") - .arg(Pow2IndexAsReadable(s), 8) - .arg(Stars.left(slice)) - .arg(CountOrEmpty(count))); - } -} - -void StatisticsViewer::AppendBlendStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - BlendStats blends = frameInfo.stats.blends; - m_Report.append(tr("\n*** Blend Statistics ***\n")); - m_Report.append( - tr("Blend calls: %1 non-null sets: %2, null (default) sets: %3, redundant sets: %4\n") - .arg(blends.calls) - .arg(blends.sets) - .arg(blends.nulls) - .arg(blends.redundants)); -} - -void StatisticsViewer::AppendDepthStencilStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - DepthStencilStats depths = frameInfo.stats.depths; - m_Report.append(tr("\n*** Depth Stencil Statistics ***\n")); - m_Report.append(tr("Depth/stencil calls: %1 non-null sets: %2, null (default) sets: " - "%3, redundant sets: %4\n") - .arg(depths.calls) - .arg(depths.sets) - .arg(depths.nulls) - .arg(depths.redundants)); -} - -void StatisticsViewer::AppendRasterizationStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - RasterizationStats rasters = frameInfo.stats.rasters; - m_Report.append(tr("\n*** Rasterization Statistics ***\n")); - m_Report.append(tr("Rasterization calls: %1 non-null sets: %2, null (default) sets: " - "%3, redundant sets: %4\n") - .arg(rasters.calls) - .arg(rasters.sets) - .arg(rasters.nulls) - .arg(rasters.redundants)); - m_Report.append(CreateSimpleIntegerHistogram(tr("Viewports set"), rasters.viewports)); - m_Report.append(CreateSimpleIntegerHistogram(tr("Scissors set"), rasters.rects)); -} - -void StatisticsViewer::AppendOutputStatistics() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - OutputTargetStats outputs = frameInfo.stats.outputs; - m_Report.append(tr("\n*** Output Statistics ***\n")); - m_Report.append(tr("Output calls: %1 non-null sets: %2, null sets: %3\n") - .arg(outputs.calls) - .arg(outputs.sets) - .arg(outputs.nulls)); - m_Report.append(CreateSimpleIntegerHistogram(tr("Outputs set"), outputs.bindslots)); -} - -void StatisticsViewer::AppendDetailedInformation() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - if(!frameInfo.stats.recorded) - return; - - AppendDrawStatistics(); - AppendDispatchStatistics(); - AppendInputAssemblerStatistics(); - AppendShaderStatistics(); - AppendConstantBindStatistics(); - AppendSamplerBindStatistics(); - AppendResourceBindStatistics(); - AppendBlendStatistics(); - AppendDepthStencilStatistics(); - AppendRasterizationStatistics(); - AppendUpdateStatistics(); - AppendOutputStatistics(); -} - -void StatisticsViewer::CountContributingEvents(const DrawcallDescription &draw, uint32_t &drawCount, - uint32_t &dispatchCount, uint32_t &diagnosticCount) -{ - const DrawFlags diagnosticMask = - DrawFlags::SetMarker | DrawFlags::PushMarker | DrawFlags::PopMarker; - DrawFlags diagnosticMasked = draw.flags & diagnosticMask; - - if(diagnosticMasked != DrawFlags::NoFlags) - diagnosticCount += 1; - - if(draw.flags & DrawFlags::Drawcall) - drawCount += 1; - - if(draw.flags & DrawFlags::Dispatch) - dispatchCount += 1; - - for(const DrawcallDescription &c : draw.children) - CountContributingEvents(c, drawCount, dispatchCount, diagnosticCount); -} - -void StatisticsViewer::AppendAPICallSummary() -{ - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - if(!frameInfo.stats.recorded) - return; - - uint32_t numConstantSets = 0; - uint32_t numSamplerSets = 0; - uint32_t numResourceSets = 0; - uint32_t numShaderSets = 0; - - for(auto s : indices()) - { - numConstantSets += frameInfo.stats.constants[s].calls; - numSamplerSets += frameInfo.stats.samplers[s].calls; - numResourceSets += frameInfo.stats.resources[s].calls; - numShaderSets += frameInfo.stats.shaders[s].calls; - } - - uint32_t numResourceUpdates = frameInfo.stats.updates.calls; - uint32_t numIndexVertexSets = (frameInfo.stats.indices.calls + frameInfo.stats.vertices.calls + - frameInfo.stats.layouts.calls); - uint32_t numBlendSets = frameInfo.stats.blends.calls; - uint32_t numDepthStencilSets = frameInfo.stats.depths.calls; - uint32_t numRasterizationSets = frameInfo.stats.rasters.calls; - uint32_t numOutputSets = frameInfo.stats.outputs.calls; - - m_Report += tr("\tIndex/vertex bind calls: %1\n").arg(numIndexVertexSets); - m_Report += tr("\tConstant bind calls: %1\n").arg(numConstantSets); - m_Report += tr("\tSampler bind calls: %1\n").arg(numSamplerSets); - m_Report += tr("\tResource bind calls: %1\n").arg(numResourceSets); - m_Report += tr("\tShader set calls: %1\n").arg(numShaderSets); - m_Report += tr("\tBlend set calls: %1\n").arg(numBlendSets); - m_Report += tr("\tDepth/stencil set calls: %1\n").arg(numDepthStencilSets); - m_Report += tr("\tRasterization set calls: %1\n").arg(numRasterizationSets); - m_Report += tr("\tResource update calls: %1\n").arg(numResourceUpdates); - m_Report += tr("\tOutput set calls: %1\n").arg(numOutputSets); -} - -void StatisticsViewer::GenerateReport() -{ - const rdctype::array &curDraws = m_Ctx.CurDrawcalls(); - - uint32_t drawCount = 0; - uint32_t dispatchCount = 0; - uint32_t diagnosticCount = 0; - for(const DrawcallDescription &d : curDraws) - CountContributingEvents(d, drawCount, dispatchCount, diagnosticCount); - - uint32_t numAPIcalls = - m_Ctx.GetLastDrawcall()->eventID - (drawCount + dispatchCount + diagnosticCount); - - int numTextures = m_Ctx.GetTextures().count; - int numBuffers = m_Ctx.GetBuffers().count; - - uint64_t IBBytes = 0; - uint64_t VBBytes = 0; - uint64_t BufBytes = 0; - for(const BufferDescription &b : m_Ctx.GetBuffers()) - { - BufBytes += b.length; - - if(b.creationFlags & BufferCategory::Index) - IBBytes += b.length; - if(b.creationFlags & BufferCategory::Vertex) - VBBytes += b.length; - } - - uint64_t RTBytes = 0; - uint64_t TexBytes = 0; - uint64_t LargeTexBytes = 0; - - int numRTs = 0; - float texW = 0, texH = 0; - float largeTexW = 0, largeTexH = 0; - int texCount = 0, largeTexCount = 0; - for(const TextureDescription &t : m_Ctx.GetTextures()) - { - if(t.creationFlags & (TextureCategory::ColorTarget | TextureCategory::DepthTarget)) - { - numRTs++; - - RTBytes += t.byteSize; - } - else - { - texW += (float)t.width; - texH += (float)t.height; - texCount++; - - TexBytes += t.byteSize; - - if(t.width > 32 && t.height > 32) - { - largeTexW += (float)t.width; - largeTexH += (float)t.height; - largeTexCount++; - - LargeTexBytes += t.byteSize; - } - } - } - - texW /= texCount; - texH /= texCount; - - largeTexW /= largeTexCount; - largeTexH /= largeTexCount; - - const FrameDescription &frameInfo = m_Ctx.FrameInfo(); - - float compressedMB = (float)frameInfo.compressedFileSize / (1024.0f * 1024.0f); - float uncompressedMB = (float)frameInfo.uncompressedFileSize / (1024.0f * 1024.0f); - float compressRatio = uncompressedMB / compressedMB; - float persistentMB = (float)frameInfo.persistentSize / (1024.0f * 1024.0f); - float initDataMB = (float)frameInfo.initDataSize / (1024.0f * 1024.0f); - - QString header = - tr("Stats for %1.\n\nFile size: %2MB (%3MB uncompressed, compression ratio %4:1)\n" - "Persistent Data (approx): %5MB, Frame-initial data (approx): %6MB\n") - .arg(QFileInfo(m_Ctx.LogFilename()).fileName()) - .arg(compressedMB, 2, 'f', 2) - .arg(uncompressedMB, 2, 'f', 2) - .arg(compressRatio, 2, 'f', 2) - .arg(persistentMB, 2, 'f', 2) - .arg(initDataMB, 2, 'f', 2); - QString drawList = tr("Draw calls: %1\nDispatch calls: %2\n").arg(drawCount).arg(dispatchCount); - QString ratio = tr("API:Draw/Dispatch call ratio: %1\n\n") - .arg((float)numAPIcalls / (float)(drawCount + dispatchCount)); - QString textures = tr("%1 Textures - %2 MB (%3 MB over 32x32), %4 RTs - %5 MB.\n" - "Avg. tex dimension: %6x%7 (%8x%9 over 32x32)\n") - .arg(numTextures) - .arg((float)TexBytes / (1024.0f * 1024.0f), 2, 'f', 2) - .arg((float)LargeTexBytes / (1024.0f * 1024.0f), 2, 'f', 2) - .arg(numRTs) - .arg((float)RTBytes / (1024.0f * 1024.0f), 2, 'f', 2) - .arg(texW) - .arg(texH) - .arg(largeTexW) - .arg(largeTexH); - QString buffers = tr("%1 Buffers - %2 MB total %3 MB IBs %4 MB VBs.\n") - .arg(numBuffers) - .arg((float)BufBytes / (1024.0f * 1024.0f), 2, 'f', 2) - .arg((float)IBBytes / (1024.0f * 1024.0f), 2, 'f', 2) - .arg((float)VBBytes / (1024.0f * 1024.0f), 2, 'f', 2); - QString load = tr("%1 MB - Grand total GPU buffer + texture load.\n") - .arg((float)(TexBytes + BufBytes + RTBytes) / (1024.0f * 1024.0f), 2, 'f', 2); - - m_Report = header; - - m_Report.append(tr("\n*** Summary ***\n\n")); - m_Report.append(drawList); - m_Report += tr("API calls: %1\n").arg(numAPIcalls); - AppendAPICallSummary(); - m_Report.append(ratio); - m_Report.append(textures); - m_Report.append(buffers); - m_Report.append(load); - - AppendDetailedInformation(); -} - -StatisticsViewer::StatisticsViewer(ICaptureContext &ctx, QWidget *parent) - : QFrame(parent), ui(new Ui::StatisticsViewer), m_Ctx(ctx) -{ - ui->setupUi(this); - - ui->statistics->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - - m_Ctx.AddLogViewer(this); -} - -StatisticsViewer::~StatisticsViewer() -{ - m_Ctx.BuiltinWindowClosed(this); - - m_Ctx.RemoveLogViewer(this); - delete ui; -} - -void StatisticsViewer::OnLogfileClosed() -{ - ui->statistics->clear(); -} - -void StatisticsViewer::OnLogfileLoaded() -{ - GenerateReport(); - ui->statistics->setText(m_Report); -} \ No newline at end of file diff --git a/qrenderdoc/Windows/StatisticsViewer.h b/qrenderdoc/Windows/StatisticsViewer.h deleted file mode 100644 index f77605bda..000000000 --- a/qrenderdoc/Windows/StatisticsViewer.h +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -namespace Ui -{ -class StatisticsViewer; -} - -class StatisticsViewer : public QFrame, public IStatisticsViewer, public ILogViewer -{ - Q_OBJECT - -public: - explicit StatisticsViewer(ICaptureContext &ctx, QWidget *parent = 0); - ~StatisticsViewer(); - - // IStatisticsViewer - QWidget *Widget() override { return this; } - // ILogViewerForm - void OnLogfileLoaded() override; - void OnLogfileClosed() override; - void OnSelectedEventChanged(uint32_t eventID) override {} - void OnEventChanged(uint32_t eventID) override {} -private: - Ui::StatisticsViewer *ui; - ICaptureContext &m_Ctx; - - QString m_Report; - - void AppendDrawStatistics(); - void AppendDispatchStatistics(); - void AppendInputAssemblerStatistics(); - void AppendShaderStatistics(); - void AppendConstantBindStatistics(); - void AppendSamplerBindStatistics(); - void AppendResourceBindStatistics(); - void AppendUpdateStatistics(); - void AppendBlendStatistics(); - void AppendDepthStencilStatistics(); - void AppendRasterizationStatistics(); - void AppendOutputStatistics(); - void AppendDetailedInformation(); - void CountContributingEvents(const DrawcallDescription &draw, uint32_t &drawCount, - uint32_t &dispatchCount, uint32_t &diagnosticCount); - void AppendAPICallSummary(); - void GenerateReport(); -}; diff --git a/qrenderdoc/Windows/StatisticsViewer.ui b/qrenderdoc/Windows/StatisticsViewer.ui deleted file mode 100644 index 70763f300..000000000 --- a/qrenderdoc/Windows/StatisticsViewer.ui +++ /dev/null @@ -1,43 +0,0 @@ - - - StatisticsViewer - - - - 0 - 0 - 400 - 300 - - - - Statistics - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - IBeamCursor - - - true - - - - - - - - diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp deleted file mode 100644 index d40cac9d7..000000000 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ /dev/null @@ -1,3816 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "TextureViewer.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "3rdparty/flowlayout/FlowLayout.h" -#include "3rdparty/toolwindowmanager/ToolWindowManagerArea.h" -#include "Code/CaptureContext.h" -#include "Code/QRDUtils.h" -#include "Code/Resources.h" -#include "Dialogs/TextureSaveDialog.h" -#include "Widgets/ResourcePreview.h" -#include "Widgets/TextureGoto.h" -#include "ui_TextureViewer.h" - -float area(const QSizeF &s) -{ - return s.width() * s.height(); -} - -float aspect(const QSizeF &s) -{ - return s.width() / s.height(); -} - -Q_DECLARE_METATYPE(Following); -Q_DECLARE_METATYPE(ResourceId); - -const Following Following::Default = Following(); - -Following::Following(FollowType t, ShaderStage s, int i, int a) -{ - Type = t; - Stage = s; - index = i; - arrayEl = a; -} - -Following::Following() -{ - Type = FollowType::OutputColour; - Stage = ShaderStage::Pixel; - index = 0; - arrayEl = 0; -} - -bool Following::operator!=(const Following &o) -{ - return !(*this == o); -} - -bool Following::operator==(const Following &o) -{ - return Type == o.Type && Stage == o.Stage && index == o.index; -} - -void Following::GetDrawContext(ICaptureContext &ctx, bool ©, bool &clear, bool &compute) -{ - const DrawcallDescription *curDraw = ctx.CurDrawcall(); - copy = curDraw != NULL && (curDraw->flags & (DrawFlags::Copy | DrawFlags::Resolve)); - clear = curDraw != NULL && (curDraw->flags & DrawFlags::Clear); - compute = curDraw != NULL && (curDraw->flags & DrawFlags::Dispatch) && - ctx.CurPipelineState().GetShader(ShaderStage::Compute) != ResourceId(); -} - -int Following::GetHighestMip(ICaptureContext &ctx) -{ - return GetBoundResource(ctx, arrayEl).HighestMip; -} - -int Following::GetFirstArraySlice(ICaptureContext &ctx) -{ - return GetBoundResource(ctx, arrayEl).FirstSlice; -} - -CompType Following::GetTypeHint(ICaptureContext &ctx) -{ - return GetBoundResource(ctx, arrayEl).typeHint; -} - -ResourceId Following::GetResourceId(ICaptureContext &ctx) -{ - return GetBoundResource(ctx, arrayEl).Id; -} - -BoundResource Following::GetBoundResource(ICaptureContext &ctx, int arrayIdx) -{ - BoundResource ret; - - if(Type == FollowType::OutputColour) - { - auto outputs = GetOutputTargets(ctx); - - if(index < outputs.size()) - ret = outputs[index]; - } - else if(Type == FollowType::OutputDepth) - { - ret = GetDepthTarget(ctx); - } - else if(Type == FollowType::ReadWrite) - { - auto rw = GetReadWriteResources(ctx); - - ShaderBindpointMapping mapping = GetMapping(ctx); - - if(index < mapping.ReadWriteResources.count) - { - BindpointMap &key = mapping.ReadWriteResources[index]; - - if(rw.contains(key)) - ret = rw[key][arrayIdx]; - } - } - else if(Type == FollowType::ReadOnly) - { - auto ro = GetReadOnlyResources(ctx); - - ShaderBindpointMapping mapping = GetMapping(ctx); - - if(index < mapping.ReadOnlyResources.count) - { - BindpointMap &key = mapping.ReadOnlyResources[index]; - - if(ro.contains(key)) - ret = ro[key][arrayIdx]; - } - } - - return ret; -} - -QVector Following::GetOutputTargets(ICaptureContext &ctx) -{ - const DrawcallDescription *curDraw = ctx.CurDrawcall(); - bool copy = false, clear = false, compute = false; - GetDrawContext(ctx, copy, clear, compute); - - if(copy || clear) - { - return {BoundResource(curDraw->copyDestination)}; - } - else if(compute) - { - return {}; - } - else - { - QVector ret = ctx.CurPipelineState().GetOutputTargets(); - - if(ret.isEmpty() && curDraw != NULL && (curDraw->flags & DrawFlags::Present)) - { - if(curDraw->copyDestination != ResourceId()) - return {BoundResource(curDraw->copyDestination)}; - - for(const TextureDescription &tex : ctx.GetTextures()) - { - if(tex.creationFlags & TextureCategory::SwapBuffer) - return {BoundResource(tex.ID)}; - } - } - - return ret; - } -} - -BoundResource Following::GetDepthTarget(ICaptureContext &ctx) -{ - bool copy = false, clear = false, compute = false; - GetDrawContext(ctx, copy, clear, compute); - - if(copy || clear || compute) - return BoundResource(ResourceId()); - else - return ctx.CurPipelineState().GetDepthTarget(); -} - -QMap> Following::GetReadWriteResources(ICaptureContext &ctx, - ShaderStage stage) -{ - bool copy = false, clear = false, compute = false; - GetDrawContext(ctx, copy, clear, compute); - - if(copy || clear) - { - return QMap>(); - } - else if(compute) - { - // only return compute resources for one stage - if(stage == ShaderStage::Pixel || stage == ShaderStage::Compute) - return ctx.CurPipelineState().GetReadWriteResources(ShaderStage::Compute); - else - return QMap>(); - } - else - { - return ctx.CurPipelineState().GetReadWriteResources(stage); - } -} - -QMap> Following::GetReadWriteResources(ICaptureContext &ctx) -{ - return GetReadWriteResources(ctx, Stage); -} - -QMap> Following::GetReadOnlyResources(ICaptureContext &ctx, - ShaderStage stage) -{ - const DrawcallDescription *curDraw = ctx.CurDrawcall(); - bool copy = false, clear = false, compute = false; - GetDrawContext(ctx, copy, clear, compute); - - if(copy || clear) - { - QMap> ret; - - // only return copy source for one stage - if(copy && stage == ShaderStage::Pixel) - ret[BindpointMap(0, 0)] = {BoundResource(curDraw->copySource)}; - - return ret; - } - else if(compute) - { - // only return compute resources for one stage - if(stage == ShaderStage::Pixel || stage == ShaderStage::Compute) - return ctx.CurPipelineState().GetReadOnlyResources(ShaderStage::Compute); - else - return QMap>(); - } - else - { - return ctx.CurPipelineState().GetReadOnlyResources(stage); - } -} - -QMap> Following::GetReadOnlyResources(ICaptureContext &ctx) -{ - return GetReadOnlyResources(ctx, Stage); -} - -const ShaderReflection *Following::GetReflection(ICaptureContext &ctx, ShaderStage stage) -{ - bool copy = false, clear = false, compute = false; - GetDrawContext(ctx, copy, clear, compute); - - if(copy || clear) - return NULL; - else if(compute) - return ctx.CurPipelineState().GetShaderReflection(ShaderStage::Compute); - else - return ctx.CurPipelineState().GetShaderReflection(stage); -} - -const ShaderReflection *Following::GetReflection(ICaptureContext &ctx) -{ - return GetReflection(ctx, Stage); -} - -const ShaderBindpointMapping &Following::GetMapping(ICaptureContext &ctx, ShaderStage stage) -{ - bool copy = false, clear = false, compute = false; - GetDrawContext(ctx, copy, clear, compute); - - if(copy || clear) - { - static ShaderBindpointMapping mapping; - - // for PS only add a single mapping to get the copy source - if(copy && stage == ShaderStage::Pixel) - mapping.ReadOnlyResources = {BindpointMap(0, 0)}; - else - mapping.ReadOnlyResources.clear(); - - return mapping; - } - else if(compute) - { - return ctx.CurPipelineState().GetBindpointMapping(ShaderStage::Compute); - } - else - { - return ctx.CurPipelineState().GetBindpointMapping(stage); - } -} - -const ShaderBindpointMapping &Following::GetMapping(ICaptureContext &ctx) -{ - return GetMapping(ctx, Stage); -} - -class TextureListItemModel : public QAbstractItemModel -{ -public: - enum FilterType - { - Textures, - RenderTargets, - String - }; - - TextureListItemModel(QWidget *parent) : QAbstractItemModel(parent) - { - goArrow.addPixmap(Pixmaps::action(parent), QIcon::Normal, QIcon::Off); - goArrow.addPixmap(Pixmaps::action_hover(parent), QIcon::Normal, QIcon::Off); - } - void reset(FilterType type, const QString &filter, ICaptureContext &ctx) - { - const rdctype::array src = ctx.GetTextures(); - - texs.clear(); - texs.reserve(src.count); - - emit beginResetModel(); - - TextureCategory rtFlags = TextureCategory::ColorTarget | TextureCategory::DepthTarget; - - for(const TextureDescription &t : src) - { - if(type == Textures) - { - if(!(t.creationFlags & rtFlags)) - texs.push_back(t); - } - else if(type == RenderTargets) - { - if((t.creationFlags & rtFlags)) - texs.push_back(t); - } - else - { - if(filter.isEmpty()) - texs.push_back(t); - else if(ToQStr(t.name).contains(filter, Qt::CaseInsensitive)) - texs.push_back(t); - } - } - - emit endResetModel(); - } - - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override - { - if(row < 0 || row >= rowCount()) - return QModelIndex(); - - return createIndex(row, 0); - } - - QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); } - int rowCount(const QModelIndex &parent = QModelIndex()) const override { return texs.count(); } - int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 1; } - Qt::ItemFlags flags(const QModelIndex &index) const override - { - if(!index.isValid()) - return 0; - - return QAbstractItemModel::flags(index); - } - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override - { - if(index.isValid()) - { - if(role == Qt::DisplayRole) - { - if(index.row() >= 0 && index.row() < texs.count()) - return ToQStr(texs[index.row()].name); - } - - if(role == Qt::UserRole) - { - return QVariant::fromValue(texs[index.row()].ID); - } - - if(role == Qt::DecorationRole) - { - return QVariant(goArrow); - } - } - - return QVariant(); - } - -private: - QVector texs; - QIcon goArrow; -}; - -class TextureListItemDelegate : public QItemDelegate -{ -public: - TextureListItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {} - void paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const override - { - if(index.isValid()) - { - QStyleOptionViewItem option = opt; - option.decorationAlignment = Qt::AlignBaseline | Qt::AlignRight; - painter->eraseRect(option.rect); - - QIcon icon = index.model()->data(index, Qt::DecorationRole).value(); - - drawBackground(painter, option, index); - if(option.state & QStyle::State_MouseOver) - drawDecoration(painter, option, option.rect, - icon.pixmap(option.decorationSize, QIcon::Active)); - else - drawDecoration(painter, option, option.rect, - icon.pixmap(option.decorationSize, QIcon::Normal)); - drawDisplay(painter, option, option.rect, - index.model()->data(index, Qt::DisplayRole).toString()); - drawFocus(painter, option, option.rect); - - if(option.state & QStyle::State_MouseOver) - { - QRect r = option.rect; - r.adjust(0, 0, -1, -1); - - painter->drawRect(r); - } - } - } -}; - -TextureDescription *TextureViewer::GetCurrentTexture() -{ - return m_CachedTexture; -} - -void TextureViewer::UI_UpdateCachedTexture() -{ - if(!m_Ctx.LogLoaded()) - { - m_CachedTexture = NULL; - return; - } - - ResourceId id = m_LockedId; - if(id == ResourceId()) - id = m_Following.GetResourceId(m_Ctx); - - if(id == ResourceId()) - id = m_TexDisplay.texid; - - m_CachedTexture = m_Ctx.GetTexture(id); -} - -TextureViewer::TextureViewer(ICaptureContext &ctx, QWidget *parent) - : QFrame(parent), ui(new Ui::TextureViewer), m_Ctx(ctx) -{ - ui->setupUi(this); - - ui->textureList->setFont(Formatter::PreferredFont()); - ui->textureListFilter->setFont(Formatter::PreferredFont()); - ui->rangeBlack->setFont(Formatter::PreferredFont()); - ui->rangeWhite->setFont(Formatter::PreferredFont()); - ui->hdrMul->setFont(Formatter::PreferredFont()); - ui->channels->setFont(Formatter::PreferredFont()); - ui->mipLevel->setFont(Formatter::PreferredFont()); - ui->sliceFace->setFont(Formatter::PreferredFont()); - ui->zoomOption->setFont(Formatter::PreferredFont()); - - Reset(); - - on_checkerBack_clicked(); - - QObject::connect(ui->zoomOption->lineEdit(), &QLineEdit::returnPressed, this, - &TextureViewer::zoomOption_returnPressed); - - QObject::connect(ui->depthDisplay, &QToolButton::toggled, this, - &TextureViewer::channelsWidget_toggled); - QObject::connect(ui->stencilDisplay, &QToolButton::toggled, this, - &TextureViewer::channelsWidget_toggled); - QObject::connect(ui->flip_y, &QToolButton::toggled, this, &TextureViewer::channelsWidget_toggled); - QObject::connect(ui->gammaDisplay, &QToolButton::toggled, this, - &TextureViewer::channelsWidget_toggled); - QObject::connect(ui->channels, OverloadedSlot::of(&QComboBox::currentIndexChanged), this, - &TextureViewer::channelsWidget_selected); - QObject::connect(ui->hdrMul, OverloadedSlot::of(&QComboBox::currentIndexChanged), this, - &TextureViewer::channelsWidget_selected); - QObject::connect(ui->customShader, OverloadedSlot::of(&QComboBox::currentIndexChanged), this, - &TextureViewer::channelsWidget_selected); - QObject::connect(ui->customShader, &QComboBox::currentTextChanged, [this] { UI_UpdateChannels(); }); - QObject::connect(ui->rangeHistogram, &RangeHistogram::rangeUpdated, this, - &TextureViewer::range_rangeUpdated); - QObject::connect(ui->rangeBlack, &RDLineEdit::textChanged, this, - &TextureViewer::rangePoint_textChanged); - QObject::connect(ui->rangeBlack, &RDLineEdit::leave, this, &TextureViewer::rangePoint_leave); - QObject::connect(ui->rangeBlack, &RDLineEdit::keyPress, this, &TextureViewer::rangePoint_keyPress); - QObject::connect(ui->rangeWhite, &RDLineEdit::textChanged, this, - &TextureViewer::rangePoint_textChanged); - QObject::connect(ui->rangeWhite, &RDLineEdit::leave, this, &TextureViewer::rangePoint_leave); - QObject::connect(ui->rangeWhite, &RDLineEdit::keyPress, this, &TextureViewer::rangePoint_keyPress); - - for(RDToolButton *butt : {ui->channelRed, ui->channelGreen, ui->channelBlue, ui->channelAlpha}) - { - QObject::connect(butt, &RDToolButton::toggled, this, &TextureViewer::channelsWidget_toggled); - QObject::connect(butt, &RDToolButton::mouseClicked, this, - &TextureViewer::channelsWidget_mouseClicked); - QObject::connect(butt, &RDToolButton::doubleClicked, this, - &TextureViewer::channelsWidget_mouseClicked); - } - - QWidget *renderContainer = ui->renderContainer; - - ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace); - ui->dockarea->setToolWindowProperties( - renderContainer, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton | - ToolWindowManager::DisableDraggableTab | - ToolWindowManager::AlwaysDisplayFullTabs); - - ui->dockarea->addToolWindow(ui->inputThumbs, ToolWindowManager::AreaReference( - ToolWindowManager::RightOf, - ui->dockarea->areaOf(renderContainer), 0.25f)); - ui->dockarea->setToolWindowProperties(ui->inputThumbs, ToolWindowManager::HideCloseButton); - - ui->dockarea->addToolWindow( - ui->outputThumbs, ToolWindowManager::AreaReference(ToolWindowManager::AddTo, - ui->dockarea->areaOf(ui->inputThumbs))); - ui->dockarea->setToolWindowProperties(ui->outputThumbs, ToolWindowManager::HideCloseButton); - - ui->dockarea->addToolWindow( - ui->pixelContextLayout, - ToolWindowManager::AreaReference(ToolWindowManager::BottomOf, - ui->dockarea->areaOf(ui->outputThumbs), 0.25f)); - ui->dockarea->setToolWindowProperties(ui->pixelContextLayout, ToolWindowManager::HideCloseButton); - - ui->dockarea->addToolWindow(ui->textureListFrame, ToolWindowManager::NoArea); - ui->dockarea->setToolWindowProperties(ui->textureListFrame, ToolWindowManager::HideOnClose); - - ui->dockarea->setAllowFloatingWindow(false); - - renderContainer->setWindowTitle(tr("Unbound")); - ui->pixelContextLayout->setWindowTitle(tr("Pixel Context")); - ui->outputThumbs->setWindowTitle(tr("Outputs")); - ui->inputThumbs->setWindowTitle(tr("Inputs")); - ui->textureListFrame->setWindowTitle(tr("Texture List")); - - ui->textureList->setHoverCursor(Qt::PointingHandCursor); - - m_Goto = new TextureGoto(this, [this](QPoint p) { GotoLocation(p.x(), p.y()); }); - - QVBoxLayout *vertical = new QVBoxLayout(this); - - vertical->setSpacing(3); - vertical->setContentsMargins(3, 3, 3, 3); - - QWidget *flow1widget = new QWidget(this); - QWidget *flow2widget = new QWidget(this); - - FlowLayout *flow1 = new FlowLayout(flow1widget, 0, 3, 3); - FlowLayout *flow2 = new FlowLayout(flow2widget, 0, 3, 3); - - flow1widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - flow2widget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); - - flow1->addWidget(ui->channelsToolbar); - flow1->addWidget(ui->subresourceToolbar); - flow1->addWidget(ui->actionToolbar); - - flow2->addWidget(ui->zoomToolbar); - flow2->addWidget(ui->overlayToolbar); - flow2->addWidget(ui->rangeToolbar); - - vertical->addWidget(flow1widget); - vertical->addWidget(flow2widget); - vertical->addWidget(ui->dockarea); - - Ui_TextureViewer *u = ui; - u->pixelcontextgrid->setAlignment(u->pixelHistory, Qt::AlignCenter); - u->pixelcontextgrid->setAlignment(u->debugPixelContext, Qt::AlignCenter); - - QWidget *statusflowWidget = new QWidget(this); - - FlowLayout *statusflow = new FlowLayout(statusflowWidget, 0, 3, 0); - - statusflowWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - - ui->statusbar->removeWidget(ui->texStatusDim); - ui->statusbar->removeWidget(ui->pickSwatch); - ui->statusbar->removeWidget(ui->statusText); - - statusflow->addWidget(ui->texStatusDim); - statusflow->addWidget(ui->pickSwatch); - statusflow->addWidget(ui->statusText); - - ui->texStatusDim->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - ui->statusText->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - - ui->statusbar->addWidget(statusflowWidget); - - ui->channels->addItems({tr("RGBA"), tr("RGBM"), tr("Custom")}); - - ui->zoomOption->addItems({lit("10%"), lit("25%"), lit("50%"), lit("75%"), lit("100%"), - lit("200%"), lit("400%"), lit("800%")}); - - ui->hdrMul->addItems({lit("2"), lit("4"), lit("8"), lit("16"), lit("32"), lit("128")}); - - ui->overlay->addItems({tr("None"), tr("Highlight Drawcall"), tr("Wireframe Mesh"), - tr("Depth Test"), tr("Stencil Test"), tr("Backface Cull"), - tr("Viewport/Scissor Region"), tr("NaN/INF/-ve Display"), - tr("Histogram Clipping"), tr("Clear Before Pass"), tr("Clear Before Draw"), - tr("Quad Overdraw (Pass)"), tr("Quad Overdraw (Draw)"), - tr("Triangle Size (Pass)"), tr("Triangle Size (Draw)")}); - - ui->textureListFilter->addItems({QString(), tr("Textures"), tr("Render Targets")}); - - ui->textureList->setModel(new TextureListItemModel(this)); - ui->textureList->setItemDelegate(new TextureListItemDelegate(ui->textureList)); - ui->textureList->viewport()->setAttribute(Qt::WA_Hover); - - ui->zoomOption->setCurrentText(QString()); - ui->fitToWindow->toggle(); - - m_Ctx.AddLogViewer(this); - - SetupTextureTabs(); -} - -TextureViewer::~TextureViewer() -{ - m_Ctx.BuiltinWindowClosed(this); - m_Ctx.RemoveLogViewer(this); - delete ui; -} - -void TextureViewer::RT_FetchCurrentPixel(uint32_t x, uint32_t y, PixelValue &pickValue, - PixelValue &realValue) -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(texptr == NULL) - return; - - if(m_TexDisplay.FlipY) - y = (texptr->height - 1) - y; - - pickValue = m_Output->PickPixel(m_TexDisplay.texid, true, x, y, m_TexDisplay.sliceFace, - m_TexDisplay.mip, m_TexDisplay.sampleIdx); - - if(m_TexDisplay.CustomShader != ResourceId()) - realValue = m_Output->PickPixel(m_TexDisplay.texid, false, x, y, m_TexDisplay.sliceFace, - m_TexDisplay.mip, m_TexDisplay.sampleIdx); -} - -void TextureViewer::RT_PickPixelsAndUpdate(IReplayController *) -{ - PixelValue pickValue, realValue; - - uint32_t x = (uint32_t)m_PickedPoint.x(); - uint32_t y = (uint32_t)m_PickedPoint.y(); - - RT_FetchCurrentPixel(x, y, pickValue, realValue); - - m_Output->SetPixelContextLocation(x, y); - - m_CurHoverValue = pickValue; - - m_CurPixelValue = pickValue; - m_CurRealValue = realValue; - - GUIInvoke::call([this]() { UI_UpdateStatusText(); }); -} - -void TextureViewer::RT_PickHoverAndUpdate(IReplayController *) -{ - PixelValue pickValue, realValue; - - uint32_t x = (uint32_t)m_CurHoverPixel.x(); - uint32_t y = (uint32_t)m_CurHoverPixel.y(); - - RT_FetchCurrentPixel(x, y, pickValue, realValue); - - m_CurHoverValue = pickValue; - - GUIInvoke::call([this]() { UI_UpdateStatusText(); }); -} - -void TextureViewer::RT_UpdateAndDisplay(IReplayController *) -{ - if(m_Output != NULL) - m_Output->SetTextureDisplay(m_TexDisplay); - - GUIInvoke::call([this]() { ui->render->update(); }); -} - -void TextureViewer::RT_UpdateVisualRange(IReplayController *) -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(!m_Visualise || texptr == NULL || m_Output == NULL) - return; - - ResourceFormat fmt = texptr->format; - - if(m_TexDisplay.CustomShader != ResourceId()) - fmt.compCount = 4; - - bool channels[] = { - m_TexDisplay.Red ? true : false, m_TexDisplay.Green && fmt.compCount > 1, - m_TexDisplay.Blue && fmt.compCount > 2, m_TexDisplay.Alpha && fmt.compCount > 3, - }; - - rdctype::array histogram = m_Output->GetHistogram( - ui->rangeHistogram->rangeMin(), ui->rangeHistogram->rangeMax(), channels); - - if(!histogram.empty()) - { - QVector histogramVec(histogram.count); - if(histogram.count > 0) - memcpy(histogramVec.data(), histogram.elems, histogram.count * sizeof(uint32_t)); - - GUIInvoke::call([this, histogramVec]() { - ui->rangeHistogram->setHistogramRange(ui->rangeHistogram->rangeMin(), - ui->rangeHistogram->rangeMax()); - ui->rangeHistogram->setHistogramData(histogramVec); - }); - } -} - -void TextureViewer::UI_UpdateStatusText() -{ - TextureDescription *texptr = GetCurrentTexture(); - if(texptr == NULL) - return; - - TextureDescription &tex = *texptr; - - bool dsv = (tex.creationFlags & TextureCategory::DepthTarget) || - (tex.format.compType == CompType::Depth); - bool uintTex = (tex.format.compType == CompType::UInt); - bool sintTex = (tex.format.compType == CompType::SInt); - - if(m_TexDisplay.overlay == DebugOverlay::QuadOverdrawPass || - m_TexDisplay.overlay == DebugOverlay::QuadOverdrawDraw) - { - dsv = false; - uintTex = false; - sintTex = true; - } - - QColor swatchColor; - - if(dsv || uintTex || sintTex) - { - swatchColor = QColor(0, 0, 0); - } - else - { - float r = qBound(0.0f, m_CurHoverValue.value_f[0], 1.0f); - float g = qBound(0.0f, m_CurHoverValue.value_f[1], 1.0f); - float b = qBound(0.0f, m_CurHoverValue.value_f[2], 1.0f); - - if(tex.format.srgbCorrected || (tex.creationFlags & TextureCategory::SwapBuffer)) - { - r = powf(r, 1.0f / 2.2f); - g = powf(g, 1.0f / 2.2f); - b = powf(b, 1.0f / 2.2f); - } - - swatchColor = QColor(int(255.0f * r), int(255.0f * g), int(255.0f * b)); - } - - { - QPalette Pal(palette()); - - Pal.setColor(QPalette::Background, swatchColor); - - ui->pickSwatch->setAutoFillBackground(true); - ui->pickSwatch->setPalette(Pal); - } - - int y = m_CurHoverPixel.y() >> (int)m_TexDisplay.mip; - - uint32_t mipWidth = qMax(1U, tex.width >> (int)m_TexDisplay.mip); - uint32_t mipHeight = qMax(1U, tex.height >> (int)m_TexDisplay.mip); - - if(m_Ctx.APIProps().pipelineType == GraphicsAPI::OpenGL) - y = (int)(mipHeight - 1) - y; - if(m_TexDisplay.FlipY) - y = (int)(mipHeight - 1) - y; - - y = qMax(0, y); - - int x = m_CurHoverPixel.x() >> (int)m_TexDisplay.mip; - float invWidth = mipWidth > 0 ? 1.0f / mipWidth : 0.0f; - float invHeight = mipHeight > 0 ? 1.0f / mipHeight : 0.0f; - - QString hoverCoords = QFormatStr("%1, %2 (%3, %4)") - .arg(x, 4) - .arg(y, 4) - .arg((x * invWidth), 5, 'f', 4) - .arg((y * invHeight), 5, 'f', 4); - - QString statusText = tr("Hover - ") + hoverCoords; - - uint32_t hoverX = (uint32_t)m_CurHoverPixel.x(); - uint32_t hoverY = (uint32_t)m_CurHoverPixel.y(); - - if(hoverX > tex.width || hoverY > tex.height) - statusText = tr("Hover - [%1]").arg(hoverCoords); - - if(m_PickedPoint.x() >= 0) - { - x = m_PickedPoint.x() >> (int)m_TexDisplay.mip; - y = m_PickedPoint.y() >> (int)m_TexDisplay.mip; - if(m_Ctx.APIProps().pipelineType == GraphicsAPI::OpenGL) - y = (int)(mipHeight - 1) - y; - if(m_TexDisplay.FlipY) - y = (int)(mipHeight - 1) - y; - - y = qMax(0, y); - - statusText += tr(" - Right click - %1, %2: ").arg(x, 4).arg(y, 4); - - PixelValue val = m_CurPixelValue; - - if(m_TexDisplay.CustomShader != ResourceId()) - { - statusText += QFormatStr("%1, %2, %3, %4") - .arg(Formatter::Format(val.value_f[0])) - .arg(Formatter::Format(val.value_f[1])) - .arg(Formatter::Format(val.value_f[2])) - .arg(Formatter::Format(val.value_f[3])); - - val = m_CurRealValue; - - statusText += tr(" (Real: "); - } - - if(dsv) - { - statusText += tr("Depth "); - if(uintTex) - { - if(tex.format.compByteWidth == 2) - statusText += Formatter::Format(val.value_u16[0]); - else - statusText += Formatter::Format(val.value_u[0]); - } - else - { - statusText += Formatter::Format(val.value_f[0]); - } - - int stencil = (int)(255.0f * val.value_f[1]); - - statusText += - tr(", Stencil %1 / 0x%2").arg(stencil).arg(Formatter::Format(uint8_t(stencil & 0xff), true)); - } - else - { - if(uintTex) - { - statusText += QFormatStr("%1, %2, %3, %4") - .arg(Formatter::Format(val.value_u[0])) - .arg(Formatter::Format(val.value_u[1])) - .arg(Formatter::Format(val.value_u[2])) - .arg(Formatter::Format(val.value_u[3])); - } - else if(sintTex) - { - statusText += QFormatStr("%1, %2, %3, %4") - .arg(Formatter::Format(val.value_i[0])) - .arg(Formatter::Format(val.value_i[1])) - .arg(Formatter::Format(val.value_i[2])) - .arg(Formatter::Format(val.value_i[3])); - } - else - { - statusText += QFormatStr("%1, %2, %3, %4") - .arg(Formatter::Format(val.value_f[0])) - .arg(Formatter::Format(val.value_f[1])) - .arg(Formatter::Format(val.value_f[2])) - .arg(Formatter::Format(val.value_f[3])); - } - } - - if(m_TexDisplay.CustomShader != ResourceId()) - statusText += lit(")"); - - // PixelPicked = true; - } - else - { - statusText += tr(" - Right click to pick a pixel"); - - if(m_Output != NULL) - { - m_Ctx.Replay().AsyncInvoke([this](IReplayController *) { m_Output->DisablePixelContext(); }); - } - - // PixelPicked = false; - } - - // try and keep status text consistent by sticking to the high water mark - // of length (prevents nasty oscillation when the length of the string is - // just popping over/under enough to overflow onto the next line). - - if(statusText.length() > m_HighWaterStatusLength) - m_HighWaterStatusLength = statusText.length(); - - if(statusText.length() < m_HighWaterStatusLength) - statusText += QString(m_HighWaterStatusLength - statusText.length(), QLatin1Char(' ')); - - ui->statusText->setText(statusText); -} - -void TextureViewer::UI_UpdateTextureDetails() -{ - QString status; - - TextureDescription *texptr = GetCurrentTexture(); - if(texptr == NULL) - { - ui->texStatusDim->setText(status); - - ui->renderContainer->setWindowTitle(tr("Unbound")); - return; - } - - TextureDescription ¤t = *texptr; - - ResourceId followID = m_Following.GetResourceId(m_Ctx); - - { - TextureDescription *followtex = m_Ctx.GetTexture(followID); - BufferDescription *followbuf = m_Ctx.GetBuffer(followID); - - QString title; - - if(followID == ResourceId()) - { - title = tr("Unbound"); - } - else if(followtex || followbuf) - { - QString name; - - if(followtex) - name = ToQStr(followtex->name); - else - name = ToQStr(followbuf->name); - - switch(m_Following.Type) - { - case FollowType::OutputColour: - title = QString(tr("Cur Output %1 - %2")).arg(m_Following.index).arg(name); - break; - case FollowType::OutputDepth: title = QString(tr("Cur Depth Output - %1")).arg(name); break; - case FollowType::ReadWrite: - title = QString(tr("Cur RW Output %1 - %2")).arg(m_Following.index).arg(name); - break; - case FollowType::ReadOnly: - title = QString(tr("Cur Input %1 - %2")).arg(m_Following.index).arg(name); - break; - } - } - else - { - switch(m_Following.Type) - { - case FollowType::OutputColour: - title = QString(tr("Cur Output %1")).arg(m_Following.index); - break; - case FollowType::OutputDepth: title = QString(tr("Cur Depth Output")); break; - case FollowType::ReadWrite: - title = QString(tr("Cur RW Output %1")).arg(m_Following.index); - break; - case FollowType::ReadOnly: - title = QString(tr("Cur Input %1")).arg(m_Following.index); - break; - } - } - - ui->renderContainer->setWindowTitle(title); - } - - status = ToQStr(current.name) + lit(" - "); - - if(current.dimension >= 1) - status += QString::number(current.width); - if(current.dimension >= 2) - status += lit("x") + QString::number(current.height); - if(current.dimension >= 3) - status += lit("x") + QString::number(current.depth); - - if(current.arraysize > 1) - status += QFormatStr("[%1]").arg(QString::number(current.arraysize)); - - if(current.msQual > 0 || current.msSamp > 1) - status += QFormatStr(" MS{%1x %2Q}").arg(current.msSamp).arg(current.msQual); - - status += QFormatStr(" %1 mips").arg(current.mips); - - status += lit(" - ") + ToQStr(current.format.strname); - - if(current.format.compType != m_TexDisplay.typeHint && m_TexDisplay.typeHint != CompType::Typeless) - { - status += tr(" Viewed as %1").arg(ToQStr(m_TexDisplay.typeHint)); - } - - ui->texStatusDim->setText(status); -} - -void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) -{ - TextureDescription *texptr = GetCurrentTexture(); - - // reset high-water mark - m_HighWaterStatusLength = 0; - - if(texptr == NULL) - return; - - TextureDescription &tex = *texptr; - - bool newtex = (m_TexDisplay.texid != tex.ID); - - // save settings for this current texture - if(m_Ctx.Config().TextureViewer_PerTexSettings) - { - m_TextureSettings[m_TexDisplay.texid].r = ui->channelRed->isChecked(); - m_TextureSettings[m_TexDisplay.texid].g = ui->channelGreen->isChecked(); - m_TextureSettings[m_TexDisplay.texid].b = ui->channelBlue->isChecked(); - m_TextureSettings[m_TexDisplay.texid].a = ui->channelAlpha->isChecked(); - - m_TextureSettings[m_TexDisplay.texid].displayType = qMax(0, ui->channels->currentIndex()); - m_TextureSettings[m_TexDisplay.texid].customShader = ui->customShader->currentText(); - - m_TextureSettings[m_TexDisplay.texid].depth = ui->depthDisplay->isChecked(); - m_TextureSettings[m_TexDisplay.texid].stencil = ui->stencilDisplay->isChecked(); - - m_TextureSettings[m_TexDisplay.texid].mip = qMax(0, ui->mipLevel->currentIndex()); - m_TextureSettings[m_TexDisplay.texid].slice = qMax(0, ui->sliceFace->currentIndex()); - - m_TextureSettings[m_TexDisplay.texid].minrange = ui->rangeHistogram->blackPoint(); - m_TextureSettings[m_TexDisplay.texid].maxrange = ui->rangeHistogram->whitePoint(); - - m_TextureSettings[m_TexDisplay.texid].typeHint = m_Following.GetTypeHint(m_Ctx); - } - - m_TexDisplay.texid = tex.ID; - - // interpret the texture according to the currently following type. - if(!currentTextureIsLocked()) - m_TexDisplay.typeHint = m_Following.GetTypeHint(m_Ctx); - else - m_TexDisplay.typeHint = CompType::Typeless; - - // if there is no such type or it isn't being followed, use the last seen interpretation - if(m_TexDisplay.typeHint == CompType::Typeless && m_TextureSettings.contains(m_TexDisplay.texid)) - m_TexDisplay.typeHint = m_TextureSettings[m_TexDisplay.texid].typeHint; - - // try to maintain the pan in the new texture. If the new texture - // is approx an integer multiple of the old texture, just changing - // the scale will keep everything the same. This is useful for - // downsample chains and things where you're flipping back and forth - // between overlapping textures, but even in the non-integer case - // pan will be kept approximately the same. - QSizeF curSize((float)tex.width, (float)tex.height); - float curArea = area(curSize); - float prevArea = area(m_PrevSize); - - if(prevArea > 0.0f) - { - float prevX = m_TexDisplay.offx; - float prevY = m_TexDisplay.offy; - - // allow slight difference in aspect ratio for rounding errors - // in downscales (e.g. 1680x1050 -> 840x525 -> 420x262 in the - // last downscale the ratios are 1.6 and 1.603053435). - if(qAbs(aspect(curSize) - aspect(m_PrevSize)) < 0.01f) - { - m_TexDisplay.scale *= m_PrevSize.width() / curSize.width(); - setCurrentZoomValue(m_TexDisplay.scale); - } - else - { - // this scale factor is arbitrary really, only intention is to have - // integer scales come out precisely, other 'similar' sizes will be - // similar ish - float scaleFactor = (float)(sqrt(curArea) / sqrt(prevArea)); - - m_TexDisplay.offx = prevX * scaleFactor; - m_TexDisplay.offy = prevY * scaleFactor; - } - } - - m_PrevSize = curSize; - - // refresh scroll position - setScrollPosition(getScrollPosition()); - - UI_UpdateStatusText(); - - ui->mipLevel->clear(); - - m_TexDisplay.mip = 0; - m_TexDisplay.sliceFace = 0; - - bool usemipsettings = true; - bool useslicesettings = true; - - if(tex.msSamp > 1) - { - for(uint32_t i = 0; i < tex.msSamp; i++) - ui->mipLevel->addItem(tr("Sample %1").arg(i)); - - // add an option to display unweighted average resolved value, - // to get an idea of how the samples average - if(tex.format.compType != CompType::UInt && tex.format.compType != CompType::SInt && - tex.format.compType != CompType::Depth && !(tex.creationFlags & TextureCategory::DepthTarget)) - ui->mipLevel->addItem(tr("Average val")); - - ui->mipLabel->setText(tr("Sample")); - - ui->mipLevel->setCurrentIndex(0); - } - else - { - for(uint32_t i = 0; i < tex.mips; i++) - ui->mipLevel->addItem( - QFormatStr("%1 - %2x%3").arg(i).arg(qMax(1U, tex.width >> i)).arg(qMax(1U, tex.height >> i))); - - ui->mipLabel->setText(tr("Mip")); - - int highestMip = -1; - - // only switch to the selected mip for outputs, and when changing drawcall - if(!currentTextureIsLocked() && m_Following.Type != FollowType::ReadOnly && newdraw) - highestMip = m_Following.GetHighestMip(m_Ctx); - - // assuming we get a valid mip for the highest mip, only switch to it - // if we've selected a new texture, or if it's different than the last mip. - // This prevents the case where the user has clicked on another mip and - // we don't want to snap their view back when stepping between events with the - // same mip used. But it does mean that if they are stepping between - // events with different mips used, then we will update in that case. - if(highestMip >= 0 && (newtex || highestMip != m_PrevHighestMip)) - { - usemipsettings = false; - ui->mipLevel->setCurrentIndex(qBound(0, highestMip, (int)tex.mips - 1)); - } - - if(ui->mipLevel->currentIndex() == -1) - ui->mipLevel->setCurrentIndex(qBound(0, m_PrevHighestMip, (int)tex.mips - 1)); - - m_PrevHighestMip = highestMip; - } - - if(tex.mips == 1 && tex.msSamp <= 1) - ui->mipLevel->setEnabled(false); - else - ui->mipLevel->setEnabled(true); - - ui->sliceFace->clear(); - - if(tex.arraysize == 1 && tex.depth <= 1) - { - ui->sliceFace->setEnabled(false); - } - else - { - ui->sliceFace->setEnabled(true); - - QString cubeFaces[] = {lit("X+"), lit("X-"), lit("Y+"), lit("Y-"), lit("Z+"), lit("Z-")}; - - uint32_t numSlices = tex.arraysize; - - // for 3D textures, display the number of slices at this mip - if(tex.depth > 1) - numSlices = qMax(1u, tex.depth >> (int)ui->mipLevel->currentIndex()); - - for(uint32_t i = 0; i < numSlices; i++) - { - if(tex.cubemap) - { - QString name = cubeFaces[i % 6]; - if(numSlices > 6) - name = QFormatStr("[%1] %2").arg(i / 6).arg( - cubeFaces[i % 6]); // Front 1, Back 2, 3, 4 etc for cube arrays - ui->sliceFace->addItem(name); - } - else - { - ui->sliceFace->addItem(tr("Slice %1").arg(i)); - } - } - - int firstArraySlice = -1; - // only switch to the selected mip for outputs, and when changing drawcall - if(!currentTextureIsLocked() && m_Following.Type != FollowType::ReadOnly && newdraw) - firstArraySlice = m_Following.GetFirstArraySlice(m_Ctx); - - // see above with highestMip and prevHighestMip for the logic behind this - if(firstArraySlice >= 0 && (newtex || firstArraySlice != m_PrevFirstArraySlice)) - { - useslicesettings = false; - ui->sliceFace->setCurrentIndex(qBound(0, firstArraySlice, (int)numSlices - 1)); - } - - if(ui->sliceFace->currentIndex() == -1) - ui->sliceFace->setCurrentIndex(qBound(0, m_PrevFirstArraySlice, (int)numSlices - 1)); - - m_PrevFirstArraySlice = firstArraySlice; - } - - // because slice and mip are specially set above, we restore any per-tex settings to apply - // even if we don't switch to a new texture. - // Note that if the slice or mip was changed because that slice or mip is the selected one - // at the API level, we leave this alone. - if(m_Ctx.Config().TextureViewer_PerTexSettings && m_TextureSettings.contains(tex.ID)) - { - if(usemipsettings) - ui->mipLevel->setCurrentIndex(m_TextureSettings[tex.ID].mip); - - if(useslicesettings) - ui->sliceFace->setCurrentIndex(m_TextureSettings[tex.ID].slice); - } - - // handling for if we've switched to a new texture - if(newtex) - { - // if we save certain settings per-texture, restore them (if we have any) - if(m_Ctx.Config().TextureViewer_PerTexSettings && m_TextureSettings.contains(tex.ID)) - { - ui->channels->setCurrentIndex(m_TextureSettings[tex.ID].displayType); - - ui->customShader->setCurrentText(m_TextureSettings[tex.ID].customShader); - - ui->channelRed->setChecked(m_TextureSettings[tex.ID].r); - ui->channelGreen->setChecked(m_TextureSettings[tex.ID].g); - ui->channelBlue->setChecked(m_TextureSettings[tex.ID].b); - ui->channelAlpha->setChecked(m_TextureSettings[tex.ID].a); - - ui->depthDisplay->setChecked(m_TextureSettings[tex.ID].depth); - ui->stencilDisplay->setChecked(m_TextureSettings[tex.ID].stencil); - - m_NoRangePaint = true; - ui->rangeHistogram->setRange(m_TextureSettings[m_TexDisplay.texid].minrange, - m_TextureSettings[m_TexDisplay.texid].maxrange); - m_NoRangePaint = false; - } - else if(m_Ctx.Config().TextureViewer_PerTexSettings) - { - // if we are using per-tex settings, reset back to RGB - ui->channels->setCurrentIndex(0); - - ui->customShader->setCurrentText(QString()); - - ui->channelRed->setChecked(true); - ui->channelGreen->setChecked(true); - ui->channelBlue->setChecked(true); - ui->channelAlpha->setChecked(false); - - ui->depthDisplay->setChecked(true); - ui->stencilDisplay->setChecked(false); - - m_NoRangePaint = true; - UI_SetHistogramRange(texptr, m_TexDisplay.typeHint); - m_NoRangePaint = false; - } - - // reset the range if desired - if(m_Ctx.Config().TextureViewer_ResetRange) - { - UI_SetHistogramRange(texptr, m_TexDisplay.typeHint); - } - } - - UI_UpdateFittedScale(); - UI_UpdateTextureDetails(); - UI_UpdateChannels(); - - if(ui->autoFit->isChecked()) - AutoFitRange(); - - m_Ctx.Replay().AsyncInvoke([this](IReplayController *r) { - RT_UpdateVisualRange(r); - - RT_UpdateAndDisplay(r); - - if(m_Output != NULL) - RT_PickPixelsAndUpdate(r); - }); - - if(m_Ctx.HasTimelineBar()) - m_Ctx.GetTimelineBar()->HighlightResourceUsage(texptr->ID); -} - -void TextureViewer::UI_SetHistogramRange(const TextureDescription *tex, CompType typeHint) -{ - if(tex != NULL && (tex->format.compType == CompType::SNorm || typeHint == CompType::SNorm)) - ui->rangeHistogram->setRange(-1.0f, 1.0f); - else - ui->rangeHistogram->setRange(0.0f, 1.0f); -} - -void TextureViewer::UI_UpdateChannels() -{ - TextureDescription *tex = GetCurrentTexture(); - -#define SHOW(widget) widget->setVisible(true) -#define HIDE(widget) widget->setVisible(false) -#define ENABLE(widget) widget->setEnabled(true) -#define DISABLE(widget) widget->setEnabled(false) - - if(tex != NULL && (tex->creationFlags & TextureCategory::SwapBuffer)) - { - // swapbuffer is always srgb for 8-bit types, linear for 16-bit types - DISABLE(ui->gammaDisplay); - - if(tex->format.compByteWidth == 2 && !tex->format.special) - m_TexDisplay.linearDisplayAsGamma = false; - else - m_TexDisplay.linearDisplayAsGamma = true; - } - else - { - if(tex != NULL && !tex->format.srgbCorrected) - ENABLE(ui->gammaDisplay); - else - DISABLE(ui->gammaDisplay); - - m_TexDisplay.linearDisplayAsGamma = - !ui->gammaDisplay->isEnabled() || ui->gammaDisplay->isChecked(); - } - - if(tex != NULL && tex->format.srgbCorrected) - m_TexDisplay.linearDisplayAsGamma = false; - - bool dsv = false; - if(tex != NULL) - dsv = (tex->creationFlags & TextureCategory::DepthTarget) || - (tex->format.compType == CompType::Depth); - - if(dsv && ui->channels->currentIndex() != 2) - { - // Depth display (when not using custom) - - HIDE(ui->channelRed); - HIDE(ui->channelGreen); - HIDE(ui->channelBlue); - HIDE(ui->channelAlpha); - HIDE(ui->mulSep); - HIDE(ui->mulLabel); - HIDE(ui->hdrMul); - HIDE(ui->customShader); - HIDE(ui->customCreate); - HIDE(ui->customEdit); - HIDE(ui->customDelete); - SHOW(ui->depthDisplay); - SHOW(ui->stencilDisplay); - - m_TexDisplay.Red = ui->depthDisplay->isChecked(); - m_TexDisplay.Green = ui->stencilDisplay->isChecked(); - m_TexDisplay.Blue = false; - m_TexDisplay.Alpha = false; - - if(m_TexDisplay.Red == m_TexDisplay.Green && !m_TexDisplay.Red) - { - m_TexDisplay.Red = true; - ui->depthDisplay->setChecked(true); - } - - m_TexDisplay.HDRMul = -1.0f; - if(m_TexDisplay.CustomShader != ResourceId()) - { - memset(m_CurPixelValue.value_f, 0, sizeof(float) * 4); - memset(m_CurRealValue.value_f, 0, sizeof(float) * 4); - UI_UpdateStatusText(); - } - m_TexDisplay.CustomShader = ResourceId(); - } - else if(ui->channels->currentIndex() == 0 || !m_Ctx.LogLoaded()) - { - // RGBA - SHOW(ui->channelRed); - SHOW(ui->channelGreen); - SHOW(ui->channelBlue); - SHOW(ui->channelAlpha); - HIDE(ui->mulSep); - HIDE(ui->mulLabel); - HIDE(ui->hdrMul); - HIDE(ui->customShader); - HIDE(ui->customCreate); - HIDE(ui->customEdit); - HIDE(ui->customDelete); - HIDE(ui->depthDisplay); - HIDE(ui->stencilDisplay); - - m_TexDisplay.Red = ui->channelRed->isChecked(); - m_TexDisplay.Green = ui->channelGreen->isChecked(); - m_TexDisplay.Blue = ui->channelBlue->isChecked(); - m_TexDisplay.Alpha = ui->channelAlpha->isChecked(); - - m_TexDisplay.HDRMul = -1.0f; - if(m_TexDisplay.CustomShader != ResourceId()) - { - memset(m_CurPixelValue.value_f, 0, sizeof(float) * 4); - memset(m_CurRealValue.value_f, 0, sizeof(float) * 4); - UI_UpdateStatusText(); - } - m_TexDisplay.CustomShader = ResourceId(); - } - else if(ui->channels->currentIndex() == 1) - { - // RGBM - SHOW(ui->channelRed); - SHOW(ui->channelGreen); - SHOW(ui->channelBlue); - HIDE(ui->channelAlpha); - SHOW(ui->mulSep); - SHOW(ui->mulLabel); - SHOW(ui->hdrMul); - HIDE(ui->customShader); - HIDE(ui->customCreate); - HIDE(ui->customEdit); - HIDE(ui->customDelete); - HIDE(ui->depthDisplay); - HIDE(ui->stencilDisplay); - - m_TexDisplay.Red = ui->channelRed->isChecked(); - m_TexDisplay.Green = ui->channelGreen->isChecked(); - m_TexDisplay.Blue = ui->channelBlue->isChecked(); - m_TexDisplay.Alpha = false; - - bool ok = false; - float mul = ui->hdrMul->currentText().toFloat(&ok); - - if(!ok) - { - mul = 32.0f; - ui->hdrMul->setCurrentText(lit("32")); - } - - m_TexDisplay.HDRMul = mul; - if(m_TexDisplay.CustomShader != ResourceId()) - { - memset(m_CurPixelValue.value_f, 0, sizeof(float) * 4); - memset(m_CurRealValue.value_f, 0, sizeof(float) * 4); - UI_UpdateStatusText(); - } - m_TexDisplay.CustomShader = ResourceId(); - } - else if(ui->channels->currentIndex() == 2) - { - // custom shaders - SHOW(ui->channelRed); - SHOW(ui->channelGreen); - SHOW(ui->channelBlue); - SHOW(ui->channelAlpha); - HIDE(ui->mulSep); - HIDE(ui->mulLabel); - HIDE(ui->hdrMul); - SHOW(ui->customShader); - SHOW(ui->customCreate); - SHOW(ui->customEdit); - SHOW(ui->customDelete); - HIDE(ui->depthDisplay); - HIDE(ui->stencilDisplay); - - m_TexDisplay.Red = ui->channelRed->isChecked(); - m_TexDisplay.Green = ui->channelGreen->isChecked(); - m_TexDisplay.Blue = ui->channelBlue->isChecked(); - m_TexDisplay.Alpha = ui->channelAlpha->isChecked(); - - m_TexDisplay.HDRMul = -1.0f; - - m_TexDisplay.CustomShader = ResourceId(); - - QString shaderName = ui->customShader->currentText().toUpper(); - - if(m_CustomShaders.contains(shaderName)) - { - if(m_TexDisplay.CustomShader == ResourceId()) - { - memset(m_CurPixelValue.value_f, 0, sizeof(float) * 4); - memset(m_CurRealValue.value_f, 0, sizeof(float) * 4); - UI_UpdateStatusText(); - } - m_TexDisplay.CustomShader = m_CustomShaders[shaderName]; - ui->customDelete->setEnabled(true); - ui->customEdit->setEnabled(true); - } - else - { - ui->customDelete->setEnabled(false); - ui->customEdit->setEnabled(false); - } - } - -#undef HIDE -#undef SHOW -#undef ENABLE -#undef DISABLE - - m_TexDisplay.FlipY = ui->flip_y->isChecked(); - - INVOKE_MEMFN(RT_UpdateAndDisplay); - INVOKE_MEMFN(RT_UpdateVisualRange); -} - -void TextureViewer::SetupTextureTabs() -{ - ToolWindowManagerArea *textureTabs = ui->dockarea->areaOf(ui->renderContainer); - - QIcon tabIcon; - tabIcon.addFile(QStringLiteral(":/logo.svg"), QSize(), QIcon::Normal, QIcon::Off); - - textureTabs->setTabIcon(0, tabIcon); - - textureTabs->setElideMode(Qt::ElideRight); - - QObject::connect(textureTabs, &QTabWidget::currentChanged, this, - &TextureViewer::textureTab_Changed); - QObject::connect(textureTabs, &QTabWidget::tabCloseRequested, this, - &TextureViewer::textureTab_Closing); - - textureTabs->disableUserDrop(); -} - -void TextureViewer::textureTab_Changed(int index) -{ - ToolWindowManagerArea *textureTabs = ui->dockarea->areaOf(ui->renderContainer); - - QWidget *w = textureTabs->widget(index); - - if(w) - { - w->setLayout(ui->renderLayout); - - if(w == ui->renderContainer) - m_LockedId = ResourceId(); - else - m_LockedId = w->property("id").value(); - - UI_UpdateCachedTexture(); - } - - UI_OnTextureSelectionChanged(false); -} - -void TextureViewer::textureTab_Closing(int index) -{ - ToolWindowManagerArea *textureTabs = ui->dockarea->areaOf(ui->renderContainer); - if(index > 0) - { - // this callback happens AFTER the widget has already been removed unfortunately, so - // we need to search through the locked tab list to see which one was removed to be - // able to delete it properly. - QList ids = m_LockedTabs.keys(); - for(int i = 0; i < textureTabs->count(); i++) - { - QWidget *w = textureTabs->widget(i); - ResourceId id = w->property("id").value(); - ids.removeOne(id); - } - - if(ids.count() != 1) - qWarning() << "Expected only one removed tab, got " << ids.count(); - - for(ResourceId id : ids) - m_LockedTabs.remove(id); - - textureTabs->setCurrentIndex(index - 1); - textureTabs->widget(index - 1)->show(); - - return; - } - - // should never get here - tab 0 is the dynamic tab which is uncloseable. - qCritical() << "Somehow closing dynamic tab?"; - if(textureTabs->count() > 1) - { - textureTabs->setCurrentIndex(1); - textureTabs->widget(1)->show(); - } -} - -ResourcePreview *TextureViewer::UI_CreateThumbnail(ThumbnailStrip *strip) -{ - ResourcePreview *prev = new ResourcePreview(m_Ctx, m_Output); - - QObject::connect(prev, &ResourcePreview::clicked, this, &TextureViewer::thumb_clicked); - QObject::connect(prev, &ResourcePreview::doubleClicked, this, &TextureViewer::thumb_doubleClicked); - - prev->setActive(false); - strip->addThumb(prev); - return prev; -} - -void TextureViewer::UI_CreateThumbnails() -{ - if(!ui->outputThumbs->thumbs().isEmpty()) - return; - - // these will expand, but we make sure that there is a good set reserved - for(int i = 0; i < 9; i++) - { - ResourcePreview *prev = UI_CreateThumbnail(ui->outputThumbs); - - if(i == 0) - prev->setSelected(true); - } - - for(int i = 0; i < 128; i++) - UI_CreateThumbnail(ui->inputThumbs); -} - -void TextureViewer::GotoLocation(int x, int y) -{ - if(!m_Ctx.LogLoaded()) - return; - - TextureDescription *tex = GetCurrentTexture(); - - if(tex == NULL) - return; - - m_PickedPoint = QPoint(x, y); - - uint32_t mipHeight = qMax(1U, tex->height >> (int)m_TexDisplay.mip); - if(m_Ctx.APIProps().pipelineType == GraphicsAPI::OpenGL) - m_PickedPoint.setY((int)(mipHeight - 1) - m_PickedPoint.y()); - if(m_TexDisplay.FlipY) - m_PickedPoint.setY((int)(mipHeight - 1) - m_PickedPoint.x()); - - if(m_Output != NULL) - INVOKE_MEMFN(RT_PickPixelsAndUpdate); - INVOKE_MEMFN(RT_UpdateAndDisplay); - - UI_UpdateStatusText(); -} - -void TextureViewer::ViewTexture(ResourceId ID, bool focus) -{ - if(QThread::currentThread() != QCoreApplication::instance()->thread()) - { - GUIInvoke::call([this, ID, focus] { this->ViewTexture(ID, focus); }); - return; - } - - if(m_LockedTabs.contains(ID)) - { - if(focus) - ToolWindowManager::raiseToolWindow(this); - - QWidget *w = m_LockedTabs[ID]; - ToolWindowManagerArea *textureTabs = ui->dockarea->areaOf(ui->renderContainer); - - int idx = textureTabs->indexOf(w); - - if(idx >= 0) - textureTabs->setCurrentIndex(idx); - - INVOKE_MEMFN(RT_UpdateAndDisplay); - return; - } - - TextureDescription *tex = m_Ctx.GetTexture(ID); - if(tex) - { - QWidget *lockedContainer = new QWidget(this); - lockedContainer->setWindowTitle(ToQStr(tex->name)); - lockedContainer->setProperty("id", QVariant::fromValue(ID)); - - ToolWindowManagerArea *textureTabs = ui->dockarea->areaOf(ui->renderContainer); - - ToolWindowManager::AreaReference ref(ToolWindowManager::AddTo, textureTabs); - - ui->dockarea->addToolWindow(lockedContainer, ref); - ui->dockarea->setToolWindowProperties( - lockedContainer, - ToolWindowManager::DisallowUserDocking | ToolWindowManager::AlwaysDisplayFullTabs); - - lockedContainer->setLayout(ui->renderLayout); - - int idx = textureTabs->indexOf(lockedContainer); - - if(idx >= 0) - textureTabs->setTabIcon(idx, Icons::page_white_link()); - else - qCritical() << "Couldn't get tab index of new tab to set icon"; - - // newPanel.DockHandler.TabPageContextMenuStrip = tabContextMenu; - - if(focus) - ToolWindowManager::raiseToolWindow(this); - - m_LockedTabs[ID] = lockedContainer; - - INVOKE_MEMFN(RT_UpdateAndDisplay); - return; - } - - BufferDescription *buf = m_Ctx.GetBuffer(ID); - if(buf) - { - IBufferViewer *viewer = m_Ctx.ViewBuffer(0, 0, ID); - - m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); - } -} - -void TextureViewer::texContextItem_triggered() -{ - QAction *act = qobject_cast(QObject::sender()); - - QVariant eid = act->property("eid"); - if(eid.isValid()) - { - m_Ctx.SetEventID({}, eid.toUInt(), eid.toUInt()); - return; - } - - QVariant id = act->property("id"); - if(id.isValid()) - { - ViewTexture(id.value(), false); - return; - } -} - -void TextureViewer::showDisabled_triggered() -{ - m_ShowDisabled = !m_ShowDisabled; - - if(m_Ctx.LogLoaded()) - m_Ctx.RefreshStatus(); -} - -void TextureViewer::showEmpty_triggered() -{ - m_ShowEmpty = !m_ShowEmpty; - - if(m_Ctx.LogLoaded()) - m_Ctx.RefreshStatus(); -} - -void TextureViewer::AddResourceUsageEntry(QMenu &menu, uint32_t start, uint32_t end, - ResourceUsage usage) -{ - QAction *item = NULL; - - if(start == end) - item = new QAction( - QFormatStr("EID %1: %2").arg(start).arg(ToQStr(usage, m_Ctx.APIProps().pipelineType)), this); - else - item = new QAction( - QFormatStr("EID %1-%2: %3").arg(start).arg(end).arg(ToQStr(usage, m_Ctx.APIProps().pipelineType)), - this); - - QObject::connect(item, &QAction::triggered, this, &TextureViewer::texContextItem_triggered); - item->setProperty("eid", QVariant(end)); - - menu.addAction(item); -} - -void TextureViewer::OpenResourceContextMenu(ResourceId id, const rdctype::array &usage) -{ - QMenu contextMenu(this); - - QAction showDisabled(tr("Show Disabled"), this); - QAction showEmpty(tr("Show Empty"), this); - QAction openLockedTab(tr("Open new Locked Tab"), this); - QAction usageTitle(tr("Used:"), this); - QAction imageLayout(this); - - openLockedTab.setIcon(Icons::action_hover()); - - showDisabled.setChecked(m_ShowDisabled); - showDisabled.setChecked(m_ShowEmpty); - - contextMenu.addAction(&showDisabled); - contextMenu.addAction(&showEmpty); - - QObject::connect(&showDisabled, &QAction::triggered, this, &TextureViewer::showDisabled_triggered); - QObject::connect(&showEmpty, &QAction::triggered, this, &TextureViewer::showEmpty_triggered); - - if(m_Ctx.CurPipelineState().SupportsBarriers()) - { - contextMenu.addSeparator(); - imageLayout.setText(tr("Image is in layout ") + m_Ctx.CurPipelineState().GetResourceLayout(id)); - contextMenu.addAction(&imageLayout); - } - - if(id != ResourceId()) - { - contextMenu.addSeparator(); - contextMenu.addAction(&openLockedTab); - contextMenu.addSeparator(); - contextMenu.addAction(&usageTitle); - - openLockedTab.setProperty("id", QVariant::fromValue(id)); - - QObject::connect(&openLockedTab, &QAction::triggered, this, - &TextureViewer::texContextItem_triggered); - - uint32_t start = 0; - uint32_t end = 0; - ResourceUsage us = ResourceUsage::IndexBuffer; - - for(const EventUsage u : usage) - { - if(start == 0) - { - start = end = u.eventID; - us = u.usage; - continue; - } - - const DrawcallDescription *curDraw = m_Ctx.GetDrawcall(u.eventID); - - bool distinct = false; - - // if the usage is different from the last, add a new entry, - // or if the previous draw link is broken. - if(u.usage != us || curDraw == NULL || curDraw->previous == 0) - { - distinct = true; - } - else - { - // otherwise search back through real draws, to see if the - // last event was where we were - otherwise it's a new - // distinct set of drawcalls and should have a separate - // entry in the context menu - const DrawcallDescription *prev = m_Ctx.GetDrawcall(curDraw->previous); - - while(prev != NULL && prev->eventID > end) - { - if(!(prev->flags & (DrawFlags::Dispatch | DrawFlags::Drawcall | DrawFlags::CmdList))) - { - prev = m_Ctx.GetDrawcall(prev->previous); - } - else - { - distinct = true; - break; - } - - if(prev == NULL) - distinct = true; - } - } - - if(distinct) - { - AddResourceUsageEntry(contextMenu, start, end, us); - start = end = u.eventID; - us = u.usage; - } - - end = u.eventID; - } - - if(start != 0) - AddResourceUsageEntry(contextMenu, start, end, us); - - RDDialog::show(&contextMenu, QCursor::pos()); - } - else - { - RDDialog::show(&contextMenu, QCursor::pos()); - } -} - -void TextureViewer::InitResourcePreview(ResourcePreview *prev, ResourceId id, CompType typeHint, - bool force, Following &follow, const QString &bindName, - const QString &slotName) -{ - if(id != ResourceId() || force) - { - TextureDescription *texptr = m_Ctx.GetTexture(id); - BufferDescription *bufptr = m_Ctx.GetBuffer(id); - - if(texptr != NULL) - { - QString fullname = bindName; - if(texptr->customName) - { - if(!fullname.isEmpty()) - fullname += lit(" = "); - fullname += ToQStr(texptr->name); - } - if(fullname.isEmpty()) - fullname = ToQStr(texptr->name); - - prev->setResourceName(fullname); - WId handle = prev->thumbWinId(); - m_Ctx.Replay().AsyncInvoke([this, handle, id, typeHint](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CurWindowingSystem(), m_Ctx.FillWindowingData(handle), id, - typeHint); - }); - } - else if(bufptr != NULL) - { - QString fullname = bindName; - if(bufptr->customName) - { - if(!fullname.isEmpty()) - fullname += lit(" = "); - fullname += ToQStr(bufptr->name); - } - if(fullname.isEmpty()) - fullname = ToQStr(bufptr->name); - - prev->setResourceName(fullname); - WId handle = prev->thumbWinId(); - m_Ctx.Replay().AsyncInvoke([this, handle](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CurWindowingSystem(), m_Ctx.FillWindowingData(handle), - ResourceId(), CompType::Typeless); - }); - } - else - { - prev->setResourceName(QString()); - WId handle = prev->thumbWinId(); - m_Ctx.Replay().AsyncInvoke([this, handle](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CurWindowingSystem(), m_Ctx.FillWindowingData(handle), - ResourceId(), CompType::Typeless); - }); - } - - prev->setProperty("f", QVariant::fromValue(follow)); - prev->setSlotName(slotName); - prev->setActive(true); - prev->setSelected(m_Following == follow); - } - else if(m_Following == follow) - { - prev->setResourceName(tr("Unused")); - prev->setActive(true); - prev->setSelected(true); - - WId handle = prev->thumbWinId(); - m_Ctx.Replay().AsyncInvoke([this, handle](IReplayController *) { - m_Output->AddThumbnail(m_Ctx.CurWindowingSystem(), m_Ctx.FillWindowingData(handle), - ResourceId(), CompType::Typeless); - }); - } - else - { - prev->setResourceName(QString()); - prev->setActive(false); - prev->setSelected(false); - } -} - -void TextureViewer::InitStageResourcePreviews(ShaderStage stage, - const rdctype::array &resourceDetails, - const rdctype::array &mapping, - QMap> &ResList, - ThumbnailStrip *prevs, int &prevIndex, bool copy, - bool rw) -{ - for(int idx = 0; idx < mapping.count; idx++) - { - const BindpointMap &key = mapping[idx]; - - const QVector *resArray = NULL; - - if(ResList.contains(key)) - resArray = &ResList[key]; - - int arrayLen = resArray != NULL ? resArray->size() : 1; - - for(int arrayIdx = 0; arrayIdx < arrayLen; arrayIdx++) - { - ResourceId id = resArray != NULL ? resArray->at(arrayIdx).Id : ResourceId(); - CompType typeHint = resArray != NULL ? resArray->at(arrayIdx).typeHint : CompType::Typeless; - - bool used = key.used; - bool samplerBind = false; - bool otherBind = false; - - QString bindName; - - for(int b = 0; b < resourceDetails.count; b++) - { - const ShaderResource &bind = resourceDetails[b]; - if(bind.bindPoint == idx && bind.IsReadOnly) - { - bindName = ToQStr(bind.name); - otherBind = true; - break; - } - - if(bind.bindPoint == idx) - { - if(bind.IsSampler && !bind.IsReadOnly) - samplerBind = true; - else - otherBind = true; - } - } - - if(samplerBind && !otherBind) - continue; - - if(copy) - { - used = true; - bindName = tr("Source"); - } - - Following follow(rw ? FollowType::ReadWrite : FollowType::ReadOnly, stage, idx, arrayIdx); - QString slotName = QFormatStr("%1 %2%3") - .arg(m_Ctx.CurPipelineState().Abbrev(stage)) - .arg(rw ? lit("RW ") : lit("")) - .arg(idx); - - if(arrayLen > 1) - slotName += QFormatStr("[%1]").arg(arrayIdx); - - if(copy) - slotName = tr("SRC"); - - // show if it's referenced by the shader - regardless of empty or not - bool show = used; - - // it's bound, but not referenced, and we have "show disabled" - show = show || (m_ShowDisabled && !used && id != ResourceId()); - - // it's empty, and we have "show empty" - show = show || (m_ShowEmpty && id == ResourceId()); - - // it's the one we're following - show = show || (follow == m_Following); - - ResourcePreview *prev = NULL; - - if(prevIndex < prevs->thumbs().size()) - { - prev = prevs->thumbs()[prevIndex]; - - // don't use it if we're not actually going to show it - if(!show && !prev->isActive()) - continue; - } - else - { - // don't create it if we're not actually going to show it - if(!show) - continue; - - prev = UI_CreateThumbnail(prevs); - } - - prevIndex++; - - InitResourcePreview(prev, show ? id : ResourceId(), typeHint, show, follow, bindName, slotName); - } - } -} - -void TextureViewer::thumb_doubleClicked(QMouseEvent *e) -{ - if(e->buttons() & Qt::LeftButton) - { - ResourceId id = m_Following.GetResourceId(m_Ctx); - - if(id != ResourceId()) - ViewTexture(id, false); - } -} - -void TextureViewer::thumb_clicked(QMouseEvent *e) -{ - if(e->buttons() & Qt::LeftButton) - { - ResourcePreview *prev = qobject_cast(QObject::sender()); - - Following follow = prev->property("f").value(); - - for(ResourcePreview *p : ui->outputThumbs->thumbs()) - p->setSelected(false); - - for(ResourcePreview *p : ui->inputThumbs->thumbs()) - p->setSelected(false); - - m_Following = follow; - prev->setSelected(true); - - UI_UpdateCachedTexture(); - - ResourceId id = m_Following.GetResourceId(m_Ctx); - - if(id != ResourceId()) - { - UI_OnTextureSelectionChanged(false); - ui->renderContainer->show(); - } - } - - if(e->buttons() & Qt::RightButton) - { - ResourcePreview *prev = qobject_cast(QObject::sender()); - - Following follow = prev->property("f").value(); - - ResourceId id = follow.GetResourceId(m_Ctx); - - if(id == ResourceId() && follow == m_Following) - id = m_TexDisplay.texid; - - rdctype::array empty; - - if(id == ResourceId()) - { - OpenResourceContextMenu(id, empty); - } - else - { - m_Ctx.Replay().AsyncInvoke([this, id](IReplayController *r) { - rdctype::array usage = r->GetUsage(id); - - GUIInvoke::call([this, id, usage]() { OpenResourceContextMenu(id, usage); }); - }); - } - } -} - -void TextureViewer::render_mouseWheel(QWheelEvent *e) -{ - QPoint cursorPos = e->pos(); - - setFitToWindow(false); - - // scroll in logarithmic scale - double logScale = logf(m_TexDisplay.scale); - logScale += e->delta() / 2500.0; - UI_SetScale((float)expf(logScale), cursorPos.x(), cursorPos.y()); - - e->accept(); -} - -void TextureViewer::render_mouseMove(QMouseEvent *e) -{ - if(m_Output == NULL) - return; - - m_CurHoverPixel.setX(int((float(e->x() * ui->render->devicePixelRatio()) - m_TexDisplay.offx) / - m_TexDisplay.scale)); - m_CurHoverPixel.setY(int((float(e->y() * ui->render->devicePixelRatio()) - m_TexDisplay.offy) / - m_TexDisplay.scale)); - - if(m_TexDisplay.texid != ResourceId()) - { - TextureDescription *texptr = GetCurrentTexture(); - - if(texptr != NULL) - { - if(e->buttons() & Qt::RightButton) - { - ui->render->setCursor(QCursor(Qt::CrossCursor)); - - m_PickedPoint = m_CurHoverPixel; - - m_PickedPoint.setX(qBound(0, m_PickedPoint.x(), (int)texptr->width - 1)); - m_PickedPoint.setY(qBound(0, m_PickedPoint.y(), (int)texptr->height - 1)); - - m_Ctx.Replay().AsyncInvoke(lit("PickPixelClick"), - [this](IReplayController *r) { RT_PickPixelsAndUpdate(r); }); - } - else if(e->buttons() == Qt::NoButton) - { - m_Ctx.Replay().AsyncInvoke(lit("PickPixelHover"), - [this](IReplayController *r) { RT_PickHoverAndUpdate(r); }); - } - } - } - - QPoint curpos = QCursor::pos(); - - if(e->buttons() & Qt::LeftButton) - { - if(qAbs(m_DragStartPos.x() - curpos.x()) > ui->renderHScroll->singleStep() || - qAbs(m_DragStartPos.y() - curpos.y()) > ui->renderVScroll->singleStep()) - { - setScrollPosition(QPoint(m_DragStartScroll.x() + (curpos.x() - m_DragStartPos.x()), - m_DragStartScroll.y() + (curpos.y() - m_DragStartPos.y()))); - } - - ui->render->setCursor(QCursor(Qt::SizeAllCursor)); - } - - if(e->buttons() == Qt::NoButton) - { - ui->render->unsetCursor(); - } - - UI_UpdateStatusText(); -} - -void TextureViewer::render_mouseClick(QMouseEvent *e) -{ - ui->render->setFocus(); - - if(e->buttons() & Qt::RightButton) - render_mouseMove(e); - - if(e->buttons() & Qt::LeftButton) - { - m_DragStartPos = QCursor::pos(); - m_DragStartScroll = getScrollPosition(); - - ui->render->setCursor(QCursor(Qt::SizeAllCursor)); - } -} - -void TextureViewer::render_resize(QResizeEvent *e) -{ - UI_UpdateFittedScale(); - UI_CalcScrollbars(); - - INVOKE_MEMFN(RT_UpdateAndDisplay); -} - -void TextureViewer::render_keyPress(QKeyEvent *e) -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(texptr == NULL) - return; - - if(e->matches(QKeySequence::Copy)) - { - QClipboard *clipboard = QApplication::clipboard(); - clipboard->setText(ui->texStatusDim->text() + lit(" | ") + ui->statusText->text()); - } - - if(!m_Ctx.LogLoaded()) - return; - - if((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_G) - { - ShowGotoPopup(); - } - - bool nudged = false; - - int increment = 1 << (int)m_TexDisplay.mip; - - if(e->key() == Qt::Key_Up && m_PickedPoint.y() > 0) - { - m_PickedPoint -= QPoint(0, increment); - nudged = true; - } - else if(e->key() == Qt::Key_Down && m_PickedPoint.y() < (int)texptr->height - 1) - { - m_PickedPoint += QPoint(0, increment); - nudged = true; - } - else if(e->key() == Qt::Key_Left && m_PickedPoint.x() > 0) - { - m_PickedPoint -= QPoint(increment, 0); - nudged = true; - } - else if(e->key() == Qt::Key_Right && m_PickedPoint.x() < (int)texptr->height - 1) - { - m_PickedPoint += QPoint(increment, 0); - nudged = true; - } - - if(nudged) - { - m_PickedPoint = QPoint(qBound(0, m_PickedPoint.x(), (int)texptr->width - 1), - qBound(0, m_PickedPoint.y(), (int)texptr->height - 1)); - e->accept(); - - m_Ctx.Replay().AsyncInvoke([this](IReplayController *r) { - RT_PickPixelsAndUpdate(r); - RT_UpdateAndDisplay(r); - }); - - UI_UpdateStatusText(); - } -} - -float TextureViewer::CurMaxScrollX() -{ - TextureDescription *texptr = GetCurrentTexture(); - - QSizeF size(1.0f, 1.0f); - - if(texptr != NULL) - size = QSizeF(texptr->width, texptr->height); - - return realRenderWidth() - size.width() * m_TexDisplay.scale; -} - -float TextureViewer::CurMaxScrollY() -{ - TextureDescription *texptr = GetCurrentTexture(); - - QSizeF size(1.0f, 1.0f); - - if(texptr != NULL) - size = QSizeF(texptr->width, texptr->height); - - return realRenderHeight() - size.height() * m_TexDisplay.scale; -} - -QPoint TextureViewer::getScrollPosition() -{ - return QPoint((int)m_TexDisplay.offx, m_TexDisplay.offy); -} - -void TextureViewer::setScrollPosition(const QPoint &pos) -{ - m_TexDisplay.offx = qMax(CurMaxScrollX(), (float)pos.x()); - m_TexDisplay.offy = qMax(CurMaxScrollY(), (float)pos.y()); - - m_TexDisplay.offx = qMin(0.0f, m_TexDisplay.offx); - m_TexDisplay.offy = qMin(0.0f, m_TexDisplay.offy); - - if(ScrollUpdateScrollbars) - { - ScrollUpdateScrollbars = false; - - if(ui->renderHScroll->isEnabled()) - ui->renderHScroll->setValue(qBound(0, -int(m_TexDisplay.offx), ui->renderHScroll->maximum())); - - if(ui->renderVScroll->isEnabled()) - ui->renderVScroll->setValue(qBound(0, -int(m_TexDisplay.offy), ui->renderVScroll->maximum())); - - ScrollUpdateScrollbars = true; - } - - INVOKE_MEMFN(RT_UpdateAndDisplay); -} - -void TextureViewer::UI_CalcScrollbars() -{ - TextureDescription *texptr = GetCurrentTexture(); - - QSizeF size(1.0f, 1.0f); - - if(texptr != NULL) - { - size = QSizeF(texptr->width, texptr->height); - } - - if((int)floor(size.width() * m_TexDisplay.scale) <= realRenderWidth()) - { - ui->renderHScroll->setEnabled(false); - } - else - { - ui->renderHScroll->setEnabled(true); - - ui->renderHScroll->setMaximum((int)ceil(size.width() * m_TexDisplay.scale - realRenderWidth())); - ui->renderHScroll->setPageStep(qMax(1, ui->renderHScroll->maximum() / 6)); - ui->renderHScroll->setSingleStep(int(m_TexDisplay.scale)); - } - - if((int)floor(size.height() * m_TexDisplay.scale) <= realRenderHeight()) - { - ui->renderVScroll->setEnabled(false); - } - else - { - ui->renderVScroll->setEnabled(true); - - ui->renderVScroll->setMaximum((int)ceil(size.height() * m_TexDisplay.scale - realRenderHeight())); - ui->renderVScroll->setPageStep(qMax(1, ui->renderVScroll->maximum() / 6)); - ui->renderVScroll->setSingleStep(int(m_TexDisplay.scale)); - } -} - -void TextureViewer::on_renderHScroll_valueChanged(int position) -{ - if(!ScrollUpdateScrollbars) - return; - - ScrollUpdateScrollbars = false; - - { - float delta = (float)position / (float)ui->renderHScroll->maximum(); - setScrollPosition(QPoint((int)(CurMaxScrollX() * delta), getScrollPosition().y())); - } - - ScrollUpdateScrollbars = true; -} - -void TextureViewer::on_renderVScroll_valueChanged(int position) -{ - if(!ScrollUpdateScrollbars) - return; - - ScrollUpdateScrollbars = false; - - { - float delta = (float)position / (float)ui->renderVScroll->maximum(); - setScrollPosition(QPoint(getScrollPosition().x(), (int)(CurMaxScrollY() * delta))); - } - - ScrollUpdateScrollbars = true; -} - -void TextureViewer::UI_RecreatePanels() -{ - ICaptureContext *ctx = &m_Ctx; - - // while a log is loaded, pass NULL into the widget - if(!m_Ctx.LogLoaded()) - ctx = NULL; - - { - CustomPaintWidget *render = new CustomPaintWidget(ctx, ui->renderContainer); - render->setObjectName(ui->render->objectName()); - render->setSizePolicy(ui->render->sizePolicy()); - delete ui->render; - ui->render = render; - ui->gridLayout->addWidget(render, 1, 0, 1, 1); - } - - { - CustomPaintWidget *pixelContext = new CustomPaintWidget(ctx, ui->pixelContextLayout); - pixelContext->setObjectName(ui->pixelContext->objectName()); - pixelContext->setSizePolicy(ui->pixelContext->sizePolicy()); - delete ui->pixelContext; - ui->pixelContext = pixelContext; - ui->pixelcontextgrid->addWidget(pixelContext, 0, 0, 1, 2); - } - - ui->render->setColours(darkBack, lightBack); - ui->pixelContext->setColours(darkBack, lightBack); - - QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::render_mouseClick); - QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &TextureViewer::render_mouseMove); - QObject::connect(ui->render, &CustomPaintWidget::mouseWheel, this, - &TextureViewer::render_mouseWheel); - QObject::connect(ui->render, &CustomPaintWidget::resize, this, &TextureViewer::render_resize); - QObject::connect(ui->render, &CustomPaintWidget::keyPress, this, &TextureViewer::render_keyPress); - - QObject::connect(ui->pixelContext, &CustomPaintWidget::keyPress, this, - &TextureViewer::render_keyPress); -} - -void TextureViewer::OnLogfileLoaded() -{ - Reset(); - - WId renderID = ui->render->winId(); - WId contextID = ui->pixelContext->winId(); - - ui->saveTex->setEnabled(true); - ui->locationGoto->setEnabled(true); - ui->viewTexBuffer->setEnabled(true); - - TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model(); - - model->reset(TextureListItemModel::String, QString(), m_Ctx); - - m_TexDisplay.darkBackgroundColor = - FloatVector(darkBack.redF(), darkBack.greenF(), darkBack.blueF(), 1.0f); - m_TexDisplay.lightBackgroundColor = - FloatVector(lightBack.redF(), lightBack.greenF(), lightBack.blueF(), 1.0f); - - m_Ctx.Replay().BlockInvoke([renderID, contextID, this](IReplayController *r) { - m_Output = r->CreateOutput(m_Ctx.CurWindowingSystem(), m_Ctx.FillWindowingData(renderID), - ReplayOutputType::Texture); - - m_Output->SetPixelContext(m_Ctx.CurWindowingSystem(), m_Ctx.FillWindowingData(contextID)); - - ui->render->setOutput(m_Output); - ui->pixelContext->setOutput(m_Output); - - RT_UpdateAndDisplay(r); - - GUIInvoke::call([this]() { OnEventChanged(m_Ctx.CurEvent()); }); - }); - - m_Watcher = new QFileSystemWatcher({ConfigFilePath(QString())}, this); - - QObject::connect(m_Watcher, &QFileSystemWatcher::fileChanged, this, - &TextureViewer::customShaderModified); - QObject::connect(m_Watcher, &QFileSystemWatcher::directoryChanged, this, - &TextureViewer::customShaderModified); - reloadCustomShaders(QString()); -} - -void TextureViewer::Reset() -{ - m_CachedTexture = NULL; - - memset(&m_TexDisplay, 0, sizeof(m_TexDisplay)); - m_TexDisplay.darkBackgroundColor = - FloatVector(darkBack.redF(), darkBack.greenF(), darkBack.blueF(), 1.0f); - m_TexDisplay.lightBackgroundColor = - FloatVector(lightBack.redF(), lightBack.greenF(), lightBack.blueF(), 1.0f); - - m_Output = NULL; - - m_TextureSettings.clear(); - - m_PrevSize = QSizeF(); - m_HighWaterStatusLength = 0; - - ui->rangeHistogram->setRange(0.0f, 1.0f); - - ui->textureListFilter->setCurrentIndex(0); - - ui->renderHScroll->setEnabled(false); - ui->renderVScroll->setEnabled(false); - - // PixelPicked = false; - - ui->statusText->setText(QString()); - ui->renderContainer->setWindowTitle(tr("Current")); - ui->zoomOption->setCurrentText(QString()); - ui->mipLevel->clear(); - ui->sliceFace->clear(); - - ui->channels->setCurrentIndex(0); - ui->overlay->setCurrentIndex(0); - - { - QPalette Pal(palette()); - - Pal.setColor(QPalette::Background, Qt::black); - - ui->pickSwatch->setAutoFillBackground(true); - ui->pickSwatch->setPalette(Pal); - } - - ui->customShader->clear(); - - UI_RecreatePanels(); - - ui->inputThumbs->clearThumbs(); - ui->outputThumbs->clearThumbs(); - - UI_UpdateTextureDetails(); - UI_UpdateChannels(); -} - -void TextureViewer::OnLogfileClosed() -{ - Reset(); - - delete m_Watcher; - m_Watcher = NULL; - - m_LockedTabs.clear(); - - ui->customShader->clear(); - m_CustomShaders.clear(); - - ui->saveTex->setEnabled(false); - ui->locationGoto->setEnabled(false); - ui->viewTexBuffer->setEnabled(false); -} - -void TextureViewer::OnEventChanged(uint32_t eventID) -{ - UI_UpdateCachedTexture(); - - TextureDescription *CurrentTexture = GetCurrentTexture(); - - if(!currentTextureIsLocked() || - (CurrentTexture != NULL && m_TexDisplay.texid != CurrentTexture->ID)) - UI_OnTextureSelectionChanged(true); - - if(m_Output == NULL) - return; - - UI_CreateThumbnails(); - - QVector RTs = Following::GetOutputTargets(m_Ctx); - BoundResource Depth = Following::GetDepthTarget(m_Ctx); - - int outIndex = 0; - int inIndex = 0; - - bool copy = false, clear = false, compute = false; - Following::GetDrawContext(m_Ctx, copy, clear, compute); - - for(int rt = 0; rt < RTs.size(); rt++) - { - ResourcePreview *prev; - - if(outIndex < ui->outputThumbs->thumbs().size()) - prev = ui->outputThumbs->thumbs()[outIndex]; - else - prev = UI_CreateThumbnail(ui->outputThumbs); - - outIndex++; - - Following follow(FollowType::OutputColour, ShaderStage::Pixel, rt, 0); - QString bindName = (copy || clear) ? tr("Destination") : QString(); - QString slotName = (copy || clear) - ? tr("DST") - : (m_Ctx.CurPipelineState().OutputAbbrev() + QString::number(rt)); - - InitResourcePreview(prev, RTs[rt].Id, RTs[rt].typeHint, false, follow, bindName, slotName); - } - - // depth - { - ResourcePreview *prev; - - if(outIndex < ui->outputThumbs->thumbs().size()) - prev = ui->outputThumbs->thumbs()[outIndex]; - else - prev = UI_CreateThumbnail(ui->outputThumbs); - - outIndex++; - - Following follow(FollowType::OutputDepth, ShaderStage::Pixel, 0, 0); - - InitResourcePreview(prev, Depth.Id, Depth.typeHint, false, follow, QString(), tr("DS")); - } - - ShaderStage stages[] = {ShaderStage::Vertex, ShaderStage::Hull, ShaderStage::Domain, - ShaderStage::Geometry, ShaderStage::Pixel}; - - int count = 5; - - if(compute) - { - stages[0] = ShaderStage::Compute; - count = 1; - } - - const rdctype::array empty; - - // display resources used for all stages - for(int i = 0; i < count; i++) - { - ShaderStage stage = stages[i]; - - QMap> RWs = Following::GetReadWriteResources(m_Ctx, stage); - QMap> ROs = Following::GetReadOnlyResources(m_Ctx, stage); - - const ShaderReflection *details = Following::GetReflection(m_Ctx, stage); - const ShaderBindpointMapping &mapping = Following::GetMapping(m_Ctx, stage); - - InitStageResourcePreviews(stage, details != NULL ? details->ReadWriteResources : empty, - mapping.ReadWriteResources, RWs, ui->outputThumbs, outIndex, copy, - true); - - InitStageResourcePreviews(stage, details != NULL ? details->ReadOnlyResources : empty, - mapping.ReadOnlyResources, ROs, ui->inputThumbs, inIndex, copy, false); - } - - // hide others - const QVector &outThumbs = ui->outputThumbs->thumbs(); - - for(; outIndex < outThumbs.size(); outIndex++) - { - ResourcePreview *prev = outThumbs[outIndex]; - prev->setResourceName(QString()); - prev->setActive(false); - prev->setSelected(false); - } - - ui->outputThumbs->refreshLayout(); - - const QVector &inThumbs = ui->inputThumbs->thumbs(); - - for(; inIndex < inThumbs.size(); inIndex++) - { - ResourcePreview *prev = inThumbs[inIndex]; - prev->setResourceName(QString()); - prev->setActive(false); - prev->setSelected(false); - } - - ui->inputThumbs->refreshLayout(); - - INVOKE_MEMFN(RT_UpdateAndDisplay); - - // if(autoFit.Checked) - // AutoFitRange(); -} - -QVariant TextureViewer::persistData() -{ - QVariantMap state = ui->dockarea->saveState(); - - state[lit("darkBack")] = darkBack; - state[lit("lightBack")] = lightBack; - - return state; -} - -void TextureViewer::setPersistData(const QVariant &persistData) -{ - QVariantMap state = persistData.toMap(); - - darkBack = state[lit("darkBack")].value(); - lightBack = state[lit("lightBack")].value(); - - if(darkBack != lightBack) - { - ui->backcolorPick->setChecked(false); - ui->checkerBack->setChecked(true); - } - else - { - ui->backcolorPick->setChecked(true); - ui->checkerBack->setChecked(false); - } - - m_TexDisplay.darkBackgroundColor = - FloatVector(darkBack.redF(), darkBack.greenF(), darkBack.blueF(), 1.0f); - m_TexDisplay.lightBackgroundColor = - FloatVector(lightBack.redF(), lightBack.greenF(), lightBack.blueF(), 1.0f); - - ui->render->setColours(darkBack, lightBack); - ui->pixelContext->setColours(darkBack, lightBack); - - ui->dockarea->restoreState(state); - - SetupTextureTabs(); -} - -float TextureViewer::GetFitScale() -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(texptr == NULL) - return 1.0f; - - float xscale = (float)realRenderWidth() / (float)texptr->width; - float yscale = (float)realRenderHeight() / (float)texptr->height; - - return qMin(xscale, yscale); -} - -int TextureViewer::realRenderWidth() const -{ - return ui->render->width() * ui->render->devicePixelRatio(); -} - -int TextureViewer::realRenderHeight() const -{ - return ui->render->height() * ui->render->devicePixelRatio(); -} - -void TextureViewer::UI_UpdateFittedScale() -{ - if(ui->fitToWindow->isChecked()) - UI_SetScale(1.0f); -} - -void TextureViewer::UI_SetScale(float s) -{ - UI_SetScale(s, ui->render->width() / 2, ui->render->height() / 2); -} - -void TextureViewer::UI_SetScale(float s, int x, int y) -{ - if(ui->fitToWindow->isChecked()) - s = GetFitScale(); - - float prevScale = m_TexDisplay.scale; - - m_TexDisplay.scale = qBound(0.1f, s, 256.0f); - - INVOKE_MEMFN(RT_UpdateAndDisplay); - - float scaleDelta = (m_TexDisplay.scale / prevScale); - - QPoint newPos = getScrollPosition(); - - newPos -= QPoint(x, y); - newPos = QPoint((int)(newPos.x() * scaleDelta), (int)(newPos.y() * scaleDelta)); - newPos += QPoint(x, y); - - setScrollPosition(newPos); - - setCurrentZoomValue(m_TexDisplay.scale); - - UI_CalcScrollbars(); -} - -void TextureViewer::setCurrentZoomValue(float zoom) -{ - ui->zoomOption->setCurrentText(QString::number(ceil(zoom * 100)) + lit("%")); -} - -float TextureViewer::getCurrentZoomValue() -{ - if(ui->fitToWindow->isChecked()) - return m_TexDisplay.scale; - - QString zoomText = ui->zoomOption->currentText().replace(QLatin1Char('%'), QLatin1Char(' ')); - - bool ok = false; - int zoom = zoomText.toInt(&ok); - - if(!ok) - zoom = 100; - - return (float)(zoom) / 100.0f; -} - -void TextureViewer::setFitToWindow(bool checked) -{ - if(checked) - { - UI_UpdateFittedScale(); - ui->fitToWindow->setChecked(true); - } - else if(!checked) - { - ui->fitToWindow->setChecked(false); - float curScale = m_TexDisplay.scale; - ui->zoomOption->setCurrentText(QString()); - setCurrentZoomValue(curScale); - } -} - -void TextureViewer::on_fitToWindow_toggled(bool checked) -{ - UI_UpdateFittedScale(); -} - -void TextureViewer::on_zoomExactSize_clicked() -{ - ui->fitToWindow->setChecked(false); - UI_SetScale(1.0f); -} - -void TextureViewer::on_zoomOption_currentIndexChanged(int index) -{ - if(index >= 0) - { - setFitToWindow(false); - ui->zoomOption->setCurrentText(ui->zoomOption->itemText(index)); - UI_SetScale(getCurrentZoomValue()); - } -} - -void TextureViewer::zoomOption_returnPressed() -{ - UI_SetScale(getCurrentZoomValue()); -} - -void TextureViewer::on_overlay_currentIndexChanged(int index) -{ - m_TexDisplay.overlay = DebugOverlay::NoOverlay; - - if(ui->overlay->currentIndex() > 0) - m_TexDisplay.overlay = (DebugOverlay)ui->overlay->currentIndex(); - - INVOKE_MEMFN(RT_UpdateAndDisplay); -} - -void TextureViewer::channelsWidget_mouseClicked(QMouseEvent *event) -{ - RDToolButton *s = qobject_cast(QObject::sender()); - - if(event->button() == Qt::RightButton && s) - { - bool checkd = false; - - RDToolButton *butts[] = {ui->channelRed, ui->channelGreen, ui->channelBlue, ui->channelAlpha}; - - for(RDToolButton *b : butts) - { - if(b->isChecked() && b != s) - checkd = true; - if(!b->isChecked() && b == s) - checkd = true; - } - - ui->channelRed->setChecked(!checkd); - ui->channelGreen->setChecked(!checkd); - ui->channelBlue->setChecked(!checkd); - ui->channelAlpha->setChecked(!checkd); - s->setChecked(checkd); - } -} - -void TextureViewer::range_rangeUpdated() -{ - m_TexDisplay.rangemin = ui->rangeHistogram->blackPoint(); - m_TexDisplay.rangemax = ui->rangeHistogram->whitePoint(); - - ui->rangeBlack->setText(Formatter::Format(m_TexDisplay.rangemin)); - ui->rangeWhite->setText(Formatter::Format(m_TexDisplay.rangemax)); - - if(m_NoRangePaint) - return; - - INVOKE_MEMFN(RT_UpdateAndDisplay); - - if(m_Output == NULL) - { - ui->render->update(); - ui->pixelcontextgrid->update(); - } -} - -void TextureViewer::rangePoint_textChanged(QString text) -{ - m_RangePoint_Dirty = true; -} - -void TextureViewer::rangePoint_Update() -{ - float black = ui->rangeHistogram->blackPoint(); - float white = ui->rangeHistogram->whitePoint(); - - bool ok = false; - double d = ui->rangeBlack->text().toDouble(&ok); - - if(ok) - black = d; - - d = ui->rangeWhite->text().toDouble(&ok); - - if(ok) - white = d; - - ui->rangeHistogram->setRange(black, white); - - INVOKE_MEMFN(RT_UpdateVisualRange); -} - -void TextureViewer::rangePoint_leave() -{ - if(!m_RangePoint_Dirty) - return; - - rangePoint_Update(); - - m_RangePoint_Dirty = false; -} - -void TextureViewer::rangePoint_keyPress(QKeyEvent *e) -{ - // escape key - if(e->key() == Qt::Key_Escape) - { - m_RangePoint_Dirty = false; - ui->rangeHistogram->setRange(ui->rangeHistogram->blackPoint(), ui->rangeHistogram->whitePoint()); - } - if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) - { - rangePoint_Update(); - } -} - -void TextureViewer::on_zoomRange_clicked() -{ - float black = ui->rangeHistogram->blackPoint(); - float white = ui->rangeHistogram->whitePoint(); - - ui->autoFit->setChecked(false); - - ui->rangeHistogram->setRange(black, white); - - INVOKE_MEMFN(RT_UpdateVisualRange); -} - -void TextureViewer::on_autoFit_clicked() -{ - AutoFitRange(); -} - -void TextureViewer::on_reset01_clicked() -{ - UI_SetHistogramRange(GetCurrentTexture(), m_TexDisplay.typeHint); - - ui->autoFit->setChecked(false); - - INVOKE_MEMFN(RT_UpdateVisualRange); -} - -void TextureViewer::on_visualiseRange_clicked() -{ - if(ui->visualiseRange->isChecked()) - { - ui->rangeHistogram->setMinimumSize(QSize(300, 90)); - - m_Visualise = true; - INVOKE_MEMFN(RT_UpdateVisualRange); - } - else - { - m_Visualise = false; - ui->rangeHistogram->setMinimumSize(QSize(200, 0)); - - ui->rangeHistogram->setHistogramData({}); - } -} - -void TextureViewer::AutoFitRange() -{ - // no log loaded or buffer/empty texture currently being viewed - don't autofit - if(!m_Ctx.LogLoaded() || GetCurrentTexture() == NULL || m_Output == NULL) - return; - - m_Ctx.Replay().AsyncInvoke([this](IReplayController *r) { - PixelValue min, max; - std::tie(min, max) = m_Output->GetMinMax(); - - { - float minval = FLT_MAX; - float maxval = -FLT_MAX; - - bool changeRange = false; - - ResourceFormat fmt = GetCurrentTexture()->format; - - if(m_TexDisplay.CustomShader != ResourceId()) - { - fmt.compType = CompType::Float; - } - - for(int i = 0; i < 4; i++) - { - if(fmt.compType == CompType::UInt) - { - min.value_f[i] = min.value_u[i]; - max.value_f[i] = max.value_u[i]; - } - else if(fmt.compType == CompType::SInt) - { - min.value_f[i] = min.value_i[i]; - max.value_f[i] = max.value_i[i]; - } - } - - if(m_TexDisplay.Red) - { - minval = qMin(minval, min.value_f[0]); - maxval = qMax(maxval, max.value_f[0]); - changeRange = true; - } - if(m_TexDisplay.Green && fmt.compCount > 1) - { - minval = qMin(minval, min.value_f[1]); - maxval = qMax(maxval, max.value_f[1]); - changeRange = true; - } - if(m_TexDisplay.Blue && fmt.compCount > 2) - { - minval = qMin(minval, min.value_f[2]); - maxval = qMax(maxval, max.value_f[2]); - changeRange = true; - } - if(m_TexDisplay.Alpha && fmt.compCount > 3) - { - minval = qMin(minval, min.value_f[3]); - maxval = qMax(maxval, max.value_f[3]); - changeRange = true; - } - - if(changeRange) - { - GUIInvoke::call([this, minval, maxval]() { - ui->rangeHistogram->setRange(minval, maxval); - INVOKE_MEMFN(RT_UpdateVisualRange); - }); - } - } - }); -} - -void TextureViewer::on_backcolorPick_clicked() -{ - QColor col = QColorDialog::getColor(Qt::black, this, tr("Choose background colour")); - - if(!col.isValid()) - return; - - col = col.toRgb(); - m_TexDisplay.darkBackgroundColor = m_TexDisplay.lightBackgroundColor = - FloatVector(col.redF(), col.greenF(), col.blueF(), 1.0f); - - darkBack = lightBack = col; - - ui->render->setColours(darkBack, lightBack); - ui->pixelContext->setColours(darkBack, lightBack); - - ui->backcolorPick->setChecked(true); - ui->checkerBack->setChecked(false); - - INVOKE_MEMFN(RT_UpdateAndDisplay); - - if(m_Output == NULL) - { - ui->render->update(); - ui->pixelcontextgrid->update(); - } -} - -void TextureViewer::on_checkerBack_clicked() -{ - ui->checkerBack->setChecked(true); - ui->backcolorPick->setChecked(false); - - m_TexDisplay.lightBackgroundColor = FloatVector(0.81f, 0.81f, 0.81f, 1.0f); - m_TexDisplay.darkBackgroundColor = FloatVector(0.57f, 0.57f, 0.57f, 1.0f); - - darkBack = QColor::fromRgb(int(m_TexDisplay.darkBackgroundColor.x * 255.0f), - int(m_TexDisplay.darkBackgroundColor.y * 255.0f), - int(m_TexDisplay.darkBackgroundColor.z * 255.0f)); - - lightBack = QColor::fromRgb(int(m_TexDisplay.lightBackgroundColor.x * 255.0f), - int(m_TexDisplay.lightBackgroundColor.y * 255.0f), - int(m_TexDisplay.lightBackgroundColor.z * 255.0f)); - - ui->render->setColours(darkBack, lightBack); - ui->pixelContext->setColours(darkBack, lightBack); - - INVOKE_MEMFN(RT_UpdateAndDisplay); - - if(m_Output == NULL) - { - ui->render->update(); - ui->pixelcontextgrid->update(); - } -} - -void TextureViewer::on_mipLevel_currentIndexChanged(int index) -{ - TextureDescription *texptr = GetCurrentTexture(); - if(texptr == NULL) - return; - - TextureDescription &tex = *texptr; - - uint32_t prevSlice = m_TexDisplay.sliceFace; - - if(tex.mips > 1) - { - m_TexDisplay.mip = (uint32_t)qMax(0, index); - m_TexDisplay.sampleIdx = 0; - } - else - { - m_TexDisplay.mip = 0; - m_TexDisplay.sampleIdx = (uint32_t)qMax(0, index); - if(m_TexDisplay.sampleIdx == tex.msSamp) - m_TexDisplay.sampleIdx = ~0U; - } - - // For 3D textures, update the slice list for this mip - if(tex.depth > 1) - { - uint32_t newSlice = prevSlice >> (int)m_TexDisplay.mip; - - uint32_t numSlices = qMax(1U, tex.depth >> (int)m_TexDisplay.mip); - - ui->sliceFace->clear(); - - for(uint32_t i = 0; i < numSlices; i++) - ui->sliceFace->addItem(tr("Slice %1").arg(i)); - - // changing sliceFace index will handle updating range & re-picking - ui->sliceFace->setCurrentIndex((int)qBound(0U, newSlice, numSlices - 1)); - - return; - } - - INVOKE_MEMFN(RT_UpdateVisualRange); - - if(m_Output != NULL && m_PickedPoint.x() >= 0 && m_PickedPoint.y() >= 0) - { - INVOKE_MEMFN(RT_PickPixelsAndUpdate); - } - - INVOKE_MEMFN(RT_UpdateAndDisplay); -} - -void TextureViewer::on_sliceFace_currentIndexChanged(int index) -{ - TextureDescription *texptr = GetCurrentTexture(); - if(texptr == NULL) - return; - - TextureDescription &tex = *texptr; - m_TexDisplay.sliceFace = (uint32_t)qMax(0, index); - - if(tex.depth > 1) - m_TexDisplay.sliceFace = (uint32_t)(qMax(0, index) << (int)m_TexDisplay.mip); - - INVOKE_MEMFN(RT_UpdateVisualRange); - - if(m_Output != NULL && m_PickedPoint.x() >= 0 && m_PickedPoint.y() >= 0) - { - INVOKE_MEMFN(RT_PickPixelsAndUpdate); - } - - INVOKE_MEMFN(RT_UpdateAndDisplay); -} - -void TextureViewer::on_locationGoto_clicked() -{ - ShowGotoPopup(); -} - -void TextureViewer::ShowGotoPopup() -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(texptr) - { - QPoint p = m_PickedPoint; - - uint32_t mipHeight = qMax(1U, texptr->height >> (int)m_TexDisplay.mip); - - if(m_Ctx.APIProps().pipelineType == GraphicsAPI::OpenGL) - p.setY((int)(mipHeight - 1) - p.y()); - if(m_TexDisplay.FlipY) - p.setY((int)(mipHeight - 1) - p.y()); - - m_Goto->show(ui->render, p); - } -} - -void TextureViewer::on_viewTexBuffer_clicked() -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(texptr) - { - QString baseType; - - QString varName = lit("pixels"); - - uint32_t w = texptr->width; - - switch(texptr->format.specialFormat) - { - case SpecialFormat::BC1: - case SpecialFormat::BC2: - case SpecialFormat::BC3: - case SpecialFormat::BC4: - case SpecialFormat::BC5: - case SpecialFormat::BC6: - case SpecialFormat::BC7: - case SpecialFormat::ETC2: - case SpecialFormat::EAC: - case SpecialFormat::ASTC: - varName = lit("block"); - // display a 4x4 block at a time - w /= 4; - default: break; - } - - switch(texptr->format.specialFormat) - { - case SpecialFormat::Unknown: - { - if(texptr->format.compByteWidth == 1) - baseType = lit("byte"); - else if(texptr->format.compByteWidth == 2) - baseType = lit("short"); - else - baseType = lit("int"); - - baseType = QFormatStr("rgb x%1%2").arg(baseType).arg(texptr->format.compCount); - - break; - } - // 2x4 byte block, for 64-bit block formats - case SpecialFormat::BC1: - case SpecialFormat::BC4: - case SpecialFormat::ETC2: - case SpecialFormat::EAC: - baseType = lit("row_major xint2x1"); - break; - // 4x4 byte block, for 128-bit block formats - case SpecialFormat::BC2: - case SpecialFormat::BC3: - case SpecialFormat::BC5: - case SpecialFormat::BC6: - case SpecialFormat::BC7: - case SpecialFormat::ASTC: baseType = lit("row_major xint4x1"); break; - case SpecialFormat::R10G10B10A2: baseType = lit("uintten"); break; - case SpecialFormat::R11G11B10: baseType = lit("rgb floateleven"); break; - case SpecialFormat::R5G6B5: - case SpecialFormat::R5G5B5A1: baseType = lit("xshort"); break; - case SpecialFormat::R9G9B9E5: baseType = lit("xint"); break; - case SpecialFormat::R4G4B4A4: baseType = lit("xbyte2"); break; - case SpecialFormat::R4G4: baseType = lit("xbyte"); break; - case SpecialFormat::D16S8: - case SpecialFormat::D24S8: - case SpecialFormat::D32S8: - case SpecialFormat::YUV: baseType = lit("xint4"); break; - case SpecialFormat::S8: baseType = lit("xbyte"); break; - } - - QString format = QFormatStr("%1 %2[%3];").arg(baseType).arg(varName).arg(w); - - IBufferViewer *viewer = - m_Ctx.ViewTextureAsBuffer(m_TexDisplay.sliceFace, m_TexDisplay.mip, texptr->ID, format); - - m_Ctx.AddDockWindow(viewer->Widget(), DockReference::AddTo, this); - } -} - -void TextureViewer::on_saveTex_clicked() -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(!texptr || !m_Output) - return; - - TextureSave config; - memset(&config, 0, sizeof(config)); - config.jpegQuality = 90; - - config.id = m_TexDisplay.texid; - config.typeHint = m_TexDisplay.typeHint; - config.slice.sliceIndex = (int)m_TexDisplay.sliceFace; - config.mip = (int)m_TexDisplay.mip; - - if(texptr->depth > 1) - config.slice.sliceIndex = (int)m_TexDisplay.sliceFace >> (int)m_TexDisplay.mip; - - config.channelExtract = -1; - if(m_TexDisplay.Red && !m_TexDisplay.Green && !m_TexDisplay.Blue && !m_TexDisplay.Alpha) - config.channelExtract = 0; - if(!m_TexDisplay.Red && m_TexDisplay.Green && !m_TexDisplay.Blue && !m_TexDisplay.Alpha) - config.channelExtract = 1; - if(!m_TexDisplay.Red && !m_TexDisplay.Green && m_TexDisplay.Blue && !m_TexDisplay.Alpha) - config.channelExtract = 2; - if(!m_TexDisplay.Red && !m_TexDisplay.Green && !m_TexDisplay.Blue && m_TexDisplay.Alpha) - config.channelExtract = 3; - - config.comp.blackPoint = m_TexDisplay.rangemin; - config.comp.whitePoint = m_TexDisplay.rangemax; - config.alphaCol = m_TexDisplay.lightBackgroundColor; - config.alpha = m_TexDisplay.Alpha ? AlphaMapping::BlendToCheckerboard : AlphaMapping::Discard; - if(m_TexDisplay.Alpha && !ui->checkerBack->isChecked()) - config.alpha = AlphaMapping::BlendToColor; - - if(m_TexDisplay.CustomShader != ResourceId()) - { - ResourceId id; - m_Ctx.Replay().BlockInvoke( - [this, &id](IReplayController *r) { id = m_Output->GetCustomShaderTexID(); }); - - if(id != ResourceId()) - config.id = id; - } - - TextureSaveDialog saveDialog(*texptr, config, this); - int res = RDDialog::show(&saveDialog); - - config = saveDialog.config(); - - if(res) - { - bool ret = false; - QString fn = saveDialog.filename(); - - m_Ctx.Replay().BlockInvoke([this, &ret, config, fn](IReplayController *r) { - ret = r->SaveTexture(config, fn.toUtf8().data()); - }); - - if(!ret) - { - RDDialog::critical( - NULL, tr("Error saving texture"), - tr("Error saving texture %1.\n\nCheck diagnostic log in Help menu for more details.").arg(fn)); - } - } -} - -void TextureViewer::on_debugPixelContext_clicked() -{ - if(m_PickedPoint.x() < 0 || m_PickedPoint.y() < 0) - return; - - int x = m_PickedPoint.x() >> (int)m_TexDisplay.mip; - int y = m_PickedPoint.y() >> (int)m_TexDisplay.mip; - - m_Ctx.Replay().AsyncInvoke([this, x, y](IReplayController *r) { - ShaderDebugTrace *trace = r->DebugPixel((uint32_t)x, (uint32_t)y, m_TexDisplay.sampleIdx, ~0U); - - if(trace->states.count == 0) - { - r->FreeTrace(trace); - - // if we couldn't debug the pixel on this event, open up a pixel history - GUIInvoke::call([this]() { on_pixelHistory_clicked(); }); - return; - } - - GUIInvoke::call([this, x, y, trace]() { - QString debugContext = tr("Pixel %1,%2").arg(x).arg(y); - - const ShaderReflection *shaderDetails = - m_Ctx.CurPipelineState().GetShaderReflection(ShaderStage::Pixel); - const ShaderBindpointMapping &bindMapping = - m_Ctx.CurPipelineState().GetBindpointMapping(ShaderStage::Pixel); - - // viewer takes ownership of the trace - IShaderViewer *s = - m_Ctx.DebugShader(&bindMapping, shaderDetails, ShaderStage::Pixel, trace, debugContext); - - m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this); - }); - }); -} - -void TextureViewer::on_pixelHistory_clicked() -{ - TextureDescription *texptr = GetCurrentTexture(); - - if(!texptr || !m_Output) - return; - - int x = m_PickedPoint.x() >> (int)m_TexDisplay.mip; - int y = m_PickedPoint.y() >> (int)m_TexDisplay.mip; - - IPixelHistoryView *hist = m_Ctx.ViewPixelHistory(texptr->ID, x, y, m_TexDisplay); - - m_Ctx.AddDockWindow(hist->Widget(), DockReference::RightOf, this, 0.2f); - - // add a short delay so that controls repainting after a new panel appears can get at the - // render thread before we insert the long blocking pixel history task - LambdaThread *thread = new LambdaThread([this, texptr, x, y, hist]() { - QThread::msleep(150); - m_Ctx.Replay().AsyncInvoke([this, texptr, x, y, hist](IReplayController *r) { - rdctype::array history = - r->PixelHistory(texptr->ID, (uint32_t)x, (int32_t)y, m_TexDisplay.sliceFace, - m_TexDisplay.mip, m_TexDisplay.sampleIdx, m_TexDisplay.typeHint); - - GUIInvoke::call([hist, history] { hist->SetHistory(history); }); - }); - }); - thread->selfDelete(true); - thread->start(); -} - -void TextureViewer::on_texListShow_clicked() -{ - if(ui->textureListFrame->isVisible()) - { - ui->dockarea->moveToolWindow(ui->textureListFrame, ToolWindowManager::NoArea); - } - else - { - ui->textureListFilter->setCurrentText(QString()); - ui->dockarea->moveToolWindow( - ui->textureListFrame, - ToolWindowManager::AreaReference(ToolWindowManager::LeftOf, - ui->dockarea->areaOf(ui->renderContainer), 0.2f)); - ui->dockarea->setToolWindowProperties(ui->textureListFrame, ToolWindowManager::HideOnClose); - } -} - -void TextureViewer::on_cancelTextureListFilter_clicked() -{ - ui->textureListFilter->setCurrentText(QString()); -} - -void TextureViewer::on_textureListFilter_editTextChanged(const QString &text) -{ - TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model(); - - if(model == NULL) - return; - - model->reset(TextureListItemModel::String, text, m_Ctx); -} - -void TextureViewer::on_textureListFilter_currentIndexChanged(int index) -{ - TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model(); - - if(model == NULL) - return; - - if(ui->textureListFilter->currentIndex() == 1) - model->reset(TextureListItemModel::Textures, QString(), m_Ctx); - else if(ui->textureListFilter->currentIndex() == 2) - model->reset(TextureListItemModel::RenderTargets, QString(), m_Ctx); - else - model->reset(TextureListItemModel::String, ui->textureListFilter->currentText(), m_Ctx); -} - -void TextureViewer::on_textureList_clicked(const QModelIndex &index) -{ - ResourceId id = index.model()->data(index, Qt::UserRole).value(); - ViewTexture(id, false); -} - -void TextureViewer::reloadCustomShaders(const QString &filter) -{ - if(!m_Ctx.LogLoaded()) - return; - - if(filter.isEmpty()) - { - QString prevtext = ui->customShader->currentText(); - - QList shaders = m_CustomShaders.values(); - - m_Ctx.Replay().AsyncInvoke([shaders](IReplayController *r) { - for(ResourceId s : shaders) - r->FreeCustomShader(s); - }); - - ui->customShader->clear(); - m_CustomShaders.clear(); - - ui->customShader->setCurrentText(prevtext); - } - else - { - QString fn = QFileInfo(filter).baseName(); - QString key = fn.toUpper(); - - if(m_CustomShaders.contains(key)) - { - if(m_CustomShadersBusy.contains(key)) - return; - - ResourceId freed = m_CustomShaders[key]; - m_Ctx.Replay().AsyncInvoke([freed](IReplayController *r) { r->FreeCustomShader(freed); }); - - m_CustomShaders.remove(key); - - QString text = ui->customShader->currentText(); - - for(int i = 0; i < ui->customShader->count(); i++) - { - if(ui->customShader->itemText(i).compare(fn, Qt::CaseInsensitive) == 0) - { - ui->customShader->removeItem(i); - break; - } - } - - ui->customShader->setCurrentText(text); - } - } - - QStringList files = - QDir(ConfigFilePath(QString())) - .entryList({QFormatStr("*.%1").arg(m_Ctx.CurPipelineState().GetShaderExtension())}, - QDir::Files | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase); - - QStringList watchedFiles = m_Watcher->files(); - if(!watchedFiles.isEmpty()) - m_Watcher->removePaths(watchedFiles); - - for(const QString &f : files) - { - QString fn = QFileInfo(f).baseName(); - QString key = fn.toUpper(); - - m_Watcher->addPath(ConfigFilePath(f)); - - if(!m_CustomShaders.contains(key) && !m_CustomShadersBusy.contains(key)) - { - QFile fileHandle(ConfigFilePath(f)); - if(fileHandle.open(QFile::ReadOnly | QFile::Text)) - { - QTextStream stream(&fileHandle); - QString source = stream.readAll(); - - fileHandle.close(); - - m_CustomShaders[key] = ResourceId(); - m_CustomShadersBusy.push_back(key); - m_Ctx.Replay().AsyncInvoke([this, fn, key, source](IReplayController *r) { - rdctype::str errors; - - ResourceId id; - std::tie(id, errors) = - r->BuildCustomShader("main", source.toUtf8().data(), 0, ShaderStage::Pixel); - - if(m_CustomShaderEditor.contains(key)) - { - IShaderViewer *editor = m_CustomShaderEditor[key]; - GUIInvoke::call([editor, errors]() { editor->ShowErrors(ToQStr(errors)); }); - } - - GUIInvoke::call([this, fn, key, id]() { - QString prevtext = ui->customShader->currentText(); - ui->customShader->addItem(fn); - ui->customShader->setCurrentText(prevtext); - - m_CustomShaders[key] = id; - m_CustomShadersBusy.removeOne(key); - - UI_UpdateChannels(); - }); - }); - } - } - } -} - -void TextureViewer::on_customCreate_clicked() -{ - QString filename = ui->customShader->currentText(); - - if(filename.isEmpty()) - { - RDDialog::critical(this, tr("Error Creating Shader"), - tr("No shader name specified.\nEnter a new name in the textbox")); - return; - } - - if(m_CustomShaders.contains(filename.toUpper())) - { - RDDialog::critical(this, tr("Error Creating Shader"), - tr("Selected shader already exists.\nEnter a new name in the textbox.")); - ui->customShader->setCurrentText(QString()); - UI_UpdateChannels(); - return; - } - - QString path = ConfigFilePath(filename + lit(".") + m_Ctx.CurPipelineState().GetShaderExtension()); - - QString src; - - if(IsD3D(m_Ctx.APIProps().pipelineType)) - { - src = - lit("float4 main(float4 pos : SV_Position, float4 uv : TEXCOORD0) : SV_Target0\n" - "{\n" - " return float4(0,0,0,1);\n" - "}\n"); - } - else - { - src = - lit("#version 420 core\n\n" - "layout (location = 0) in vec2 uv;\n\n" - "layout (location = 0) out vec4 color_out;\n\n" - "void main()\n" - "{\n" - " color_out = vec4(0,0,0,1);\n" - "}\n"); - } - - QFile fileHandle(path); - if(fileHandle.open(QFile::WriteOnly | QIODevice::Truncate | QIODevice::Text)) - { - fileHandle.write(src.toUtf8()); - fileHandle.close(); - } - else - { - RDDialog::critical( - this, tr("Cannot create shader"), - tr("Couldn't create file for shader %1\n%2").arg(filename).arg(fileHandle.errorString())); - } - - // auto-open edit window - on_customEdit_clicked(); - - reloadCustomShaders(filename); -} - -void TextureViewer::on_customEdit_clicked() -{ - QString filename = ui->customShader->currentText(); - QString key = filename.toUpper(); - - if(filename.isEmpty()) - { - RDDialog::critical(this, tr("Error Editing Shader"), - tr("No shader selected.\nSelect a custom shader from the drop-down")); - return; - } - - QString path = ConfigFilePath(filename + lit(".") + m_Ctx.CurPipelineState().GetShaderExtension()); - - QString src; - - QFile fileHandle(path); - if(fileHandle.open(QFile::ReadOnly | QFile::Text)) - { - QTextStream stream(&fileHandle); - src = stream.readAll(); - fileHandle.close(); - } - else - { - RDDialog::critical( - this, tr("Cannot open shader"), - tr("Couldn't open file for shader %1\n%2").arg(filename).arg(fileHandle.errorString())); - return; - } - - QStringMap files; - files[filename] = src; - - IShaderViewer *s = m_Ctx.EditShader( - true, lit("main"), files, - // Save Callback - [this, key, filename, path](ICaptureContext *ctx, IShaderViewer *viewer, - const QStringMap &updatedfiles) { - { - QFile fileHandle(path); - if(fileHandle.open(QFile::WriteOnly | QIODevice::Truncate | QIODevice::Text)) - { - fileHandle.write(updatedfiles[filename].toUtf8()); - fileHandle.close(); - - // watcher doesn't trigger on internal modifications - reloadCustomShaders(filename); - } - else - { - RDDialog::critical( - this, tr("Cannot save shader"), - tr("Couldn't save file for shader %1\n%2").arg(filename).arg(fileHandle.errorString())); - } - } - }, - - [this, key](ICaptureContext *ctx) { m_CustomShaderEditor.remove(key); }); - - m_CustomShaderEditor[key] = s; - - m_Ctx.AddDockWindow(s->Widget(), DockReference::AddTo, this); -} - -void TextureViewer::on_customDelete_clicked() -{ - QString shaderName = ui->customShader->currentText(); - - if(shaderName.isEmpty()) - { - RDDialog::critical(this, tr("Error Deleting Shader"), - tr("No shader selected.\nSelect a custom shader from the drop-down")); - return; - } - - if(!m_CustomShaders.contains(shaderName.toUpper())) - { - RDDialog::critical( - this, tr("Error Deleting Shader"), - tr("Selected shader doesn't exist.\nSelect a custom shader from the drop-down")); - return; - } - - QMessageBox::StandardButton res = - RDDialog::question(this, tr("Deleting Custom Shader"), - tr("Really delete %1?").arg(shaderName), RDDialog::YesNoCancel); - - if(res == QMessageBox::Yes) - { - QString path = - ConfigFilePath(shaderName + lit(".") + m_Ctx.CurPipelineState().GetShaderExtension()); - if(!QFileInfo::exists(path)) - { - RDDialog::critical( - this, tr("Error Deleting Shader"), - tr("Shader file %1 can't be found.\nSelect a custom shader from the drop-down") - .arg(shaderName)); - return; - } - - if(!QFile::remove(path)) - { - RDDialog::critical(this, tr("Error Deleting Shader"), - tr("Error deleting shader %1 from disk").arg(shaderName)); - return; - } - - ui->customShader->setCurrentText(QString()); - UI_UpdateChannels(); - } -} - -void TextureViewer::customShaderModified(const QString &path) -{ - // allow time for modifications to finish - QThread::msleep(15); - - reloadCustomShaders(QString()); -} diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h deleted file mode 100644 index 9d8f58a9e..000000000 --- a/qrenderdoc/Windows/TextureViewer.h +++ /dev/null @@ -1,320 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2016-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include -#include -#include "Code/CaptureContext.h" - -namespace Ui -{ -class TextureViewer; -} - -class ResourcePreview; -class ThumbnailStrip; -class TextureGoto; -class QFileSystemWatcher; - -enum struct FollowType -{ - OutputColour, - OutputDepth, - ReadWrite, - ReadOnly -}; - -struct Following -{ - FollowType Type; - ShaderStage Stage; - int index; - int arrayEl; - - static const Following Default; - - Following(); - - Following(FollowType t, ShaderStage s, int i, int a); - - bool operator==(const Following &o); - bool operator!=(const Following &o); - static void GetDrawContext(ICaptureContext &ctx, bool ©, bool &clear, bool &compute); - - int GetHighestMip(ICaptureContext &ctx); - int GetFirstArraySlice(ICaptureContext &ctx); - CompType GetTypeHint(ICaptureContext &ctx); - - ResourceId GetResourceId(ICaptureContext &ctx); - BoundResource GetBoundResource(ICaptureContext &ctx, int arrayIdx); - - static QVector GetOutputTargets(ICaptureContext &ctx); - - static BoundResource GetDepthTarget(ICaptureContext &ctx); - - QMap> GetReadWriteResources(ICaptureContext &ctx); - - static QMap> GetReadWriteResources(ICaptureContext &ctx, - ShaderStage stage); - - QMap> GetReadOnlyResources(ICaptureContext &ctx); - - static QMap> GetReadOnlyResources(ICaptureContext &ctx, - ShaderStage stage); - - const ShaderReflection *GetReflection(ICaptureContext &ctx); - static const ShaderReflection *GetReflection(ICaptureContext &ctx, ShaderStage stage); - - const ShaderBindpointMapping &GetMapping(ICaptureContext &ctx); - static const ShaderBindpointMapping &GetMapping(ICaptureContext &ctx, ShaderStage stage); -}; - -struct TexSettings -{ - TexSettings() - { - r = g = b = true; - a = false; - mip = 0; - slice = 0; - minrange = 0.0f; - maxrange = 1.0f; - typeHint = CompType::Typeless; - } - - int displayType; // RGBA, RGBM, Custom - QString customShader; - bool r, g, b, a; - bool depth, stencil; - int mip, slice; - float minrange, maxrange; - CompType typeHint; -}; - -class TextureViewer : public QFrame, public ITextureViewer, public ILogViewer -{ -private: - Q_OBJECT - - Q_PROPERTY(QVariant persistData READ persistData WRITE setPersistData DESIGNABLE false SCRIPTABLE false) - -public: - explicit TextureViewer(ICaptureContext &ctx, QWidget *parent = 0); - ~TextureViewer(); - - // ITextureViewer - QWidget *Widget() override { return this; } - void ViewTexture(ResourceId ID, bool focus) override; - void GotoLocation(int x, int y) override; - - // ILogViewerForm - void OnLogfileLoaded() override; - void OnLogfileClosed() override; - void OnSelectedEventChanged(uint32_t eventID) override {} - void OnEventChanged(uint32_t eventID) override; - - QVariant persistData(); - void setPersistData(const QVariant &persistData); - -private slots: - // automatic slots - void on_renderHScroll_valueChanged(int position); - void on_renderVScroll_valueChanged(int position); - - void on_fitToWindow_toggled(bool checked); - void on_zoomExactSize_clicked(); - void on_zoomOption_currentIndexChanged(int index); - - void on_mipLevel_currentIndexChanged(int index); - void on_sliceFace_currentIndexChanged(int index); - void on_overlay_currentIndexChanged(int index); - - void on_zoomRange_clicked(); - void on_autoFit_clicked(); - void on_reset01_clicked(); - void on_visualiseRange_clicked(); - void on_backcolorPick_clicked(); - void on_checkerBack_clicked(); - - void on_locationGoto_clicked(); - void on_viewTexBuffer_clicked(); - void on_texListShow_clicked(); - void on_saveTex_clicked(); - void on_debugPixelContext_clicked(); - void on_pixelHistory_clicked(); - - void on_customCreate_clicked(); - void on_customEdit_clicked(); - void on_customDelete_clicked(); - - void on_cancelTextureListFilter_clicked(); - void on_textureListFilter_editTextChanged(const QString &text); - void on_textureListFilter_currentIndexChanged(int index); - void on_textureList_clicked(const QModelIndex &index); - - // manual slots - void render_mouseClick(QMouseEvent *e); - void render_mouseMove(QMouseEvent *e); - void render_mouseWheel(QWheelEvent *e); - void render_resize(QResizeEvent *e); - void render_keyPress(QKeyEvent *e); - - void textureTab_Changed(int index); - void textureTab_Closing(int index); - - void thumb_clicked(QMouseEvent *); - void thumb_doubleClicked(QMouseEvent *); - void texContextItem_triggered(); - void showDisabled_triggered(); - void showEmpty_triggered(); - - void zoomOption_returnPressed(); - - void range_rangeUpdated(); - void rangePoint_textChanged(QString text); - void rangePoint_leave(); - void rangePoint_keyPress(QKeyEvent *e); - - void customShaderModified(const QString &path); - - void channelsWidget_mouseClicked(QMouseEvent *event); - void channelsWidget_toggled(bool checked) { UI_UpdateChannels(); } - void channelsWidget_selected(int index) { UI_UpdateChannels(); } -private: - void RT_FetchCurrentPixel(uint32_t x, uint32_t y, PixelValue &pickValue, PixelValue &realValue); - void RT_PickPixelsAndUpdate(IReplayController *); - void RT_PickHoverAndUpdate(IReplayController *); - void RT_UpdateAndDisplay(IReplayController *); - void RT_UpdateVisualRange(IReplayController *); - - void UI_RecreatePanels(); - - void UI_UpdateStatusText(); - void UI_UpdateTextureDetails(); - void UI_OnTextureSelectionChanged(bool newdraw); - - void UI_SetHistogramRange(const TextureDescription *tex, CompType typeHint); - - void UI_UpdateChannels(); - - void SetupTextureTabs(); - - void Reset(); - - ResourcePreview *UI_CreateThumbnail(ThumbnailStrip *strip); - void UI_CreateThumbnails(); - void InitResourcePreview(ResourcePreview *prev, ResourceId id, CompType typeHint, bool force, - Following &follow, const QString &bindName, const QString &slotName); - - void InitStageResourcePreviews(ShaderStage stage, - const rdctype::array &resourceDetails, - const rdctype::array &mapping, - QMap> &ResList, - ThumbnailStrip *prevs, int &prevIndex, bool copy, bool rw); - - void AddResourceUsageEntry(QMenu &menu, uint32_t start, uint32_t end, ResourceUsage usage); - void OpenResourceContextMenu(ResourceId id, const rdctype::array &usage); - - void AutoFitRange(); - void rangePoint_Update(); - - bool currentTextureIsLocked() { return m_LockedId != ResourceId(); } - void setFitToWindow(bool checked); - - void setCurrentZoomValue(float zoom); - float getCurrentZoomValue(); - - bool ScrollUpdateScrollbars = true; - - float CurMaxScrollX(); - float CurMaxScrollY(); - - float GetFitScale(); - - int realRenderWidth() const; - int realRenderHeight() const; - - QPoint getScrollPosition(); - void setScrollPosition(const QPoint &pos); - - TextureDescription *GetCurrentTexture(); - void UI_UpdateCachedTexture(); - - void ShowGotoPopup(); - - void UI_UpdateFittedScale(); - void UI_SetScale(float s); - void UI_SetScale(float s, int x, int y); - void UI_CalcScrollbars(); - - QPoint m_DragStartScroll; - QPoint m_DragStartPos; - - QPoint m_CurHoverPixel; - QPoint m_PickedPoint; - - QSizeF m_PrevSize; - - PixelValue m_CurRealValue; - PixelValue m_CurPixelValue; - PixelValue m_CurHoverValue; - - QColor darkBack; - QColor lightBack; - - int m_HighWaterStatusLength = 0; - int m_PrevFirstArraySlice = -1; - int m_PrevHighestMip = -1; - - bool m_ShowEmpty = false; - bool m_ShowDisabled = false; - - bool m_Visualise = false; - bool m_NoRangePaint = false; - bool m_RangePoint_Dirty = false; - - ResourceId m_LockedId; - QMap m_LockedTabs; - - TextureGoto *m_Goto; - - Ui::TextureViewer *ui; - ICaptureContext &m_Ctx; - IReplayOutput *m_Output = NULL; - - TextureDescription *m_CachedTexture; - Following m_Following = Following::Default; - QMap m_TextureSettings; - - QFileSystemWatcher *m_Watcher = NULL; - QStringList m_CustomShadersBusy; - QMap m_CustomShaders; - QMap m_CustomShaderEditor; - - void reloadCustomShaders(const QString &filter); - - TextureDisplay m_TexDisplay; -}; diff --git a/qrenderdoc/Windows/TextureViewer.ui b/qrenderdoc/Windows/TextureViewer.ui deleted file mode 100644 index c90b1cbcb..000000000 --- a/qrenderdoc/Windows/TextureViewer.ui +++ /dev/null @@ -1,1305 +0,0 @@ - - - TextureViewer - - - - 0 - 0 - 775 - 571 - - - - Texture Viewer - - - - - 50 - 460 - 119 - 100 - - - - - 0 - 0 - - - - - 100 - 100 - - - - false - - - - - - 10 - 120 - 558 - 28 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 3 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Range - - - - - - - - 0 - 0 - - - - 0.0 - - - - - - - - 200 - 0 - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - 1.0 - - - - - - - - 0 - 0 - - - - Zoom the visible range controls to the current black and white points - - - - - - - :/zoom.png:/zoom.png - - - true - - - - - - - - 0 - 0 - - - - Automatically fit the black and white points of the range to the minimum and maximum values contained in the texture - - - - - - - :/wand.png:/wand.png - - - true - - - - - - - - 0 - 0 - - - - Reset to [0, 1] - - - ... - - - - :/arrow_undo.png:/arrow_undo.png - - - true - - - - - - - - 0 - 0 - - - - Show a histogram with the distribution of values on top of the visible range - - - ... - - - - :/chart_curve.png:/chart_curve.png - - - true - - - true - - - - - - - - - 490 - 40 - 129 - 28 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Overlay - - - - - - - 20 - - - - - - - - - 10 - 80 - 221 - 28 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Zoom - - - - - - - true - - - Reset the zoom to 100% - - - 1:1 - - - false - - - false - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - true - - - Fit the current texture to the window - - - Fit - - - - :/arrow_out.png:/arrow_out.png - - - true - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 70 - 0 - - - - true - - - QComboBox::NoInsert - - - - - - - Flip the texture in the Y axis - - - - - - - :/flip_y.png:/flip_y.png - - - true - - - true - - - - - - - - - 330 - 40 - 149 - 28 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Actions - - - - - - - Save selected Texture - - - - - - - :/save.png:/save.png - - - true - - - - - - - Open Texture List - - - - - - - :/page_white_link.png:/page_white_link.png - - - true - - - - - - - Open the texture contents in a raw buffer viewer - - - - - - - :/page_white_code.png:/page_white_code.png - - - true - - - - - - - Enter co-ordinates to select a specific pixel location - - - - - - - :/find.png:/find.png - - - true - - - - - - - - - 10 - 40 - 299 - 28 - - - - - 0 - 0 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Subresource - - - - - - - Qt::Vertical - - - - - - - Mip - - - - - - - 20 - - - QComboBox::AdjustToContents - - - - - - - Slice/Face - - - - - - - 20 - - - QComboBox::AdjustToContents - - - - - - - - - 3 - 3 - 696 - 28 - - - - - 0 - 0 - - - - - 0 - 28 - - - - QFrame::Panel - - - QFrame::Raised - - - - 2 - - - 6 - - - 2 - - - 6 - - - 2 - - - - - Channels - - - - - - - true - - - - - - - Qt::Vertical - - - - - - - Show Red (Right click to toggle solo) - - - R - - - true - - - true - - - true - - - - - - - Show Green (Right click to toggle solo) - - - G - - - true - - - true - - - true - - - - - - - Show Blue (Right click to toggle solo) - - - B - - - true - - - true - - - QToolButton::DelayedPopup - - - true - - - - - - - Show Alpha (Right click to toggle solo) - - - A - - - true - - - true - - - - - - - Qt::Vertical - - - - - - - Mul: - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - true - - - 128 - - - QComboBox::NoInsert - - - - - - - Depth - - - - - - - Stencil - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - true - - - QComboBox::NoInsert - - - - - - - Create New Custom Shader - - - - - - - :/add.png:/add.png - - - true - - - - - - - Edit Selected Shader - - - - - - - :/page_white_edit.png:/page_white_edit.png - - - true - - - - - - - Delete Custom Shader - - - - - - - :/del.png:/del.png - - - true - - - - - - - Alpha: Pick Solid Background Color - - - - - - - :/color_wheel.png:/color_wheel.png - - - true - - - true - - - - - - - Alpha: Show Checkerboard Background - - - - - - - :/checkerboard.png:/checkerboard.png - - - true - - - true - - - true - - - - - - - Qt::Vertical - - - - - - - - 23 - 22 - - - - Override display of linear data in gamma space - -See FAQ on "Gamma display of linear data" - - - γ - - - true - - - true - - - true - - - - - - - - - 250 - 220 - 291 - 231 - - - - - 0 - 0 - - - - - 100 - 100 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - - - - - Qt::Horizontal - - - - - - - - - - - - 0 - 0 - - - - - Consolas - - - - texStatusDim - - - - - - - - 0 - 0 - - - - - 32 - 14 - - - - - - - - - 0 - 0 - - - - - Consolas - - - - Status Text - - - - - - - - - - - 40 - 240 - 201 - 181 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - 0 - 0 - - - - - - - - History - - - - - - - Debug - - - - - - - - - - - 40 - 470 - 120 - 80 - - - - - - - 210 - 470 - 120 - 80 - - - - - - - 550 - 210 - 221 - 244 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - 6 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - 0 - - - - - - 0 - 0 - - - - true - - - - - - - - - - - :/cross.png:/cross.png - - - true - - - - - - - - - QFrame::Box - - - QFrame::Sunken - - - QAbstractItemView::NoEditTriggers - - - false - - - Qt::CopyAction - - - QAbstractItemView::NoSelection - - - QListView::ListMode - - - true - - - - - - - - - RDLineEdit - QLineEdit -
Widgets/Extended/RDLineEdit.h
-
- - ToolWindowManager - QWidget -
3rdparty/toolwindowmanager/ToolWindowManager.h
-
- - CustomPaintWidget - QWidget -
Widgets/CustomPaintWidget.h
-
- - ThumbnailStrip - QWidget -
Widgets/ThumbnailStrip.h
- 1 -
- - RDListView - QListView -
Widgets/Extended/RDListView.h
-
- - RangeHistogram - QWidget -
Widgets/RangeHistogram.h
- 1 -
- - RDToolButton - QToolButton -
Widgets/Extended/RDToolButton.h
-
-
- - - - -
diff --git a/qrenderdoc/Windows/TimelineBar.cpp b/qrenderdoc/Windows/TimelineBar.cpp deleted file mode 100644 index deaf74733..000000000 --- a/qrenderdoc/Windows/TimelineBar.cpp +++ /dev/null @@ -1,971 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "TimelineBar.h" -#include -#include -#include -#include -#include "Code/Resources.h" - -QPointF aliasAlign(QPointF pt) -{ - pt.setX(int(pt.x()) + 0.5); - pt.setY(int(pt.y()) + 0.5); - return pt; -} - -QMarginsF uniformMargins(qreal m) -{ - return QMarginsF(m, m, m, m); -} - -QMargins uniformMargins(int m) -{ - return QMargins(m, m, m, m); -} - -TimelineBar::TimelineBar(ICaptureContext &ctx, QWidget *parent) - : QAbstractScrollArea(parent), m_Ctx(ctx) -{ - m_Ctx.AddLogViewer(this); - - setMouseTracking(true); - - setFrameShape(NoFrame); - - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - QObject::connect(horizontalScrollBar(), &QScrollBar::valueChanged, - [this](int value) { m_pan = -value; }); - - setWindowTitle(tr("Timeline")); -} - -TimelineBar::~TimelineBar() -{ - m_Ctx.BuiltinWindowClosed(this); - - m_Ctx.RemoveLogViewer(this); -} - -void TimelineBar::HighlightResourceUsage(ResourceId id) -{ - m_UsageEvents.clear(); - - TextureDescription *tex = m_Ctx.GetTexture(id); - - if(tex) - m_UsageTarget = ToQStr(tex->name); - - BufferDescription *buf = m_Ctx.GetBuffer(id); - - if(buf) - m_UsageTarget = ToQStr(buf->name); - - m_Ctx.Replay().AsyncInvoke([this, id](IReplayController *r) { - rdctype::array usage = r->GetUsage(id); - - GUIInvoke::call([this, usage]() { - for(const EventUsage &u : usage) - m_UsageEvents << u; - viewport()->update(); - }); - }); - - viewport()->update(); -} - -void TimelineBar::HighlightHistory(ResourceId id, const QList &history) -{ - m_HistoryTarget = QString(); - m_HistoryEvents.clear(); - - if(id != ResourceId()) - { - TextureDescription *tex = m_Ctx.GetTexture(id); - - if(tex) - m_HistoryTarget = ToQStr(tex->name); - - BufferDescription *buf = m_Ctx.GetBuffer(id); - - if(buf) - m_HistoryTarget = ToQStr(buf->name); - - for(const PixelModification &mod : history) - m_HistoryEvents << mod; - } - - viewport()->update(); -} - -void TimelineBar::OnLogfileClosed() -{ - setWindowTitle(tr("Timeline")); - - m_Draws.clear(); - m_RootDraws.clear(); - m_RootMarkers.clear(); - - layout(); -} - -void TimelineBar::OnLogfileLoaded() -{ - setWindowTitle(tr("Timeline - Frame #%1").arg(m_Ctx.FrameInfo().frameNumber)); - - processDraws(m_RootMarkers, m_RootDraws, m_Ctx.CurDrawcalls()); - - m_zoom = 1.0; - m_pan = 0.0; - m_lastPos = QPointF(); - - layout(); -} - -void TimelineBar::OnEventChanged(uint32_t eventID) -{ - viewport()->update(); -} - -QSize TimelineBar::minimumSizeHint() const -{ - return QSize(margin * 4 + borderWidth * 2 + 100, - margin * 4 + borderWidth * 2 + m_eidAxisRect.height() * 2 + - m_highlightingRect.height() + horizontalScrollBar()->sizeHint().height()); -} - -void TimelineBar::resizeEvent(QResizeEvent *e) -{ - layout(); -} - -void TimelineBar::layout() -{ - QFontMetrics fm(Formatter::PreferredFont()); - - // the area of everything - m_area = QRectF(viewport()->rect()).marginsRemoved(uniformMargins(borderWidth + margin)); - - m_titleWidth = fm.width(eidAxisTitle) + fm.height(); - - m_dataArea = m_area; - m_dataArea.setLeft(m_dataArea.left() + m_titleWidth); - - m_eidAxisRect = m_dataArea.marginsRemoved(uniformMargins(margin)); - m_eidAxisRect.setHeight(qMax(fm.height(), dataBarHeight)); - - m_markerRect = m_dataArea.marginsRemoved(uniformMargins(margin)); - m_markerRect.setTop(m_eidAxisRect.bottom() + margin); - - m_highlightingRect = m_area; - m_highlightingRect.setHeight(qMax(fm.height(), dataBarHeight) + highlightingExtra); - m_highlightingRect.moveTop(m_markerRect.bottom() - m_highlightingRect.height()); - - m_markerRect.setBottom(m_highlightingRect.top()); - - uint32_t maxEID = m_Draws.isEmpty() ? 0 : m_Draws.back(); - - int stepSize = 1; - int stepMagnitude = 1; - - m_eidAxisLabelTextWidth = fm.width(QString::number(maxEID)); - m_eidAxisLabelWidth = m_eidAxisLabelTextWidth + fm.height(); - m_eidAxisLabelStep = stepSize * stepMagnitude; - - qreal virtualSize = m_dataArea.width() * m_zoom; - - while(virtualSize > 0 && (maxEID / m_eidAxisLabelStep) * m_eidAxisLabelWidth > virtualSize) - { - // increment 1, 2, 5, 10, 20, 50, 100, ... - if(stepSize == 1) - { - stepSize = 2; - } - else if(stepSize == 2) - { - stepSize = 5; - } - else if(stepSize == 5) - { - stepSize = 1; - stepMagnitude *= 10; - } - - m_eidAxisLabelStep = stepSize * stepMagnitude; - } - - int numLabels = maxEID / m_eidAxisLabelStep + 1; - - m_eidAxisLabelWidth = virtualSize / numLabels; - - m_eidWidth = virtualSize / (maxEID + 1); - - int savedPan = m_pan; - - horizontalScrollBar()->setRange(0, virtualSize - m_dataArea.width()); - horizontalScrollBar()->setSingleStep(m_eidAxisLabelWidth); - horizontalScrollBar()->setPageStep(m_dataArea.width()); - horizontalScrollBar()->setValue(-savedPan); - - viewport()->update(); -} - -void TimelineBar::mousePressEvent(QMouseEvent *e) -{ - m_lastPos = e->localPos(); - - qreal x = e->localPos().x(); - - if((e->modifiers() & Qt::AltModifier) == 0) - { - Marker *marker = findMarker(m_RootMarkers, m_markerRect, m_lastPos); - if(marker) - { - marker->expanded = !marker->expanded; - m_lastPos = QPointF(); - viewport()->update(); - return; - } - - if(m_highlightingRect.contains(m_lastPos)) - { - uint32_t eid = eventAt(x); - - m_lastPos = QPointF(); - - // history events get first crack at any selection, if they exist - if(!m_HistoryEvents.isEmpty()) - { - auto it = std::find_if(m_HistoryEvents.begin(), m_HistoryEvents.end(), - [this, eid](const PixelModification &mod) { - if(mod.eventID == eid) - return true; - - return false; - }); - - if(it != m_HistoryEvents.end()) - m_Ctx.SetEventID({}, eid, eid); - - return; - } - - if(!m_UsageEvents.isEmpty()) - { - auto it = std::find_if(m_UsageEvents.begin(), m_UsageEvents.end(), - [this, eid](const EventUsage &use) { - if(use.eventID == eid) - return true; - - return false; - }); - - if(it != m_UsageEvents.end()) - m_Ctx.SetEventID({}, eid, eid); - } - - return; - } - - if(!m_Draws.isEmpty() && m_dataArea.contains(m_lastPos)) - { - uint32_t eid = eventAt(x); - auto it = std::find_if(m_Draws.begin(), m_Draws.end(), [this, eid](uint32_t d) { - if(d >= eid) - return true; - - return false; - }); - - if(it == m_Draws.end()) - m_Ctx.SetEventID({}, m_Draws.back(), m_Draws.back()); - else - m_Ctx.SetEventID({}, *it, *it); - } - } -} - -void TimelineBar::mouseReleaseEvent(QMouseEvent *e) -{ -} - -void TimelineBar::mouseMoveEvent(QMouseEvent *e) -{ - if(e->buttons() == Qt::LeftButton && m_lastPos != QPointF()) - { - qreal x = e->localPos().x(); - - if(e->modifiers() & Qt::AltModifier) - { - qreal delta = x - m_lastPos.x(); - m_pan += delta; - - m_pan = qBound(-m_eidAxisRect.width() * (m_zoom - 1.0), m_pan, 0.0); - - layout(); - } - else if(!m_Draws.isEmpty() && m_dataArea.contains(e->localPos())) - { - uint32_t eid = eventAt(x); - if(m_Draws.contains(eid) && eid != m_Ctx.CurEvent()) - m_Ctx.SetEventID({}, eid, eid); - } - } - else - { - viewport()->update(); - } - - m_lastPos = e->localPos(); - - Marker *marker = findMarker(m_RootMarkers, m_markerRect, m_lastPos); - if(marker) - setCursor(Qt::PointingHandCursor); - else - unsetCursor(); -} - -void TimelineBar::wheelEvent(QWheelEvent *e) -{ - float mod = (1.0 + e->delta() / 2500.0f); - - qreal prevZoom = m_zoom; - - m_zoom = qMax(1.0, m_zoom * mod); - - qreal zoomDelta = (m_zoom / prevZoom); - - // adjust the pan so that it's still in bounds, and so the zoom acts centred on the mouse - qreal newPan = m_pan; - - newPan -= (e->x() - m_eidAxisRect.left()); - newPan = newPan * zoomDelta; - newPan += (e->x() - m_eidAxisRect.left()); - - m_pan = qBound(-m_dataArea.width() * (m_zoom - 1.0), newPan, 0.0); - - e->accept(); - - layout(); -} - -void TimelineBar::leaveEvent(QEvent *e) -{ - unsetCursor(); - viewport()->update(); -} - -void TimelineBar::paintEvent(QPaintEvent *e) -{ - QPainter p(viewport()); - - p.setFont(font()); - p.setRenderHint(QPainter::TextAntialiasing); - - // draw boundaries and background - { - QRectF r = viewport()->rect(); - - p.fillRect(r, palette().brush(QPalette::Window)); - - r = r.marginsRemoved(QMargins(borderWidth + margin, borderWidth + margin, borderWidth + margin, - borderWidth + margin)); - - p.fillRect(r, palette().brush(QPalette::Base)); - p.drawRect(r); - } - - QTextOption to; - - to.setWrapMode(QTextOption::NoWrap); - to.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - - QFontMetrics fm = p.fontMetrics(); - - { - QRectF titleRect = m_eidAxisRect; - titleRect.setLeft(titleRect.left() - m_titleWidth); - titleRect.setWidth(m_titleWidth); - - p.setPen(QPen(palette().brush(QPalette::Text), 1.0)); - - // add an extra margin for the text - p.drawText(titleRect.marginsRemoved(QMarginsF(margin, 0, 0, 0)), eidAxisTitle, to); - - titleRect.setLeft(titleRect.left() - margin); - titleRect.setTop(titleRect.top() - margin); - p.drawLine(titleRect.bottomLeft(), titleRect.bottomRight()); - p.drawLine(titleRect.topRight(), titleRect.bottomRight()); - } - - QRectF eidAxisRect = m_eidAxisRect; - - p.drawLine(eidAxisRect.bottomLeft(), eidAxisRect.bottomRight() + QPointF(margin, 0)); - - p.drawLine(m_highlightingRect.topLeft(), m_highlightingRect.topRight()); - - if(m_Draws.isEmpty()) - return; - - eidAxisRect.setLeft(m_eidAxisRect.left() + m_pan); - - uint32_t maxEID = m_Draws.isEmpty() ? 0 : m_Draws.back(); - - to.setAlignment(Qt::AlignCenter | Qt::AlignVCenter); - - p.setFont(Formatter::PreferredFont()); - - QRectF hoverRect = eidAxisRect; - - // clip labels to the visible section - p.setClipRect(m_eidAxisRect.marginsAdded(QMargins(0, margin, margin, 0))); - - // draw where we're hovering - { - QPoint pos = viewport()->mapFromGlobal(QCursor::pos()); - - if(m_dataArea.contains(pos)) - { - uint32_t hoverEID = eventAt(pos.x()); - - hoverRect.setLeft(offsetOf(hoverEID)); - hoverRect.setWidth(m_eidAxisLabelWidth); - - // recentre - hoverRect.moveLeft(hoverRect.left() - m_eidAxisLabelWidth / 2 + m_eidWidth / 2); - - QColor backCol = palette().color(QPalette::Base); - - if(getLuminance(backCol) < 0.2f) - backCol = backCol.lighter(120); - else - backCol = backCol.darker(120); - - QRectF backRect = hoverRect.marginsAdded(QMargins(0, margin - borderWidth, 0, 0)); - - backRect.setLeft(qMax(backRect.left(), m_eidAxisRect.left() + 1)); - - p.fillRect(backRect, backCol); - - p.drawText(hoverRect, QString::number(hoverEID), to); - - // re-add the top margin so the lines match up with the border around the EID axis - hoverRect = hoverRect.marginsAdded(QMargins(0, margin, 0, 0)); - - if(hoverRect.left() >= m_eidAxisRect.left()) - p.drawLine(hoverRect.topLeft(), hoverRect.bottomLeft()); - p.drawLine(hoverRect.topRight(), hoverRect.bottomRight()); - - // shrink the rect a bit for clipping against labels below - hoverRect.setX(qRound(hoverRect.x() + 0.5)); - hoverRect.setWidth(int(hoverRect.width())); - } - else - { - hoverRect = QRectF(); - } - } - - QRectF labelRect = eidAxisRect; - labelRect.setWidth(m_eidAxisLabelWidth); - - // iterate through the EIDs from 0, starting from possible a negative offset if the user has - // panned to the right. - for(uint32_t i = 0; i <= maxEID; i += m_eidAxisLabelStep) - { - labelRect.moveLeft(offsetOf(i) - labelRect.width() / 2 + m_eidWidth / 2); - - // check if this label is visible at all, but don't draw labels that intersect with the hovered - // number - if(labelRect.right() >= 0 && !labelRect.intersects(hoverRect)) - p.drawText(labelRect, QString::number(i), to); - - // check if labelRect is off the edge of the screen - if(labelRect.left() >= m_eidAxisRect.right()) - break; - } - - // stop clipping - p.setClipRect(viewport()->rect()); - - // clip the markers - p.setClipRect(m_markerRect); - - { - QPen pen = p.pen(); - paintMarkers(p, m_RootMarkers, m_RootDraws, m_markerRect); - p.setPen(pen); - } - - // stop clipping - p.setClipRect(viewport()->rect()); - - QRectF currentRect = eidAxisRect; - - // draw the current label and line - { - uint32_t curEID = m_Ctx.CurEvent(); - - currentRect.setLeft(offsetOf(curEID)); - currentRect.setWidth( - qMax(m_eidAxisLabelWidth, m_eidAxisLabelTextWidth + dataBarHeight + margin * 2)); - - // recentre - currentRect.moveLeft(currentRect.left() - currentRect.width() / 2 + m_eidWidth / 2); - - // remember where the middle would have been, without clamping - qreal realMiddle = currentRect.center().x(); - - // clamp the position from the left or right side - if(currentRect.left() < eidAxisRect.left()) - currentRect.moveLeft(eidAxisRect.left()); - else if(currentRect.right() > eidAxisRect.right()) - currentRect.moveRight(eidAxisRect.right()); - - // re-add the top margin so the lines match up with the border around the EID axis - QRectF currentBackRect = currentRect.marginsAdded(QMargins(0, margin, 0, 0)); - - p.fillRect(currentBackRect, palette().brush(QPalette::Base)); - p.drawRect(currentBackRect); - - // draw the 'current marker' pixmap - const QPixmap &px = Pixmaps::flag_green(devicePixelRatio()); - p.drawPixmap(currentRect.topLeft() + QPointF(margin, 1), px, px.rect()); - - // move to where the text should be and draw it - currentRect.setLeft(currentRect.left() + margin * 2 + dataBarHeight); - p.drawText(currentRect, QString::number(curEID), to); - - // draw a line from the bottom of the shadow downwards - QPointF currentTop = currentRect.center(); - currentTop.setX(int(qBound(eidAxisRect.left(), realMiddle, eidAxisRect.right() - 2.0)) + 0.5); - currentTop.setY(currentRect.bottom()); - - QPointF currentBottom = currentTop; - currentBottom.setY(m_markerRect.bottom()); - - p.drawLine(currentTop, currentBottom); - } - - to.setAlignment(Qt::AlignLeft | Qt::AlignTop); - - if(!m_UsageTarget.isEmpty() || !m_HistoryTarget.isEmpty()) - { - p.setRenderHint(QPainter::Antialiasing); - - QRectF highlightLabel = m_highlightingRect.marginsRemoved(uniformMargins(margin)); - - highlightLabel.setX(highlightLabel.x() + margin); - - QString text; - - if(!m_HistoryTarget.isEmpty()) - text = tr("Pixel history for %1").arg(m_HistoryTarget); - else - text = tr("Usage for %1:").arg(m_UsageTarget); - - p.drawText(highlightLabel, text, to); - - const int triRadius = fm.averageCharWidth(); - const int triHeight = fm.ascent(); - - QPainterPath triangle; - triangle.addPolygon( - QPolygonF({QPoint(0, triHeight), QPoint(triRadius * 2, triHeight), QPoint(triRadius, 0)})); - triangle.closeSubpath(); - - enum - { - ReadUsage, - WriteUsage, - ReadWriteUsage, - ClearUsage, - BarrierUsage, - - HistoryPassed, - HistoryFailed, - - UsageCount, - }; - - const QColor colors[UsageCount] = { - // read - QColor(Qt::red), - // write - QColor(Qt::green), - // read/write - QColor(Qt::yellow), - // clear - QColor(Qt::blue), - // barrier - QColor(Qt::magenta), - - // pass - QColor(Qt::green), - // fail - QColor(Qt::red), - }; - - // draw the key - if(m_HistoryTarget.isEmpty()) - { - // advance past the first text to draw the key - highlightLabel.setLeft(highlightLabel.left() + fm.width(text)); - - text = lit(" Reads, "); - p.drawText(highlightLabel, text, to); - highlightLabel.setLeft(highlightLabel.left() + fm.width(text)); - - QPainterPath path = triangle.translated(aliasAlign(highlightLabel.topLeft())); - p.fillPath(path, colors[ReadUsage]); - p.drawPath(path); - highlightLabel.setLeft(highlightLabel.left() + triRadius * 2); - - text = lit(" Writes, "); - p.drawText(highlightLabel, text, to); - highlightLabel.setLeft(highlightLabel.left() + fm.width(text)); - - path = triangle.translated(aliasAlign(highlightLabel.topLeft())); - p.fillPath(path, colors[WriteUsage]); - p.drawPath(path); - highlightLabel.setLeft(highlightLabel.left() + triRadius * 2); - - text = lit(" Read/Write, "); - p.drawText(highlightLabel, text, to); - highlightLabel.setLeft(highlightLabel.left() + fm.width(text)); - - path = triangle.translated(aliasAlign(highlightLabel.topLeft())); - p.fillPath(path, colors[ReadWriteUsage]); - p.drawPath(path); - highlightLabel.setLeft(highlightLabel.left() + triRadius * 2); - - if(m_Ctx.CurPipelineState().SupportsBarriers()) - { - text = lit(" Barriers, "); - p.drawText(highlightLabel, text, to); - highlightLabel.setLeft(highlightLabel.left() + fm.width(text)); - - path = triangle.translated(aliasAlign(highlightLabel.topLeft())); - p.fillPath(path, colors[BarrierUsage]); - p.drawPath(path); - highlightLabel.setLeft(highlightLabel.left() + triRadius * 2); - } - - text = lit(" and Clears "); - p.drawText(highlightLabel, text, to); - highlightLabel.setLeft(highlightLabel.left() + fm.width(text)); - - path = triangle.translated(aliasAlign(highlightLabel.topLeft())); - p.fillPath(path, colors[ClearUsage]); - p.drawPath(path); - highlightLabel.setLeft(highlightLabel.left() + triRadius * 2); - } - - QPainterPath paths[UsageCount]; - - QRectF pipsRect = m_highlightingRect.marginsRemoved(uniformMargins(margin)); - - pipsRect.setX(pipsRect.x() + margin + m_titleWidth); - pipsRect.setHeight(triHeight + margin); - pipsRect.moveBottom(m_highlightingRect.bottom()); - - p.setClipRect(pipsRect); - - if(!m_HistoryEvents.isEmpty()) - { - for(const PixelModification &mod : m_HistoryEvents) - { - QPointF pos; - - pos.setX(offsetOf(mod.eventID) + m_eidWidth / 2 - triRadius); - pos.setY(pipsRect.y()); - - QPainterPath path = triangle.translated(aliasAlign(pos)); - - if(mod.passed()) - paths[HistoryPassed] = paths[HistoryPassed].united(path); - else - paths[HistoryFailed] = paths[HistoryFailed].united(path); - } - } - else - { - for(const EventUsage &use : m_UsageEvents) - { - QPointF pos; - - pos.setX(offsetOf(use.eventID) + m_eidWidth / 2 - triRadius); - pos.setY(pipsRect.y()); - - QPainterPath path = triangle.translated(aliasAlign(pos)); - - if(((int)use.usage >= (int)ResourceUsage::VS_RWResource && - (int)use.usage <= (int)ResourceUsage::All_RWResource) || - use.usage == ResourceUsage::GenMips || use.usage == ResourceUsage::Copy || - use.usage == ResourceUsage::Resolve) - { - paths[ReadWriteUsage] = paths[ReadWriteUsage].united(path); - } - else if(use.usage == ResourceUsage::StreamOut || use.usage == ResourceUsage::ResolveDst || - use.usage == ResourceUsage::ColorTarget || use.usage == ResourceUsage::CopyDst) - { - paths[WriteUsage] = paths[WriteUsage].united(path); - } - else if(use.usage == ResourceUsage::Clear) - { - paths[ClearUsage] = paths[ClearUsage].united(path); - } - else if(use.usage == ResourceUsage::Barrier) - { - paths[BarrierUsage] = paths[BarrierUsage].united(path); - } - else - { - paths[ReadUsage] = paths[ReadUsage].united(path); - } - } - } - - for(int i = 0; i < UsageCount; i++) - { - if(!paths[i].isEmpty()) - { - p.drawPath(paths[i]); - p.fillPath(paths[i], colors[i]); - } - } - } - else - { - QRectF highlightLabel = m_highlightingRect; - highlightLabel = highlightLabel.marginsRemoved(uniformMargins(margin)); - - highlightLabel.setX(highlightLabel.x() + margin); - - p.drawText(highlightLabel, tr("No resource selected for highlighting."), to); - } -} - -TimelineBar::Marker *TimelineBar::findMarker(QVector &markers, QRectF markerRect, QPointF pos) -{ - QFontMetrics fm(Formatter::PreferredFont()); - - for(Marker &m : markers) - { - QRectF r = markerRect; - r.setLeft(qMax(m_markerRect.left() + borderWidth * 2, offsetOf(m.eidStart))); - r.setRight(qMin(m_markerRect.right() - borderWidth, offsetOf(m.eidEnd + 1))); - r.setHeight(fm.height() + borderWidth * 2); - - if(r.width() <= borderWidth * 2) - continue; - - if(r.contains(pos)) - { - return &m; - } - - if(!m.children.isEmpty() && m.expanded) - { - QRectF childRect = r; - childRect.setTop(r.bottom() + borderWidth * 2); - childRect.setBottom(markerRect.bottom()); - - Marker *res = findMarker(m.children, childRect, pos); - - if(res) - return res; - } - } - - return NULL; -} - -void TimelineBar::paintMarkers(QPainter &p, const QVector &markers, - const QVector &draws, QRectF markerRect) -{ - if(markers.isEmpty() && draws.isEmpty()) - return; - - QTextOption to; - - to.setWrapMode(QTextOption::NoWrap); - to.setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - - QFontMetrics fm(Formatter::PreferredFont()); - - // store a reference of what a completely elided string looks like - QString tooshort = fm.elidedText(lit("asd"), Qt::ElideRight, fm.height()); - - for(const Marker &m : markers) - { - QRectF r = markerRect; - r.setLeft(qMax(m_dataArea.left() + borderWidth * 3, offsetOf(m.eidStart))); - r.setRight(qMin(m_dataArea.right() - borderWidth, offsetOf(m.eidEnd + 1))); - r.setHeight(fm.height() + borderWidth * 2); - - if(r.width() <= borderWidth * 2) - continue; - - QColor backColor = m.color; - if(r.contains(m_lastPos)) - backColor.setAlpha(150); - - p.setPen(QPen(palette().brush(QPalette::Text), 1.0)); - p.fillRect(r, QBrush(backColor)); - p.drawRect(r); - - p.setPen(QPen(QBrush(contrastingColor(backColor, palette().color(QPalette::Text))), 1.0)); - - r.setLeft(r.left() + margin); - - int plusWidth = fm.width(QLatin1Char('+')); - if(r.width() > plusWidth) - { - QRectF plusRect = r; - plusRect.setWidth(plusWidth); - - QTextOption plusOption = to; - plusOption.setAlignment(Qt::AlignCenter | Qt::AlignVCenter); - - p.drawText(plusRect, m.expanded ? lit("-") : lit("+"), plusOption); - - r.setLeft(r.left() + plusWidth + margin); - } - - QString elided = fm.elidedText(m.name, Qt::ElideRight, r.width()); - - // if everything was elided, just omit the title entirely - if(elided == tooshort) - elided = QString(); - - QRectF textRect = r; - r.setLeft(qRound(r.left() + margin)); - - p.drawText(r, elided, to); - - if(m.expanded) - { - QRectF childRect = r; - childRect.setTop(r.bottom() + borderWidth * 2); - childRect.setBottom(markerRect.bottom()); - - paintMarkers(p, m.children, m.draws, childRect); - } - } - - p.setRenderHint(QPainter::Antialiasing); - - for(uint32_t d : draws) - { - QRectF r = markerRect; - r.setLeft(qMax(m_dataArea.left() + borderWidth * 3, offsetOf(d))); - r.setRight(qMin(m_dataArea.right() - borderWidth, offsetOf(d + 1))); - r.setHeight(fm.height() + borderWidth * 2); - - QPainterPath path; - path.addRoundedRect(r, 5, 5); - - p.setPen(QPen(palette().brush(QPalette::Text), 1.0)); - p.fillPath(path, Qt::blue); - p.drawPath(path); - } - - p.setRenderHint(QPainter::Antialiasing, false); -} - -uint32_t TimelineBar::eventAt(qreal x) -{ - if(m_Draws.isEmpty()) - return 0; - - // clamp to the visible viewport - x = qBound(m_eidAxisRect.left(), x, m_eidAxisRect.right()); - - // do the reverse of offsetOf() - first make the x relative to the root - x -= m_pan + m_eidAxisRect.left(); - - // multiply up to get a floating point 'steps' - qreal steps = x / m_eidAxisLabelWidth; - - // finally convert to EID and clamp - uint32_t maxEID = m_Draws.back(); - return qMin(maxEID, uint32_t(steps * m_eidAxisLabelStep)); -} - -qreal TimelineBar::offsetOf(uint32_t eid) -{ - int steps = eid / m_eidAxisLabelStep; - - qreal fractionalPart = qreal(eid % m_eidAxisLabelStep) / qreal(m_eidAxisLabelStep); - - return m_eidAxisRect.left() + m_pan + steps * m_eidAxisLabelWidth + - fractionalPart * m_eidAxisLabelWidth; -} - -uint32_t TimelineBar::processDraws(QVector &markers, QVector &draws, - const rdctype::array &curDraws) -{ - uint32_t maxEID = 0; - - for(const DrawcallDescription &d : curDraws) - { - if(d.children.count > 0) - { - markers.push_back(Marker()); - Marker &m = markers.back(); - - m.name = ToQStr(d.name); - m.eidStart = d.eventID; - m.eidEnd = processDraws(m.children, m.draws, d.children); - - maxEID = qMax(maxEID, m.eidEnd); - - if(d.markerColor[3] > 0.0f) - { - m.color = QColor::fromRgb( - qRgb(d.markerColor[0] * 255.0f, d.markerColor[1] * 255.0f, d.markerColor[2] * 255.0f)); - } - else - { - m.color = QColor(Qt::gray); - } - } - else - { - if((d.flags & (DrawFlags::SetMarker | DrawFlags::APICalls)) != DrawFlags::SetMarker) - { - m_Draws.push_back(d.eventID); - draws.push_back(d.eventID); - } - } - - maxEID = qMax(maxEID, d.eventID); - } - - return maxEID; -} diff --git a/qrenderdoc/Windows/TimelineBar.h b/qrenderdoc/Windows/TimelineBar.h deleted file mode 100644 index 11566b3c4..000000000 --- a/qrenderdoc/Windows/TimelineBar.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -#include -#include "Code/CaptureContext.h" - -class TimelineBar : public QAbstractScrollArea, public ITimelineBar, public ILogViewer -{ - Q_OBJECT - -public: - explicit TimelineBar(ICaptureContext &ctx, QWidget *parent = 0); - ~TimelineBar(); - - QSize minimumSizeHint() const override; - - // IStatisticsViewer - QWidget *Widget() override { return this; } - void HighlightResourceUsage(ResourceId id) override; - void HighlightHistory(ResourceId id, const QList &history) override; - // ILogViewerForm - void OnLogfileLoaded() override; - void OnLogfileClosed() override; - void OnSelectedEventChanged(uint32_t eventID) override {} - void OnEventChanged(uint32_t eventID) override; - -protected: - void mousePressEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - void mouseMoveEvent(QMouseEvent *e) override; - void wheelEvent(QWheelEvent *e) override; - void leaveEvent(QEvent *e) override; - void paintEvent(QPaintEvent *e) override; - void resizeEvent(QResizeEvent *e) override; - -private: - ICaptureContext &m_Ctx; - - struct Marker - { - uint32_t eidStart = 0, eidEnd = 0; - - QString name; - QColor color; - bool expanded = false; - - QVector children; - QVector draws; - }; - - QVector m_RootMarkers; - QVector m_RootDraws; - QVector m_Draws; - - QString m_HistoryTarget; - QList m_HistoryEvents; - - QString m_UsageTarget; - QList m_UsageEvents; - - const qreal margin = 2.0; - const qreal borderWidth = 1.0; - const QString eidAxisTitle = lit("EID:"); - const int dataBarHeight = 18; - const int highlightingExtra = 12; - - int m_eidAxisLabelStep = 0; - qreal m_eidAxisLabelTextWidth = 0; - qreal m_eidAxisLabelWidth = 0; - qreal m_eidWidth = 0; - - QRectF m_area; - QRectF m_dataArea; - QRectF m_eidAxisRect; - QRectF m_markerRect; - QRectF m_highlightingRect; - qreal m_titleWidth = 0; - - qreal m_zoom = 1.0; - qreal m_pan = 0.0; - QPointF m_lastPos; - - void layout(); - - uint32_t eventAt(qreal x); - qreal offsetOf(uint32_t eid); - uint32_t processDraws(QVector &markers, QVector &draws, - const rdctype::array &curDraws); - void paintMarkers(QPainter &p, const QVector &markers, const QVector &draws, - QRectF markerRect); - Marker *findMarker(QVector &markers, QRectF markerRect, QPointF pos); -}; diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro deleted file mode 100644 index 5a8123b6d..000000000 --- a/qrenderdoc/qrenderdoc.pro +++ /dev/null @@ -1,354 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2015-03-18T20:10:50 -# -#------------------------------------------------- - -QT += core gui widgets svg - -CONFIG += silent - -lessThan(QT_MAJOR_VERSION, 5): error("requires Qt 5") - -equals(QT_MAJOR_VERSION, 5): lessThan(QT_MINOR_VERSION, 6): error("requires Qt 5.6") - -TARGET = qrenderdoc -TEMPLATE = app - -# include path for core renderdoc API -INCLUDEPATH += $$_PRO_FILE_PWD_/../renderdoc/api/replay - -# Allow includes relative to the root -INCLUDEPATH += $$_PRO_FILE_PWD_/ - -# For ToolWindowManager -INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/toolwindowmanager -# For FlowLayout -INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/flowlayout -# For Scintilla -INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/scintilla/include/qt -INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/scintilla/include - -# Disable conversions to/from const char * in QString -DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII - -# Different output folders per platform -win32 { - - RC_INCLUDEPATH = $$_PRO_FILE_PWD_/../renderdoc/api/replay - RC_FILE = Resources/qrenderdoc.rc - - # generate pdb files even in release - QMAKE_LFLAGS_RELEASE+=/MAP - QMAKE_CFLAGS_RELEASE += /Zi - QMAKE_LFLAGS_RELEASE +=/debug /opt:ref - - !contains(QMAKE_TARGET.arch, x86_64) { - Debug:DESTDIR = $$_PRO_FILE_PWD_/../Win32/Development - Release:DESTDIR = $$_PRO_FILE_PWD_/../Win32/Release - } else { - Debug:DESTDIR = $$_PRO_FILE_PWD_/../x64/Development - Release:DESTDIR = $$_PRO_FILE_PWD_/../x64/Release - } - - # Run SWIG here, since normally we run it from VS - swig.name = SWIG ${QMAKE_FILE_IN} - swig.input = SWIGSOURCES - swig.output = ${QMAKE_FILE_BASE}_python.cxx - swig.commands = $$_PRO_FILE_PWD_/3rdparty/swig/swig.exe -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I$$_PRO_FILE_PWD_ -I$$_PRO_FILE_PWD_/../renderdoc/api/replay -outdir . -o ${QMAKE_FILE_BASE}_python.cxx ${QMAKE_FILE_IN} - swig.CONFIG += target_predeps - swig.variable_out = GENERATED_SOURCES - silent:swig.commands = @echo SWIG ${QMAKE_FILE_IN} && $$swig.commands - QMAKE_EXTRA_COMPILERS += swig - - # windows only qrc file with qt.conf - RESOURCES += Resources/qtconf.qrc - - SWIGSOURCES += Code/pyrenderdoc/renderdoc.i - SWIGSOURCES += Code/pyrenderdoc/qrenderdoc.i - - # Embed renderdoc.py and qrenderdoc.py - RC_DEFINES = RENDERDOC_PY_PATH=renderdoc.py - RC_DEFINES += QRENDERDOC_PY_PATH=qrenderdoc.py - - # Include and link against python - INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/python/include - !contains(QMAKE_TARGET.arch, x86_64) { - LIBS += $$_PRO_FILE_PWD_/3rdparty/python/Win32/python36.lib - } else { - LIBS += $$_PRO_FILE_PWD_/3rdparty/python/x64/python36.lib - } - - # Include and link against PySide2 - DEFINES += PYSIDE2_ENABLED=1 - INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/pyside/include/shiboken2 - INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/pyside/include/PySide2 - INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/pyside/include/PySide2/QtCore - INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/pyside/include/PySide2/QtGui - INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/pyside/include/PySide2/QtWidgets - !contains(QMAKE_TARGET.arch, x86_64) { - LIBS += $$_PRO_FILE_PWD_/3rdparty/pyside/Win32/shiboken2.lib - } else { - LIBS += $$_PRO_FILE_PWD_/3rdparty/pyside/x64/shiboken2.lib - } - - # Link against the core library - LIBS += $$DESTDIR/renderdoc.lib - - QMAKE_CXXFLAGS_WARN_ON -= -w34100 - DEFINES += RENDERDOC_PLATFORM_WIN32 - -} else { - isEmpty(CMAKE_DIR) { - error("When run from outside CMake, please set the Build Environment Variable CMAKE_DIR to point to your CMake build root. In Qt Creator add CMAKE_DIR=/path/to/renderdoc/build under 'Additional arguments' in the qmake Build Step. If running qmake directly, add CMAKE_DIR=/path/to/renderdoc/build/ to the command line.") - } - - DESTDIR=$$CMAKE_DIR/bin - - include($$CMAKE_DIR/qrenderdoc/qrenderdoc_cmake.pri) - - # Temp files into .obj - MOC_DIR = .obj - UI_DIR = .obj - RCC_DIR = .obj - OBJECTS_DIR = .obj - - # Link against the core library - LIBS += -lrenderdoc - QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN\',-rpath,\'\$$ORIGIN/../lib\'' - - # Add the SWIG files that were generated in cmake - SOURCES += $$CMAKE_DIR/qrenderdoc/renderdoc_python.cxx - SOURCES += $$CMAKE_DIR/qrenderdoc/renderdoc.py.c - SOURCES += $$CMAKE_DIR/qrenderdoc/qrenderdoc_python.cxx - SOURCES += $$CMAKE_DIR/qrenderdoc/qrenderdoc.py.c - - CONFIG += warn_off - CONFIG += c++14 - QMAKE_CFLAGS_WARN_OFF -= -w - QMAKE_CXXFLAGS_WARN_OFF -= -w - - macx: { - DEFINES += RENDERDOC_PLATFORM_POSIX RENDERDOC_PLATFORM_APPLE - ICON = $$OSX_ICONFILE - - INFO_PLIST_PATH = $$shell_quote($$DESTDIR/$${TARGET}.app/Contents/Info.plist) - QMAKE_POST_LINK += $$_PRO_FILE_PWD_/../scripts/set_plist_version.sh $${RENDERDOC_VERSION}.0 $${INFO_PLIST_PATH} - } else { - QT += x11extras - DEFINES += RENDERDOC_PLATFORM_POSIX RENDERDOC_PLATFORM_LINUX RENDERDOC_WINDOWING_XLIB RENDERDOC_WINDOWING_XCB - QMAKE_LFLAGS += '-Wl,--no-as-needed' - - contains(QMAKE_CXXFLAGS, "-DRENDERDOC_SUPPORT_GL") { - # Link against GL - LIBS += -lGL - } - - contains(QMAKE_CXXFLAGS, "-DRENDERDOC_SUPPORT_GLES") { - # Link against EGL - LIBS += -lEGL - } - } -} - -# Add our sources first so Qt Creator adds new files here - -SOURCES += Code/qrenderdoc.cpp \ - Code/qprocessinfo.cpp \ - Code/ReplayManager.cpp \ - Code/CaptureContext.cpp \ - Code/ScintillaSyntax.cpp \ - Code/QRDUtils.cpp \ - Code/FormatElement.cpp \ - Code/Resources.cpp \ - Code/pyrenderdoc/PythonContext.cpp \ - Code/Interface/QRDInterface.cpp \ - Code/Interface/CommonPipelineState.cpp \ - Code/Interface/PersistantConfig.cpp \ - Code/Interface/RemoteHost.cpp \ - Styles/RDStyle/RDStyle.cpp \ - Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.cpp \ - Windows/Dialogs/AboutDialog.cpp \ - Windows/MainWindow.cpp \ - Windows/EventBrowser.cpp \ - Windows/TextureViewer.cpp \ - Widgets/Extended/RDLineEdit.cpp \ - Widgets/Extended/RDTextEdit.cpp \ - Widgets/Extended/RDLabel.cpp \ - Widgets/Extended/RDHeaderView.cpp \ - Widgets/Extended/RDToolButton.cpp \ - Widgets/Extended/RDDoubleSpinBox.cpp \ - Widgets/Extended/RDListView.cpp \ - Widgets/CustomPaintWidget.cpp \ - Widgets/ResourcePreview.cpp \ - Widgets/ThumbnailStrip.cpp \ - Widgets/TextureGoto.cpp \ - Widgets/RangeHistogram.cpp \ - Windows/Dialogs/TextureSaveDialog.cpp \ - Windows/Dialogs/CaptureDialog.cpp \ - Windows/Dialogs/LiveCapture.cpp \ - Widgets/Extended/RDListWidget.cpp \ - Windows/APIInspector.cpp \ - Windows/PipelineState/PipelineStateViewer.cpp \ - Windows/PipelineState/VulkanPipelineStateViewer.cpp \ - Windows/PipelineState/D3D11PipelineStateViewer.cpp \ - Windows/PipelineState/D3D12PipelineStateViewer.cpp \ - Windows/PipelineState/GLPipelineStateViewer.cpp \ - Widgets/Extended/RDTreeView.cpp \ - Widgets/Extended/RDTreeWidget.cpp \ - Windows/ConstantBufferPreviewer.cpp \ - Widgets/BufferFormatSpecifier.cpp \ - Windows/BufferViewer.cpp \ - Widgets/Extended/RDTableView.cpp \ - Windows/DebugMessageView.cpp \ - Windows/StatisticsViewer.cpp \ - Windows/TimelineBar.cpp \ - Windows/Dialogs/SettingsDialog.cpp \ - Windows/Dialogs/OrderedListEditor.cpp \ - Widgets/Extended/RDTableWidget.cpp \ - Windows/Dialogs/SuggestRemoteDialog.cpp \ - Windows/Dialogs/VirtualFileDialog.cpp \ - Windows/Dialogs/RemoteManager.cpp \ - Windows/PixelHistoryView.cpp \ - Widgets/PipelineFlowChart.cpp \ - Windows/Dialogs/EnvironmentEditor.cpp \ - Widgets/FindReplace.cpp \ - Widgets/Extended/RDSplitter.cpp \ - Windows/Dialogs/TipsDialog.cpp \ - Windows/PythonShell.cpp -HEADERS += Code/CaptureContext.h \ - Code/qprocessinfo.h \ - Code/ReplayManager.h \ - Code/ScintillaSyntax.h \ - Code/QRDUtils.h \ - Code/Resources.h \ - Code/pyrenderdoc/PythonContext.h \ - Code/pyrenderdoc/pyconversion.h \ - Code/pyrenderdoc/document_check.h \ - Code/Interface/QRDInterface.h \ - Code/Interface/CommonPipelineState.h \ - Code/Interface/PersistantConfig.h \ - Code/Interface/RemoteHost.h \ - Styles/RDStyle/RDStyle.h \ - Styles/RDTweakedNativeStyle/RDTweakedNativeStyle.h \ - Windows/Dialogs/AboutDialog.h \ - Windows/MainWindow.h \ - Windows/EventBrowser.h \ - Windows/TextureViewer.h \ - Widgets/Extended/RDLineEdit.h \ - Widgets/Extended/RDTextEdit.h \ - Widgets/Extended/RDLabel.h \ - Widgets/Extended/RDHeaderView.h \ - Widgets/Extended/RDToolButton.h \ - Widgets/Extended/RDDoubleSpinBox.h \ - Widgets/Extended/RDListView.h \ - Widgets/CustomPaintWidget.h \ - Widgets/ResourcePreview.h \ - Widgets/ThumbnailStrip.h \ - Widgets/TextureGoto.h \ - Widgets/RangeHistogram.h \ - Windows/Dialogs/TextureSaveDialog.h \ - Windows/Dialogs/CaptureDialog.h \ - Windows/Dialogs/LiveCapture.h \ - Widgets/Extended/RDListWidget.h \ - Windows/APIInspector.h \ - Windows/PipelineState/PipelineStateViewer.h \ - Windows/PipelineState/VulkanPipelineStateViewer.h \ - Windows/PipelineState/D3D11PipelineStateViewer.h \ - Windows/PipelineState/D3D12PipelineStateViewer.h \ - Windows/PipelineState/GLPipelineStateViewer.h \ - Widgets/Extended/RDTreeView.h \ - Widgets/Extended/RDTreeWidget.h \ - Windows/ConstantBufferPreviewer.h \ - Widgets/BufferFormatSpecifier.h \ - Windows/BufferViewer.h \ - Widgets/Extended/RDTableView.h \ - Windows/DebugMessageView.h \ - Windows/StatisticsViewer.h \ - Windows/TimelineBar.h \ - Windows/Dialogs/SettingsDialog.h \ - Windows/Dialogs/OrderedListEditor.h \ - Widgets/Extended/RDTableWidget.h \ - Windows/Dialogs/SuggestRemoteDialog.h \ - Windows/Dialogs/VirtualFileDialog.h \ - Windows/Dialogs/RemoteManager.h \ - Windows/PixelHistoryView.h \ - Widgets/PipelineFlowChart.h \ - Windows/Dialogs/EnvironmentEditor.h \ - Widgets/FindReplace.h \ - Widgets/Extended/RDSplitter.h \ - Windows/Dialogs/TipsDialog.h \ - Windows/PythonShell.h -FORMS += Windows/Dialogs/AboutDialog.ui \ - Windows/MainWindow.ui \ - Windows/EventBrowser.ui \ - Windows/TextureViewer.ui \ - Widgets/ResourcePreview.ui \ - Widgets/ThumbnailStrip.ui \ - Windows/Dialogs/TextureSaveDialog.ui \ - Windows/Dialogs/CaptureDialog.ui \ - Windows/Dialogs/LiveCapture.ui \ - Windows/APIInspector.ui \ - Windows/PipelineState/PipelineStateViewer.ui \ - Windows/PipelineState/VulkanPipelineStateViewer.ui \ - Windows/PipelineState/D3D11PipelineStateViewer.ui \ - Windows/PipelineState/D3D12PipelineStateViewer.ui \ - Windows/PipelineState/GLPipelineStateViewer.ui \ - Windows/ConstantBufferPreviewer.ui \ - Widgets/BufferFormatSpecifier.ui \ - Windows/BufferViewer.ui \ - Windows/ShaderViewer.ui \ - Windows/DebugMessageView.ui \ - Windows/StatisticsViewer.ui \ - Windows/Dialogs/SettingsDialog.ui \ - Windows/Dialogs/OrderedListEditor.ui \ - Windows/Dialogs/SuggestRemoteDialog.ui \ - Windows/Dialogs/VirtualFileDialog.ui \ - Windows/Dialogs/RemoteManager.ui \ - Windows/PixelHistoryView.ui \ - Windows/Dialogs/EnvironmentEditor.ui \ - Widgets/FindReplace.ui \ - Windows/Dialogs/TipsDialog.ui \ - Windows/PythonShell.ui - -RESOURCES += Resources/resources.qrc - -# Add ToolWindowManager - -SOURCES += 3rdparty/toolwindowmanager/ToolWindowManager.cpp \ - 3rdparty/toolwindowmanager/ToolWindowManagerArea.cpp \ - 3rdparty/toolwindowmanager/ToolWindowManagerSplitter.cpp \ - 3rdparty/toolwindowmanager/ToolWindowManagerTabBar.cpp \ - 3rdparty/toolwindowmanager/ToolWindowManagerWrapper.cpp - -HEADERS += 3rdparty/toolwindowmanager/ToolWindowManager.h \ - 3rdparty/toolwindowmanager/ToolWindowManagerArea.h \ - 3rdparty/toolwindowmanager/ToolWindowManagerSplitter.h \ - 3rdparty/toolwindowmanager/ToolWindowManagerTabBar.h \ - 3rdparty/toolwindowmanager/ToolWindowManagerWrapper.h - -# Add FlowLayout - -SOURCES += 3rdparty/flowlayout/FlowLayout.cpp -HEADERS += 3rdparty/flowlayout/FlowLayout.h - -# Add Scintilla last as it has extra search paths - -# Needed for building -DEFINES += SCINTILLA_QT=1 MAKING_LIBRARY=1 SCI_LEXER=1 -INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/scintilla/src -INCLUDEPATH += $$_PRO_FILE_PWD_/3rdparty/scintilla/lexlib - -SOURCES += $$_PRO_FILE_PWD_/3rdparty/scintilla/lexlib/*.cxx \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/lexers/*.cxx \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/src/*.cxx \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/qt/ScintillaEdit/*.cpp \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/qt/ScintillaEditBase/*.cpp \ - Windows/ShaderViewer.cpp - -HEADERS += $$_PRO_FILE_PWD_/3rdparty/scintilla/lexlib/*.h \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/src/*.h \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/qt/ScintillaEdit/*.h \ - $$_PRO_FILE_PWD_/3rdparty/scintilla/qt/ScintillaEditBase/*.h \ - Windows/ShaderViewer.h - diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj deleted file mode 100644 index 99104b144..000000000 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ /dev/null @@ -1,1636 +0,0 @@ - - - - - Development - Win32 - - - Release - Win32 - - - Release - x64 - - - Development - x64 - - - QTDebug - Win32 - - - QTDebug - x64 - - - - {A14A6AE5-02B1-35FE-BE59-B3E7C273B40B} - qrenderdoc - Qt4VSv1.0 - 8.1 - qrenderdoc - - - - v140 - $(SolutionDir)$(Platform)\$(Configuration)\ - false - NotSet - Application - qrenderdoc - qrenderdoc - true - $(Platform)\$(Configuration)\obj\$(ProjectName)\ - - - $(SolutionDir)$(Platform)\Development\ - $(Platform)\Development\obj\$(ProjectName)\ - - - $(SolutionDir)$(SolutionRelativeIntDir) - $(IntDir) - $(OutputDirectory)\ - - - false - true - - - - - - - $(OutputDirectory) - - - - WIN64;%(PreprocessorDefinitions) - - - WIN64;%(PreprocessorDefinitions) - - - - - RELEASE;QT_MESSAGELOGCONTEXT;QT_NO_DEBUG;NDEBUG;%(PreprocessorDefinitions) - - - - - MultiThreadedDLL - true - true - false - false - ProgramDatabase - true - true - $(ProjectDir);$(IntDir)generated\;$(SolutionDir)\renderdoc\api\replay;3rdparty\python\include;3rdparty\pyside\include\PySide2;3rdparty\pyside\include\PySide2\QtCore;3rdparty\pyside\include\PySide2\QtGui;3rdparty\pyside\include\PySide2\QtWidgets;3rdparty\pyside\include\shiboken2;3rdparty\qt\$(Platform)\include;3rdparty\qt\$(Platform)\include\QtWidgets;3rdparty\qt\$(Platform)\include\QtGui;3rdparty\qt\$(Platform)\include\QtCore;3rdparty\qt\$(Platform)\include\QtSvg;%(AdditionalIncludeDirectories) - /Zc:strictStrings /Zc:throwingNew %(AdditionalOptions) - _WINDOWS;UNICODE;WIN32;WIN64;RENDERDOC_PLATFORM_WIN32;PYSIDE2_ENABLED=1;SCINTILLA_QT=1;MAKING_LIBRARY=1;SCI_LEXER=1;QT_NO_CAST_FROM_ASCII;QT_NO_CAST_TO_ASCII;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_SVG_LIB;%(PreprocessorDefinitions) - Level4 - true - 4100;4127;4189;4714;4718;4996;%(DisableSpecificWarnings) - Use - precompiled.h - precompiled.h - - - Windows - shiboken2.lib;python36.lib;qtmain.lib;Qt5Widgets.lib;Qt5Gui.lib;Qt5Core.lib;Qt5Svg.lib;shell32.lib - 3rdparty\pyside\$(Platform);3rdparty\python\$(Platform);3rdparty\qt\$(Platform)\lib;%(AdditionalLibraryDirectories) - true - true - true - true - true - - - true - - - Unsigned - None - 0 - - - _WINDOWS;UNICODE;WIN32;RENDERDOC_PLATFORM_WIN32;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_SVG_LIB;%(PreprocessorDefinitions) - $(SolutionDir)\renderdoc\api\replay - - - - - Disabled - - - - - Disabled - - - - - MaxSpeed - Default - true - true - - - true - true - - - - - MultiThreadedDebugDLL - - - shiboken2.lib;python36.lib;qtmaind.lib;Qt5Widgetsd.lib;Qt5Guid.lib;Qt5Cored.lib;Qt5Svgd.lib;shell32.lib - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - 4458;%(DisableSpecificWarnings) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - NotUsing - - - - - - - - - - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - - - 3rdparty\scintilla\include;3rdparty\scintilla\include\qt;3rdparty\scintilla\src;3rdparty\scintilla\lexlib;%(AdditionalIncludeDirectories) - - - - - - - - - - - - - - - - - - - - - - - - 4101;4456;4459;%(DisableSpecificWarnings) - - - 4101;4456;4459;%(DisableSpecificWarnings) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotUsing - - - - - - - - - - - - - - - - - - - - NotUsing - - - - - NotUsing - - - - - NotUsing - - - - - NotUsing - - - - - NotUsing - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui" -I"$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp" - MOC %(Filename).h - $(IntDir)generated\moc_%(Filename).cpp - - - - - Document - %(Fullpath);pyconversion.i;document_check.h;$(SolutionDir)renderdoc\api\replay\basic_types.h;$(SolutionDir)renderdoc\api\replay\capture_options.h;$(SolutionDir)renderdoc\api\replay\control_types.h;$(SolutionDir)renderdoc\api\replay\d3d11_pipestate.h;$(SolutionDir)renderdoc\api\replay\d3d12_pipestate.h;$(SolutionDir)renderdoc\api\replay\data_types.h;$(SolutionDir)renderdoc\api\replay\gl_pipestate.h;$(SolutionDir)renderdoc\api\replay\renderdoc_replay.h;$(SolutionDir)renderdoc\api\replay\replay_enums.h;$(SolutionDir)renderdoc\api\replay\shader_types.h;$(SolutionDir)renderdoc\api\replay\vk_pipestate.h;%(AdditionalInputs) - "$(ProjectDir)3rdparty\swig\swig.exe" -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I"$(SolutionDir)renderdoc\api\replay" -outdir "$(IntDir)generated" -o "$(IntDir)generated\%(Filename)_python.cxx" "%(FullPath)" - Compiling SWIG interface - $(IntDir)generated\%(Filename).py;$(IntDir)generated\%(Filename)_python.cxx;%(Outputs) - false - - - Document - %(Fullpath);Code\Interface\QRDInterface.h;Code\Interface\CommonPipelineState.h;Code\Interface\PersistantConfig.h;Code\Interface\RemoteHost.h;$(IntDir)generated\renderdoc.py;%(AdditionalInputs) - "$(ProjectDir)3rdparty\swig\swig.exe" -v -Wextra -Werror -O -c++ -python -modern -modernargs -enumclass -fastunpack -py3 -builtin -I"$(SolutionDir)renderdoc\api\replay" -I"$(ProjectDir)." -outdir "$(IntDir)generated" -o "$(IntDir)generated\%(Filename)_python.cxx" "%(FullPath)" - Compiling SWIG interface - $(IntDir)generated\%(Filename).py;$(IntDir)generated\%(Filename)_python.cxx;%(Outputs) - false - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - Designer - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - Designer - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - - - %(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h" - UIC %(Filename).ui - $(IntDir)generated\ui_%(Filename).h - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Resources\resources.qrc;$(ProjectDir)3rdparty\qt\$(Platform)\bin\rcc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\rcc.exe" -name resources Resources\resources.qrc -o "$(IntDir)generated\qrc_resources.cpp" - RCC resources.qrc - $(IntDir)generated\qrc_resources.cpp - - - Resources\qtconf.qrc;$(ProjectDir)3rdparty\qt\$(Platform)\bin\rcc.exe;%(AdditionalInputs) - "$(ProjectDir)3rdparty\qt\$(Platform)\bin\rcc.exe" -name qtconf Resources\qtconf.qrc -o "$(IntDir)generated\qrc_qtconf.cpp" - RCC qtconf.qrc - $(IntDir)generated\qrc_qtconf.cpp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - python36.zip - PreserveNewest - false - - - _ctypes.pyd - PreserveNewest - false - - - python36.dll - PreserveNewest - false - - - shiboken2.dll - PreserveNewest - false - - - PySide2\pyside2.dll - PreserveNewest - false - - - PySide2\__init__.py - PreserveNewest - false - - - PySide2\_utils.py - PreserveNewest - false - - - PySide2\QtCore.pyd - PreserveNewest - false - - - PySide2\QtGui.pyd - PreserveNewest - false - - - PySide2\QtWidgets.pyd - PreserveNewest - false - - - qtplugins\platforms\qwindows.dll - PreserveNewest - false - - - qtplugins\imageformats\qsvg.dll - PreserveNewest - false - - - Qt5Core.dll - PreserveNewest - False - - - Qt5Gui.dll - PreserveNewest - false - - - Qt5Widgets.dll - PreserveNewest - false - - - Qt5Svg.dll - PreserveNewest - false - - - Qt5Network.dll - PreserveNewest - false - - - qtplugins\platforms\qwindowsd.dll - PreserveNewest - false - - - qtplugins\imageformats\qsvgd.dll - PreserveNewest - false - - - Qt5Cored.dll - PreserveNewest - False - - - Qt5Cored.dll - PreserveNewest - False - - - Qt5Guid.dll - PreserveNewest - false - - - Qt5Widgetsd.dll - PreserveNewest - false - - - Qt5Svgd.dll - PreserveNewest - false - - - Qt5Networkd.dll - PreserveNewest - false - - - - - {e2b46d67-90e2-40b6-9597-72930e7845e5} - - - - - RENDERDOC_PY_PATH=.\..\$(SolutionRelativeIntDir)\generated\renderdoc.py;QRENDERDOC_PY_PATH=.\..\$(SolutionRelativeIntDir)\generated\qrenderdoc.py;%(PreprocessorDefinitions) - - - - - \ No newline at end of file diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters deleted file mode 100644 index 6c476fad5..000000000 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ /dev/null @@ -1,1443 +0,0 @@ - - - - - {71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11} - - - {D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E} - - - {c6877252-7f18-4c63-a2f7-66b1913d8ada} - - - {476acc91-c8c7-4ba7-9835-c0b566f562dd} - - - {6c205a59-af2f-49ab-bcbf-e83799ce89a3} - - - {c820ead5-74a1-4010-86bb-d5d77b5d13fd} - - - {96c62ca7-39e7-4fca-a6a4-c8e1c3e2a324} - - - {c2e91ed4-8c04-4fdc-accf-8fed288f2cd8} - - - {897f728c-8a11-41c3-ba6f-75815d9e06db} - - - {06b18b38-7ec5-4195-8230-f5be6348ecfb} - - - {633cf7bf-24ec-4927-835b-f6e96e21c288} - - - {42a491e9-4e18-4220-8de2-e07b7cde26bc} - - - {7ba076e7-3417-4e91-be51-9e7f17a19c24} - - - {6c0de148-de6a-4ab3-91ad-fae4a5278c03} - - - {e0300f3d-d087-46c8-9a35-b9d709a212d8} - - - {bd9a022f-7925-4f17-acc3-8d4688b8c0d6} - - - {92b9dc0e-7bb4-402a-bd5e-799d5ccdaa36} - - - {2b0fab33-f1b9-4488-bc9c-f3b65b0e955c} - - - {3dcd3970-3ccb-448b-b596-93c1a272b0fd} - - - {28c1a078-8722-4949-bed4-a1bed6c26082} - - - {e7b5de50-ab5a-4a91-a53f-a524ea51641c} - - - {4a14bfec-662c-410a-8d94-dccf5ba6cb0b} - - - {7986f203-466f-4a74-93a2-6feeaec3b05b} - - - {4869e303-055c-4458-91d6-89ecc827f338} - - - {f74a424c-ce15-4da6-9af4-c6bcf62aa581} - - - {1e176174-0c57-44df-82b1-638ced184b72} - - - {c0be5204-4ee0-4948-87b4-cc957b6f8953} - - - - - 3rdparty\ToolWindowManager - - - 3rdparty\ToolWindowManager - - - 3rdparty\ToolWindowManager - - - 3rdparty\FlowLayout - - - Code - - - Widgets - - - Windows - - - Windows - - - Windows - - - Widgets - - - Widgets - - - Code - - - Widgets - - - Widgets - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Code - - - Code - - - Windows\Dialogs - - - Widgets\Extended - - - Windows - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Widgets\Extended - - - Windows - - - Widgets - - - Windows - - - Widgets\Extended - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\lexers - - - 3rdparty\Scintilla\qt\ScintillaEditBase - - - 3rdparty\Scintilla\qt\ScintillaEditBase - - - 3rdparty\Scintilla\qt\ScintillaEditBase - - - 3rdparty\Scintilla\qt\ScintillaEdit - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\qt\ScintillaEdit - - - Windows - - - Code - - - Windows\Dialogs - - - Windows\Dialogs - - - Widgets\Extended - - - Windows\Dialogs - - - Windows\Dialogs - - - Code - - - Windows - - - Windows - - - Windows\Dialogs - - - Windows - - - Widgets\Extended - - - Code - - - Widgets - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Windows\Dialogs - - - Widgets - - - Generated Files - - - Generated Files - - - Widgets\Extended - - - Code\pyrenderdoc - - - Generated Files - - - Generated Files - - - Code\Interface - - - Code\Interface - - - Code\Interface - - - Code\Interface - - - Code - - - Generated Files - - - Windows - - - Widgets\Extended - - - Generated Files - - - PCH - - - Widgets\Extended - - - Generated Files - - - Generated Files - - - 3rdparty\ToolWindowManager - - - 3rdparty\ToolWindowManager - - - Generated Files - - - Generated Files - - - Widgets\Extended - - - Generated Files - - - Windows - - - Generated Files - - - Styles\RDStyle - - - Generated Files - - - Generated Files - - - Styles\RDTweakedNativeStyle - - - - - 3rdparty\FlowLayout - - - Code - - - Code - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\lexlib - - - 3rdparty\Scintilla\include\qt - - - 3rdparty\Scintilla\include\qt - - - 3rdparty\Scintilla\include\qt - - - 3rdparty\Scintilla\include - - - 3rdparty\Scintilla\include - - - 3rdparty\Scintilla\include - - - 3rdparty\Scintilla\include - - - 3rdparty\Scintilla\include - - - 3rdparty\Scintilla\include - - - 3rdparty\Scintilla\qt\ScintillaEditBase - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - 3rdparty\Scintilla\src - - - Code - - - Resources - - - Code - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Generated Files - - - Code\Interface - - - Code\Interface - - - Code\Interface - - - Code\Interface - - - Code\pyrenderdoc - - - Code - - - Generated Files - - - PCH - - - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Resources\Files - - - Code\pyrenderdoc - - - Code\pyrenderdoc - - - - - Resources - - - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Widgets - - - Widgets - - - Widgets - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Resources - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Windows - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets\Extended - - - Widgets - - - Widgets - - - Widgets - - - Widgets - - - Widgets - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\PipelineState - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Windows\PipelineState - - - Code - - - Widgets - - - 3rdparty\ToolWindowManager - - - 3rdparty\ToolWindowManager - - - 3rdparty\ToolWindowManager - - - 3rdparty\Scintilla\qt\ScintillaEdit - - - 3rdparty\Scintilla\qt\ScintillaEdit - - - 3rdparty\Scintilla\qt\ScintillaEditBase - - - 3rdparty\Scintilla\qt\ScintillaEditBase - - - Windows\Dialogs - - - Windows\Dialogs - - - Windows - - - Windows - - - Widgets\Extended - - - Widgets - - - Windows\Dialogs - - - Windows\Dialogs - - - Widgets - - - Widgets - - - Widgets\Extended - - - Code\pyrenderdoc - - - Code\pyrenderdoc - - - Code\pyrenderdoc - - - Widgets\Extended - - - Windows - - - Windows - - - Widgets\Extended - - - 3rdparty\ToolWindowManager - - - 3rdparty\ToolWindowManager - - - Widgets\Extended - - - Resources - - - Windows - - - Styles\RDStyle - - - Styles\RDTweakedNativeStyle - - - \ No newline at end of file diff --git a/qrenderdoc/share/application-x-renderdoc-capture.svg b/qrenderdoc/share/application-x-renderdoc-capture.svg deleted file mode 100644 index d3b7f94dd..000000000 --- a/qrenderdoc/share/application-x-renderdoc-capture.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/qrenderdoc/share/magic b/qrenderdoc/share/magic deleted file mode 100644 index fa8b3e5da..000000000 --- a/qrenderdoc/share/magic +++ /dev/null @@ -1,7 +0,0 @@ -# Magic local data for file(1) command. Format is described in magic(5). -# This can be added to ~/.magic or /etc/magic or anywhere else magic -# data is sourced from. - -# RenderDoc -0 string RDOC RenderDoc Capture File -!:mime application/x-renderdoc-capture diff --git a/qrenderdoc/share/menu b/qrenderdoc/share/menu deleted file mode 100644 index f1f503b4c..000000000 --- a/qrenderdoc/share/menu +++ /dev/null @@ -1,6 +0,0 @@ -?package(local.renderdoc):needs="x11" section="Applications/Programming" \ - title="RenderDoc" \ - command="qrenderdoc" \ - icon="/usr/share/pixmaps/renderdoc-icon-32x32.xpm" \ - icon16x16="/usr/share/pixmaps/renderdoc-icon-16x16.xpm" \ - icon32x32="/usr/share/pixmaps/renderdoc-icon-32x32.xpm" diff --git a/qrenderdoc/share/renderdoc-capture.xml b/qrenderdoc/share/renderdoc-capture.xml deleted file mode 100644 index 7c668a28b..000000000 --- a/qrenderdoc/share/renderdoc-capture.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - RenderDoc capture file - - - - - - diff --git a/qrenderdoc/share/renderdoc-icon-16x16.xpm b/qrenderdoc/share/renderdoc-icon-16x16.xpm deleted file mode 100644 index e5a007e60..000000000 --- a/qrenderdoc/share/renderdoc-icon-16x16.xpm +++ /dev/null @@ -1,63 +0,0 @@ -/* XPM */ -static char *renderdoc_icon_16x16[] = { -/* columns rows colors chars-per-pixel */ -"16 16 41 1 ", -" c #2323AAAA6767", -". c #2323ABAB6868", -"X c #2424ACAC6868", -"o c #2424ADAD6A6A", -"O c #2626AFAF6D6D", -"+ c #2626B0B06E6E", -"@ c #2727B0B06E6E", -"# c #2828B3B37171", -"$ c #2929B3B37272", -"% c #2929B4B47272", -"& c #2929B4B47373", -"* c #2A2AB5B57474", -"= c #3434B2B27373", -"- c #3D3DB0B07575", -"; c #3E3EB5B57979", -": c #4141B6B67C7C", -"> c #4747B5B57C7C", -", c #4F4FBBBB8484", -"< c #5757BABA8787", -"1 c #6565C1C19191", -"2 c #6B6BC6C69898", -"3 c #6B6BC7C79B9B", -"4 c #7A7AC8C89F9F", -"5 c #8A8ACECEAAAA", -"6 c #8C8CCFCFADAD", -"7 c #8E8ED1D1AEAE", -"8 c #9494D3D3B2B2", -"9 c #9797D4D4B4B4", -"0 c #A2A2D7D7BABA", -"q c #A5A5DBDBBFBF", -"w c #B2B2DFDFC8C8", -"e c #C2C2E5E5D2D2", -"r c #C4C4E6E6D4D4", -"t c #C5C5E8E8D6D6", -"y c #CCCCE9E9D9D9", -"u c #D6D6EDEDE0E0", -"i c #D8D8EEEEE2E2", -"p c #DFDFF1F1E8E8", -"a c #EEEEF8F8F3F3", -"s c #F0F0F9F9F4F4", -"d c white", -/* pixels */ -"****************", -"****************", -"******%$*%******", -"*****%@oo@%*****", -"****$o9dd7o%****", -"****Owd0qdqO****", -"***%;d4o 5d=****", -"***%,d>@O c #5F5FC8C89797", -", c #6060C8C89797", -"< c #6666CACA9B9B", -"1 c #6F6FCDCDA1A1", -"2 c #7070CDCDA2A2", -"3 c #7373CECEA3A3", -"4 c #7979D1D1A8A8", -"5 c #7E7ED2D2ABAB", -"6 c #8383D4D4AEAE", -"7 c #8989D6D6B2B2", -"8 c #8E8ED8D8B5B5", -"9 c #9090D8D8B7B7", -"0 c #9D9DDDDDBFBF", -"q c #A1A1DEDEC1C1", -"w c #A7A7E1E1C6C6", -"e c #A9A9E1E1C7C7", -"r c #ADADE3E3CACA", -"t c #B5B5E5E5CFCF", -"y c #BBBBE7E7D3D3", -"u c #C7C7ECECDADA", -"i c #C9C9ECECDCDC", -"p c #CECEEEEEDFDF", -"a c #D3D3F0F0E2E2", -"s c #DADAF2F2E7E7", -"d c #DBDBF3F3E8E8", -"f c #DFDFF4F4EAEA", -"g c #E0E0F4F4EBEB", -"h c #E1E1F5F5EBEB", -"j c #E2E2F5F5ECEC", -"k c #E7E7F7F7EFEF", -"l c #E9E9F7F7F1F1", -"z c #ECECF8F8F2F2", -"x c #EDEDF9F9F4F4", -"c c #F2F2FBFBF7F7", -"v c #F4F4FBFBF8F8", -"b c #F5F5FCFCF8F8", -"n c #F9F9FDFDFBFB", -"m c #FCFCFEFEFDFD", -"M c white", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ${data_objects}) -add_library(renderdoc SHARED ${renderdoc_objects}) +add_library(renderdoc STATIC ${renderdoc_objects}) target_compile_definitions(renderdoc ${RDOC_DEFINITIONS}) target_include_directories(renderdoc ${RDOC_INCLUDES}) target_link_libraries(renderdoc ${RDOC_LIBRARIES}) diff --git a/renderdoc/api/replay/basic_types.h b/renderdoc/api/replay/basic_types.h index d29a83faa..3003f56a4 100644 --- a/renderdoc/api/replay/basic_types.h +++ b/renderdoc/api/replay/basic_types.h @@ -81,14 +81,8 @@ struct array count = 0; } -#ifdef RENDERDOC_EXPORTS static void *allocate(size_t s) { return malloc(s); } static void deallocate(const void *p) { free((void *)p); } -#else - static void *allocate(size_t s) { return RENDERDOC_AllocArrayMem(s); } - static void deallocate(const void *p) { RENDERDOC_FreeArrayMem(p); } -#endif - T &operator[](size_t i) { return elems[i]; } const T &operator[](size_t i) const { return elems[i]; } array(const std::vector &in) diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index eaaacef6a..d3b97ef3a 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -71,21 +71,14 @@ typedef uint32_t bool32; #if defined(RENDERDOC_PLATFORM_WIN32) -#ifdef RENDERDOC_EXPORTS -#define RENDERDOC_API __declspec(dllexport) -#else -#define RENDERDOC_API __declspec(dllimport) -#endif +#define RENDERDOC_API + #define RENDERDOC_CC __cdecl #elif defined(RENDERDOC_PLATFORM_LINUX) || defined(RENDERDOC_PLATFORM_APPLE) || \ defined(RENDERDOC_PLATFORM_ANDROID) -#ifdef RENDERDOC_EXPORTS -#define RENDERDOC_API __attribute__((visibility("default"))) -#else #define RENDERDOC_API -#endif #define RENDERDOC_CC @@ -181,12 +174,6 @@ struct GlobalEnvironment // needs to be declared up here for reference in basic_types -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeArrayMem(const void *mem); -typedef void(RENDERDOC_CC *pRENDERDOC_FreeArrayMem)(const void *mem); - -extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz); -typedef void *(RENDERDOC_CC *pRENDERDOC_AllocArrayMem)(uint64_t sz); - #include "basic_types.h" #ifdef RENDERDOC_EXPORTS diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 331f06a11..b45a76b5f 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -26,6 +26,7 @@ #include "core/core.h" #include #include +#include "3rdparty/tinyfiledialogs/tinyfiledialogs.h" #include "api/replay/version.h" #include "common/common.h" #include "common/dds_readwrite.h" @@ -1149,3 +1150,134 @@ void RenderDoc::RemoveFrameCapturer(void *dev, void *wnd) RDCERR("Removing FrameCapturer for unknown window!"); } } + +static RENDERDOC_API_1_1_1 *checkAPI(void *handle) +{ + if(handle) + { + pRENDERDOC_GetAPI getapi = + (pRENDERDOC_GetAPI)Process::GetFunctionAddress(handle, "RENDERDOC_GetAPI"); + + if(getapi) + { + RENDERDOC_API_1_1_1 *ret = NULL; + getapi(eRENDERDOC_API_Version_1_1_1, (void **)&ret); + + int major = 0, minor = 0, patch = 0; + ret->GetAPIVersion(&major, &minor, &patch); + + uint64_t combined = 0; + combined |= uint64_t(major & 0xffff) << 32; + combined |= uint64_t(minor & 0xffff) << 16; + combined |= uint64_t(patch & 0xffff) << 0; + + uint64_t ver1_1_1 = (1ULL << 32) | (1ULL << 16) | (1ULL << 0); + + // only capture in new renderdoc, above API 1.1.1 + if(combined <= ver1_1_1) + return NULL; + + time_t t = time(NULL); + tm now; + +#if ENABLED(RDOC_WIN32) + localtime_s(&now, &t); +#else + now = *localtime(&t); +#endif + + std::string path; + FileIO::GetExecutableFilename(path); + path = dirname(path) + StringFormat::Fmt("/converted_%04d.%02d.%02d_%02d.%02d.rdc", + 1900 + now.tm_year, now.tm_mon + 1, now.tm_mday, + now.tm_hour, now.tm_min); + + ret->SetLogFilePathTemplate(path.c_str()); + + return ret; + } + } + + return NULL; +} + +RENDERDOC_API_1_1_1 *RENDERDOC_LoadConverter() +{ + RenderDoc::Inst().SetReplayApp(true); + + RenderDoc::Inst().Initialise(); + +#if ENABLED(RDOC_LINUX) + XInitThreads(); + + GlobalEnvironment env; + env.xlibDisplay = XOpenDisplay(NULL); + + RenderDoc::Inst().ProcessGlobalEnvironment(env, {}); +#endif + + const char *modulename = +#if ENABLED(RDOC_WIN32) + "renderdoc.dll"; +#else + "librenderdoc.so"; +#endif + + // try to locate the module in the default search path + void *handle = Process::LoadModule(modulename); + + RENDERDOC_API_1_1_1 *api = checkAPI(handle); + + if(api) + return api; + +#if ENABLED(RDOC_WIN32) + // check in the registry @ HKLM\SOFTWARE\Classes\RenderDoc.RDCCapture.1\DefaultIcon + HKEY key = NULL; + LSTATUS ret = + RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\RenderDoc.RDCCapture.1\\DefaultIcon", 0, + KEY_READ, &key); + + if(ret == ERROR_SUCCESS) + { + std::wstring exepath; + + DWORD sz = 0; + ret = RegGetValueW(key, NULL, NULL, RRF_RT_ANY, NULL, NULL, &sz); + if(ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS) + { + exepath.resize(sz / sizeof(wchar_t)); + ret = RegGetValueW(key, NULL, NULL, RRF_RT_ANY, NULL, (void *)&exepath[0], &sz); + + if(ret == ERROR_SUCCESS) + { + std::string installpath = dirname(StringFormat::Wide2UTF8(exepath)); + + handle = Process::LoadModule((installpath + "/renderdoc.dll").c_str()); + } + } + } + + if(key) + RegCloseKey(key); + + api = checkAPI(handle); + + if(api) + return api; +#endif + + modulename = tinyfd_openFileDialog("Locate renderdoc module", modulename, 0, NULL, NULL, 0); + + handle = Process::LoadModule(modulename); + + api = checkAPI(handle); + + if(api) + return api; + + tinyfd_messageBox("Coulnd't locate renderdoc module", + "Couldn't locate compatible 1.0+ renderdoc module", "ok", "error", 1); + + return NULL; +} \ No newline at end of file diff --git a/renderdoc/core/core.h b/renderdoc/core/core.h index 919e2ce9c..a7bbea049 100644 --- a/renderdoc/core/core.h +++ b/renderdoc/core/core.h @@ -49,6 +49,9 @@ class Chunk; // not provided by tinyexr, just do by hand bool is_exr_file(FILE *f); +// this becomes non-NULL when we should capture. +extern RENDERDOC_API_1_1_1 *ConverterAPI; + struct ICrashHandler { virtual ~ICrashHandler() {} diff --git a/renderdoc/core/crash_handler.h b/renderdoc/core/crash_handler.h index e85858fd7..5671fb07f 100644 --- a/renderdoc/core/crash_handler.h +++ b/renderdoc/core/crash_handler.h @@ -23,128 +23,5 @@ * THE SOFTWARE. ******************************************************************************/ -// currently breakpad crash-handler is only available on windows -#if ENABLED(RDOC_RELEASE) && RENDERDOC_OFFICIAL_BUILD && ENABLED(RDOC_WIN32) - -#define RDOC_CRASH_HANDLER OPTION_ON - -// breakpad -#include "breakpad/client/windows/common/ipc_protocol.h" -#include "breakpad/client/windows/handler/exception_handler.h" - -class CrashHandler : public ICrashHandler -{ -public: - CrashHandler(ICrashHandler *existing) - { - m_ExHandler = NULL; - - google_breakpad::AppMemoryList mem; - - if(existing) - mem = ((CrashHandler *)existing)->m_ExHandler->QueryRegisteredAppMemory(); - - SAFE_DELETE(existing); - - /////////////////// - - wchar_t tempPath[MAX_PATH] = {0}; - GetTempPathW(MAX_PATH - 1, tempPath); - - wstring dumpFolder = tempPath; - dumpFolder += L"RenderDoc/dumps"; - - CreateDirectoryW(dumpFolder.c_str(), NULL); - - MINIDUMP_TYPE dumpType = MINIDUMP_TYPE(MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory); - - { - PROCESS_INFORMATION pi; - STARTUPINFOW si; - RDCEraseEl(pi); - RDCEraseEl(si); - - HANDLE waitEvent = CreateEventA(NULL, TRUE, FALSE, "RENDERDOC_CRASHHANDLE"); - - wchar_t radpath[MAX_PATH] = {0}; - GetModuleFileNameW(GetModuleHandleA("renderdoc.dll"), radpath, MAX_PATH - 1); - - wchar_t *slash = wcsrchr(radpath, L'\\'); - - if(slash) - { - *slash = 0; - } - else - { - slash = wcsrchr(radpath, L'/'); - - if(slash) - *slash = 0; - else - { - radpath[0] = L'.'; - radpath[1] = 0; - } - } - - wstring cmdline = L"\""; - cmdline += radpath; - cmdline += L"/renderdoccmd.exe\" crashhandle"; - - wchar_t *paramsAlloc = new wchar_t[512]; - - wcscpy_s(paramsAlloc, 511, cmdline.c_str()); - - CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - - WaitForSingleObject(waitEvent, 2000); - - CloseHandle(waitEvent); - } - - static google_breakpad::CustomInfoEntry breakpadCustomInfo[] = { - google_breakpad::CustomInfoEntry(L"version", L""), - google_breakpad::CustomInfoEntry(L"logpath", L""), - google_breakpad::CustomInfoEntry(L"gitcommit", L""), - }; - - wstring wideStr = StringFormat::UTF82Wide(string(MAJOR_MINOR_VERSION_STRING)); - breakpadCustomInfo[0].set_value(wideStr.c_str()); - wideStr = StringFormat::UTF82Wide(string(RDCGETLOGFILE())); - breakpadCustomInfo[1].set_value(wideStr.c_str()); - wideStr = StringFormat::UTF82Wide(string(GIT_COMMIT_HASH)); - breakpadCustomInfo[2].set_value(wideStr.c_str()); - - google_breakpad::CustomClientInfo custom = {&breakpadCustomInfo[0], - ARRAY_COUNT(breakpadCustomInfo)}; - - _CrtSetReportMode(_CRT_ASSERT, 0); - m_ExHandler = new google_breakpad::ExceptionHandler( - dumpFolder.c_str(), NULL, NULL, NULL, google_breakpad::ExceptionHandler::HANDLER_ALL, - dumpType, L"\\\\.\\pipe\\RenderDocBreakpadServer", &custom); - - m_ExHandler->set_handle_debug_exceptions(true); - - for(size_t i = 0; i < mem.size(); i++) - m_ExHandler->RegisterAppMemory((void *)mem[i].ptr, mem[i].length); - } - - virtual ~CrashHandler() { SAFE_DELETE(m_ExHandler); } - void WriteMinidump() { m_ExHandler->WriteMinidump(); } - void WriteMinidump(void *data) - { - m_ExHandler->WriteMinidumpForException((EXCEPTION_POINTERS *)data); - } - - void RegisterMemoryRegion(void *mem, size_t size) { m_ExHandler->RegisterAppMemory(mem, size); } - void UnregisterMemoryRegion(void *mem) { m_ExHandler->UnregisterAppMemory(mem); } -private: - google_breakpad::ExceptionHandler *m_ExHandler; -}; - -#else - +// crash-handler is removed #define RDOC_CRASH_HANDLER OPTION_OFF - -#endif diff --git a/renderdoc/data/renderdoc.rc b/renderdoc/data/renderdoc.rc index 8ce08a39b..08b0b2d1c 100644 --- a/renderdoc/data/renderdoc.rc +++ b/renderdoc/data/renderdoc.rc @@ -61,84 +61,9 @@ END LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK #pragma code_page(1252) -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION RENDERDOC_VERSION_MAJOR,RENDERDOC_VERSION_MINOR,0,0 - PRODUCTVERSION RENDERDOC_VERSION_MAJOR,RENDERDOC_VERSION_MINOR,0,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "080904b0" - BEGIN - VALUE "CompanyName", "Baldur Karlsson" - VALUE "FileDescription", "Core DLL for RenderDoc - https://renderdoc.org/" - VALUE "FileVersion", MAJOR_MINOR_VERSION_STRING ".0.0" - VALUE "InternalName", "renderdoc.dll" - VALUE "LegalCopyright", "Copyright © 2016 Baldur Karlsson" - VALUE "OriginalFilename", "renderdoc.dll" - VALUE "ProductName", "RenderDoc" - VALUE "ProductVersion", FULL_VERSION_STRING - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x809, 1200 - END -END - #endif // English (United Kingdom) resources ///////////////////////////////////////////////////////////////////////////// -RESOURCE_debugdisplay_hlsl TYPE_EMBED "hlsl/debugdisplay.hlsl" -RESOURCE_debugtext_hlsl TYPE_EMBED "hlsl/debugtext.hlsl" -RESOURCE_debugcommon_hlsl TYPE_EMBED "hlsl/debugcommon.hlsl" -RESOURCE_histogram_hlsl TYPE_EMBED "hlsl/histogram.hlsl" -RESOURCE_debugcbuffers_h TYPE_EMBED "hlsl/debugcbuffers.h" -RESOURCE_multisample_hlsl TYPE_EMBED "hlsl/multisample.hlsl" -RESOURCE_mesh_hlsl TYPE_EMBED "hlsl/mesh.hlsl" - -RESOURCE_sourcecodepro_ttf TYPE_EMBED "sourcecodepro.ttf" - -RESOURCE_glsl_blit_vert TYPE_EMBED "glsl/blit.vert" -RESOURCE_glsl_checkerboard_frag TYPE_EMBED "glsl/checkerboard.frag" -RESOURCE_glsl_texdisplay_frag TYPE_EMBED "glsl/texdisplay.frag" -RESOURCE_glsl_text_vert TYPE_EMBED "glsl/text.vert" -RESOURCE_glsl_text_frag TYPE_EMBED "glsl/text.frag" -RESOURCE_glsl_fixedcol_frag TYPE_EMBED "glsl/fixedcol.frag" -RESOURCE_glsl_mesh_vert TYPE_EMBED "glsl/mesh.vert" -RESOURCE_glsl_mesh_geom TYPE_EMBED "glsl/mesh.geom" -RESOURCE_glsl_mesh_frag TYPE_EMBED "glsl/mesh.frag" -RESOURCE_glsl_minmaxtile_comp TYPE_EMBED "glsl/minmaxtile.comp" -RESOURCE_glsl_minmaxresult_comp TYPE_EMBED "glsl/minmaxresult.comp" -RESOURCE_glsl_histogram_comp TYPE_EMBED "glsl/histogram.comp" -RESOURCE_glsl_outline_frag TYPE_EMBED "glsl/outline.frag" -RESOURCE_glsl_debuguniforms_h TYPE_EMBED "glsl/debuguniforms.h" -RESOURCE_glsl_gl_texsample_h TYPE_EMBED "glsl/gl_texsample.h" -RESOURCE_glsl_vk_texsample_h TYPE_EMBED "glsl/vk_texsample.h" -RESOURCE_glsl_quadresolve_frag TYPE_EMBED "glsl/quadresolve.frag" -RESOURCE_glsl_quadwrite_frag TYPE_EMBED "glsl/quadwrite.frag" -RESOURCE_glsl_mesh_comp TYPE_EMBED "glsl/mesh.comp" -RESOURCE_glsl_array2ms_comp TYPE_EMBED "glsl/array2ms.comp" -RESOURCE_glsl_ms2array_comp TYPE_EMBED "glsl/ms2array.comp" -RESOURCE_glsl_trisize_geom TYPE_EMBED "glsl/trisize.geom" -RESOURCE_glsl_trisize_frag TYPE_EMBED "glsl/trisize.frag" -RESOURCE_glsl_deptharr2ms_frag TYPE_EMBED "glsl/deptharr2ms.frag" -RESOURCE_glsl_depthms2arr_frag TYPE_EMBED "glsl/depthms2arr.frag" -RESOURCE_glsl_gles_texsample_h TYPE_EMBED "glsl/gles_texsample.h" - #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // diff --git a/renderdoc/data/resource.h b/renderdoc/data/resource.h index e69faa013..4a1c86d32 100644 --- a/renderdoc/data/resource.h +++ b/renderdoc/data/resource.h @@ -2,54 +2,52 @@ // Microsoft Visual C++ generated include file. // Used by renderdoc.rc // -#define TYPE_EMBED 256 +#define TYPE_EMBED 256 -#define RESOURCE_debugdisplay_hlsl 101 -#define RESOURCE_debugtext_hlsl 102 -#define RESOURCE_debugcbuffers_h 103 -#define RESOURCE_debugcommon_hlsl 104 -#define RESOURCE_histogram_hlsl 105 -#define RESOURCE_multisample_hlsl 106 -#define RESOURCE_mesh_hlsl 107 +#define RESOURCE_debugdisplay_hlsl 101 +#define RESOURCE_debugtext_hlsl 102 +#define RESOURCE_debugcbuffers_h 103 +#define RESOURCE_debugcommon_hlsl 104 +#define RESOURCE_histogram_hlsl 105 +#define RESOURCE_multisample_hlsl 106 +#define RESOURCE_mesh_hlsl 107 -#define RESOURCE_sourcecodepro_ttf 301 +#define RESOURCE_sourcecodepro_ttf 301 -#define RESOURCE_glsl_blit_vert 401 +#define RESOURCE_glsl_blit_vert 401 #define RESOURCE_glsl_checkerboard_frag 402 -#define RESOURCE_glsl_texdisplay_frag 403 -#define RESOURCE_glsl_text_vert 404 -#define RESOURCE_glsl_text_frag 405 -#define RESOURCE_glsl_fixedcol_frag 408 -#define RESOURCE_glsl_mesh_vert 409 -#define RESOURCE_glsl_mesh_geom 410 -#define RESOURCE_glsl_mesh_frag 411 -#define RESOURCE_glsl_minmaxtile_comp 412 +#define RESOURCE_glsl_texdisplay_frag 403 +#define RESOURCE_glsl_text_vert 404 +#define RESOURCE_glsl_text_frag 405 +#define RESOURCE_glsl_fixedcol_frag 408 +#define RESOURCE_glsl_mesh_vert 409 +#define RESOURCE_glsl_mesh_geom 410 +#define RESOURCE_glsl_mesh_frag 411 +#define RESOURCE_glsl_minmaxtile_comp 412 #define RESOURCE_glsl_minmaxresult_comp 413 -#define RESOURCE_glsl_histogram_comp 414 -#define RESOURCE_glsl_outline_frag 415 -#define RESOURCE_glsl_debuguniforms_h 416 -#define RESOURCE_glsl_gl_texsample_h 417 -#define RESOURCE_glsl_vk_texsample_h 418 -#define RESOURCE_glsl_quadresolve_frag 419 -#define RESOURCE_glsl_quadwrite_frag 420 -#define RESOURCE_glsl_mesh_comp 421 -#define RESOURCE_glsl_array2ms_comp 422 -#define RESOURCE_glsl_ms2array_comp 423 -#define RESOURCE_glsl_trisize_geom 424 -#define RESOURCE_glsl_trisize_frag 425 -#define RESOURCE_glsl_deptharr2ms_frag 426 -#define RESOURCE_glsl_depthms2arr_frag 427 -#define RESOURCE_glsl_gles_texsample_h 428 +#define RESOURCE_glsl_histogram_comp 414 +#define RESOURCE_glsl_outline_frag 415 +#define RESOURCE_glsl_debuguniforms_h 416 +#define RESOURCE_glsl_gl_texsample_h 417 +#define RESOURCE_glsl_vk_texsample_h 418 +#define RESOURCE_glsl_quadresolve_frag 419 +#define RESOURCE_glsl_quadwrite_frag 420 +#define RESOURCE_glsl_mesh_comp 421 +#define RESOURCE_glsl_array2ms_comp 422 +#define RESOURCE_glsl_ms2array_comp 423 +#define RESOURCE_glsl_trisize_geom 424 +#define RESOURCE_glsl_trisize_frag 425 +#define RESOURCE_glsl_deptharr2ms_frag 426 +#define RESOURCE_glsl_depthms2arr_frag 427 +#define RESOURCE_glsl_gles_texsample_h 428 // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 114 -#define _APS_NEXT_COMMAND_VALUE 40029 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 114 +#define _APS_NEXT_COMMAND_VALUE 40029 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 #endif #endif - -#include "api/replay/version.h" diff --git a/renderdoc/driver/d3d11/d3d11_context.cpp b/renderdoc/driver/d3d11/d3d11_context.cpp index d1438a7de..abe15e402 100644 --- a/renderdoc/driver/d3d11/d3d11_context.cpp +++ b/renderdoc/driver/d3d11/d3d11_context.cpp @@ -837,7 +837,8 @@ void WrappedID3D11DeviceContext::ProcessChunk(uint64_t offset, D3D11ChunkType ch if(context->m_DrawcallStack.size() > 1) context->m_DrawcallStack.pop_back(); } - else if(context->m_State == READING) + + if(context->m_State == READING) { if(!m_AddedDrawcall) context->AddEvent(m_pSerialiser->GetDebugStr()); diff --git a/renderdoc/driver/d3d11/d3d11_device.cpp b/renderdoc/driver/d3d11/d3d11_device.cpp index bbe53cf88..c173e6cf4 100644 --- a/renderdoc/driver/d3d11/d3d11_device.cpp +++ b/renderdoc/driver/d3d11/d3d11_device.cpp @@ -2481,6 +2481,9 @@ void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, m_ReplayEventCount = 0; + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->StartFrameCapture(m_pDevice, NULL); + if(replayType == eReplay_Full) m_pImmediateContext->ReplayLog(EXECUTING, startEventID, endEventID, partial); else if(replayType == eReplay_WithoutDraw) @@ -2494,6 +2497,9 @@ void WrappedID3D11Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, for(int i = 0; i < m_ReplayEventCount; i++) D3D11MarkerRegion::End(); + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->EndFrameCapture(m_pDevice, NULL); + D3D11MarkerRegion::Set("!!!!RenderDoc Internal: Done replay"); } diff --git a/renderdoc/driver/d3d11/d3d11_replay.cpp b/renderdoc/driver/d3d11/d3d11_replay.cpp index b68cdeefa..1ea61663f 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.cpp +++ b/renderdoc/driver/d3d11/d3d11_replay.cpp @@ -1981,6 +1981,13 @@ void D3D11Replay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataSi ID3DDevice *GetD3D11DeviceIfAlloc(IUnknown *dev); +extern "C" __declspec(dllexport) HRESULT __cdecl RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain( + __in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, + __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, + UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, + __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, + __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext); + ReplayStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { RDCDEBUG("Creating a D3D11 replay device"); @@ -2015,18 +2022,6 @@ ReplayStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver **drive return ReplayStatus::APIInitFailed; } - typedef HRESULT(__cdecl * PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN)( - __in_opt IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT, - __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *, UINT FeatureLevels, UINT, - __in_opt CONST DXGI_SWAP_CHAIN_DESC *, __out_opt IDXGISwapChain **, __out_opt ID3D11Device **, - __out_opt D3D_FEATURE_LEVEL *, __out_opt ID3D11DeviceContext **); - - PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN createDevice = - (PFN_RENDERDOC_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress( - GetModuleHandleA("renderdoc.dll"), "RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain"); - - RDCASSERT(createDevice); - ID3D11Device *device = NULL; D3D11InitParams initParams; @@ -2080,8 +2075,9 @@ ReplayStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver **drive // check for feature level 11 support - passing NULL feature level array implicitly checks for // 11_0 before others - hr = createDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, NULL, NULL, - NULL, &maxFeatureLevel, NULL); + hr = RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, + 0, D3D11_SDK_VERSION, NULL, NULL, NULL, + &maxFeatureLevel, NULL); bool warpFallback = false; @@ -2099,7 +2095,7 @@ ReplayStatus D3D11_CreateReplayDevice(const char *logfile, IReplayDriver **drive hr = E_FAIL; for(;;) { - hr = createDevice( + hr = RENDERDOC_CreateWrappedD3D11DeviceAndSwapChain( /*pAdapter=*/NULL, driverType, /*Software=*/NULL, flags, /*pFeatureLevels=*/featureLevelArray, /*nFeatureLevels=*/numFeatureLevels, D3D11_SDK_VERSION, /*pSwapChainDesc=*/NULL, (IDXGISwapChain **)NULL, (ID3D11Device **)&device, diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index ed6c5388e..bbb027c96 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -2523,6 +2523,9 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, GetQueue(), StringFormat::Fmt("!!!!RenderDoc Internal: RenderDoc Replay %d (%d): %u->%u", (int)replayType, (int)partial, startEventID, endEventID)); + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->StartFrameCapture(m_pDevice, NULL); + { D3D12CommandData &cmd = *m_Queue->GetCommandData(); @@ -2573,6 +2576,9 @@ void WrappedID3D12Device::ReplayLog(uint32_t startEventID, uint32_t endEventID, #endif } + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->EndFrameCapture(m_pDevice, NULL); + D3D12MarkerRegion::Set(GetQueue(), "!!!!RenderDoc Internal: Done replay"); // ensure all UAV writes have finished before subsequent work diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index 265e7c514..6acdc1c45 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -4515,6 +4515,9 @@ void WrappedOpenGL::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay GLMarkerRegion::Set(StringFormat::Fmt("!!!!RenderDoc Internal: Replay %d (%d): %u->%u", (int)replayType, (int)partial, startEventID, endEventID)); + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->StartFrameCapture(GetCtx(), NULL); + m_ReplayEventCount = 0; if(replayType == eReplay_Full) @@ -4530,5 +4533,8 @@ void WrappedOpenGL::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay for(int i = 0; i < m_ReplayEventCount; i++) GLMarkerRegion::End(); + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->EndFrameCapture(GetCtx(), NULL); + GLMarkerRegion::Set("!!!!RenderDoc Internal: Done replay"); } diff --git a/renderdoc/driver/gl/gl_replay.cpp b/renderdoc/driver/gl/gl_replay.cpp index c1883d238..92b36cacb 100644 --- a/renderdoc/driver/gl/gl_replay.cpp +++ b/renderdoc/driver/gl/gl_replay.cpp @@ -3448,7 +3448,7 @@ bool GLReplay::IsOutputWindowVisible(uint64_t id) // defined in gl_replay_.cpp ReplayStatus GL_CreateReplayDevice(const char *logfile, IReplayDriver **driver); -static DriverRegistration GLDriverRegistration(RDC_OpenGL, "OpenGL", &GL_CreateReplayDevice); +DriverRegistration GLDriverRegistration(RDC_OpenGL, "OpenGL", &GL_CreateReplayDevice); #endif @@ -3457,6 +3457,6 @@ static DriverRegistration GLDriverRegistration(RDC_OpenGL, "OpenGL", &GL_CreateR // defined in gl_replay_egl.cpp ReplayStatus GLES_CreateReplayDevice(const char *logfile, IReplayDriver **driver); -static DriverRegistration GLESDriverRegistration(RDC_OpenGLES, "OpenGLES", &GLES_CreateReplayDevice); +DriverRegistration GLESDriverRegistration(RDC_OpenGLES, "OpenGLES", &GLES_CreateReplayDevice); #endif diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 65c544f7c..df3643195 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -2367,6 +2367,11 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay VkMarkerRegion::Set(StringFormat::Fmt("!!!!RenderDoc Internal: RenderDoc Replay %d (%d): %u->%u", (int)replayType, (int)partial, startEventID, endEventID)); +#define RENDERDOC_DEVICEPOINTER_FROM_VKINSTANCE(inst) (*((void **)(inst))) + + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->StartFrameCapture(NULL, NULL); + { if(!partial) { @@ -2496,6 +2501,9 @@ void WrappedVulkan::ReplayLog(uint32_t startEventID, uint32_t endEventID, Replay #endif } + if(ConverterAPI && replayType != eReplay_OnlyDraw) + ConverterAPI->EndFrameCapture(NULL, NULL); + VkMarkerRegion::Set("!!!!RenderDoc Internal: Done replay"); } diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index e528afa97..5bfa829fd 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -5361,9 +5361,9 @@ ReplayStatus Vulkan_CreateReplayDevice(const char *logfile, IReplayDriver **driv { RDCDEBUG("Creating a VulkanReplay replay device"); - // disable the layer env var, just in case the user left it set from a previous capture run + // *enable* the layer env var so we can capture. Process::RegisterEnvironmentModification( - EnvironmentModification(EnvMod::Set, EnvSep::NoSep, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "0")); + EnvironmentModification(EnvMod::Set, EnvSep::NoSep, "ENABLE_VULKAN_RENDERDOC_CAPTURE", "1")); // disable buggy and user-hostile NV optimus layer, which can completely delete physical devices // (not just rearrange them) and cause problems between capture and replay. @@ -5429,4 +5429,4 @@ struct VulkanDriverRegistration } }; -static VulkanDriverRegistration VkDriverRegistration; +VulkanDriverRegistration VkDriverRegistration; diff --git a/renderdoc/os/posix/posix_libentry.cpp b/renderdoc/os/posix/posix_libentry.cpp index b675f08ab..66df2c47a 100644 --- a/renderdoc/os/posix/posix_libentry.cpp +++ b/renderdoc/os/posix/posix_libentry.cpp @@ -22,70 +22,4 @@ * THE SOFTWARE. ******************************************************************************/ -#include "core/core.h" -#include "hooks/hooks.h" -#include "os/os_specific.h" - -void dlopen_hook_init(); - -void readCapOpts(const char *str, CaptureOptions *opts) -{ - // serialise from string with two chars per byte - byte *b = (byte *)opts; - for(size_t i = 0; i < sizeof(CaptureOptions); i++) - *(b++) = (byte(str[i * 2 + 0] - 'a') << 4) | byte(str[i * 2 + 1] - 'a'); -} - -// DllMain equivalent -void library_loaded() -{ - string curfile; - FileIO::GetExecutableFilename(curfile); - - if(curfile.find("/renderdoccmd") != string::npos || - curfile.find("/renderdocui") != string::npos || curfile.find("/qrenderdoc") != string::npos || - curfile.find("org.renderdoc.renderdoccmd") != string::npos) - { - RDCDEBUG("Not creating hooks - in replay app"); - - RenderDoc::Inst().SetReplayApp(true); - - RenderDoc::Inst().Initialise(); - - return; - } - else - { - RenderDoc::Inst().Initialise(); - - char *logfile = getenv("RENDERDOC_LOGFILE"); - char *opts = getenv("RENDERDOC_CAPTUREOPTS"); - - if(opts) - { - string optstr = opts; - - CaptureOptions optstruct; - readCapOpts(optstr.c_str(), &optstruct); - - RenderDoc::Inst().SetCaptureOptions(optstruct); - } - - if(logfile) - { - RenderDoc::Inst().SetLogFile(logfile); - } - - RDCLOG("Loading into %s", curfile.c_str()); - - LibraryHooks::GetInstance().CreateHooks(); - } -} - -// wrap in a struct to enforce ordering. This file is -// linked last, so all other global struct constructors -// should run first -struct init -{ - init() { library_loaded(); } -} do_init; +// not used in converter \ No newline at end of file diff --git a/renderdoc/os/win32/win32_libentry.cpp b/renderdoc/os/win32/win32_libentry.cpp index 9d51afba2..40e6ad5a4 100644 --- a/renderdoc/os/win32/win32_libentry.cpp +++ b/renderdoc/os/win32/win32_libentry.cpp @@ -23,62 +23,4 @@ * THE SOFTWARE. ******************************************************************************/ -// win32_libentry.cpp : Defines the entry point for the DLL -#include -#include -#include "common/common.h" -#include "core/core.h" -#include "hooks/hooks.h" -#include "serialise/string_utils.h" - -static BOOL add_hooks() -{ - wchar_t curFile[512]; - GetModuleFileNameW(NULL, curFile, 512); - - wstring f = strlower(wstring(curFile)); - - // bail immediately if we're in a system process. We don't want to hook, log, anything - - // this instance is being used for a shell extension. - if(f.find(L"dllhost.exe") != wstring::npos || f.find(L"explorer.exe") != wstring::npos) - { -#ifndef _RELEASE - OutputDebugStringA("Hosting " STRINGIZE(RDOC_DLL_FILE) ".dll in shell process\n"); -#endif - return TRUE; - } - - if(f.find(CONCAT(L, STRINGIZE(RDOC_DLL_FILE)) L"cmd.exe") != wstring::npos || - f.find(CONCAT(L, STRINGIZE(RDOC_DLL_FILE)) L"ui.vshost.exe") != wstring::npos || - f.find(L"q" CONCAT(L, STRINGIZE(RDOC_DLL_FILE)) L".exe") != wstring::npos || - f.find(CONCAT(L, STRINGIZE(RDOC_DLL_FILE)) L"ui.exe") != wstring::npos) - { - RDCDEBUG("Not creating hooks - in replay app"); - - RenderDoc::Inst().SetReplayApp(true); - - RenderDoc::Inst().Initialise(); - - return true; - } - - RenderDoc::Inst().Initialise(); - - RDCLOG("Loading into %ls", curFile); - - LibraryHooks::GetInstance().CreateHooks(); - - return TRUE; -} - -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - if(ul_reason_for_call == DLL_PROCESS_ATTACH) - { - BOOL ret = add_hooks(); - SetLastError(0); - return ret; - } - - return TRUE; -} +// not used in converter \ No newline at end of file diff --git a/renderdoc/renderdoc.vcxproj b/renderdoc/renderdoc.vcxproj index 59e9f1486..38cfd4338 100644 --- a/renderdoc/renderdoc.vcxproj +++ b/renderdoc/renderdoc.vcxproj @@ -23,16 +23,17 @@ Win32Proj renderdoc renderdoc + 8.1 - DynamicLibrary + StaticLibrary true Unicode v140 - false + false true diff --git a/renderdoc/replay/entry_points.cpp b/renderdoc/replay/entry_points.cpp index 0c90fe247..67393c84b 100644 --- a/renderdoc/replay/entry_points.cpp +++ b/renderdoc/replay/entry_points.cpp @@ -424,16 +424,6 @@ extern "C" RENDERDOC_API bool32 RENDERDOC_CC RENDERDOC_GetThumbnail(const char * return true; } -extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeArrayMem(const void *mem) -{ - rdctype::array::deallocate(mem); -} - -extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_AllocArrayMem(uint64_t sz) -{ - return rdctype::array::allocate((size_t)sz); -} - extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_EnumerateRemoteTargets(const char *host, uint32_t nextIdent) { diff --git a/renderdoccmd/3rdparty/cmdline/cmdline.h b/renderdoccmd/3rdparty/cmdline/cmdline.h deleted file mode 100644 index be35c6042..000000000 --- a/renderdoccmd/3rdparty/cmdline/cmdline.h +++ /dev/null @@ -1,829 +0,0 @@ -/* - Copyright (c) 2009, Hideyuki Tanaka - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY ''AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef max -#undef max -#endif - -namespace cmdline{ - -namespace detail{ - -template -class lexical_cast_t{ -public: - static Target cast(const Source &arg){ - Target ret; - std::stringstream ss; - if (!(ss<>ret && ss.eof())) - throw std::bad_cast(); - - return ret; - } -}; - -template -class lexical_cast_t{ -public: - static Target cast(const Source &arg){ - return arg; - } -}; - -template -class lexical_cast_t{ -public: - static std::string cast(const Source &arg){ - std::ostringstream ss; - ss< -class lexical_cast_t{ -public: - static Target cast(const std::string &arg){ - Target ret; - std::istringstream ss(arg); - if (!(ss>>ret && ss.eof())) - throw std::bad_cast(); - return ret; - } -}; - -template -struct is_same { - static const bool value = false; -}; - -template -struct is_same{ - static const bool value = true; -}; - -template -Target lexical_cast(const Source &arg) -{ - return lexical_cast_t::value>::cast(arg); -} - -template -std::string readable_typename(); - -template -std::string default_value(T def) -{ - return detail::lexical_cast(def); -} - -template <> -inline std::string readable_typename() -{ - return "string"; -} - -template <> -inline std::string readable_typename() -{ - return "int"; -} - -template <> -inline std::string readable_typename() -{ - return "uint"; -} - -} // detail - -//----- - -class cmdline_error : public std::exception { -public: - cmdline_error(const std::string &msg): msg(msg){} - ~cmdline_error() throw() {} - const char *what() const throw() { return msg.c_str(); } -private: - std::string msg; -}; - -template -struct default_reader{ - T operator()(const std::string &str){ - return detail::lexical_cast(str); - } - std::string description() const { return ""; } -}; - -template -struct range_reader{ - range_reader(const T &low, const T &high): low(low), high(high) {} - T operator()(const std::string &s) const { - T ret=default_reader()(s); - if (!(ret>=low && ret<=high)) - throw cmdline::cmdline_error(description()); - return ret; - } - std::string description() const { return "Must be within [" + detail::lexical_cast(low) + ", " + detail::lexical_cast(high) + "]"; } -private: - T low, high; -}; - -template -range_reader range(const T &low, const T &high) -{ - return range_reader(low, high); -} - -template -struct oneof_reader{ - T operator()(const std::string &s){ - T ret=default_reader()(s); - if (std::find(alt.begin(), alt.end(), ret)==alt.end()) - throw cmdline::cmdline_error("'" + s + "' is not one of the accepted values"); - return ret; - } - void add(const T &v){ alt.push_back(v); } - std::string description() const - { - std::string ret = "Options are:"; - for(size_t i=0; i < alt.size(); i++) - ret += "\n * " + detail::lexical_cast(alt[i]); - return ret; - } -private: - std::vector alt; -}; - -template -oneof_reader oneof(T a1) -{ - oneof_reader ret; - ret.add(a1); - return ret; -} - -template -oneof_reader oneof(T a1, T a2) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4, T a5) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - ret.add(a5); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - ret.add(a5); - ret.add(a6); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - ret.add(a5); - ret.add(a6); - ret.add(a7); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - ret.add(a5); - ret.add(a6); - ret.add(a7); - ret.add(a8); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - ret.add(a5); - ret.add(a6); - ret.add(a7); - ret.add(a8); - ret.add(a9); - return ret; -} - -template -oneof_reader oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10) -{ - oneof_reader ret; - ret.add(a1); - ret.add(a2); - ret.add(a3); - ret.add(a4); - ret.add(a5); - ret.add(a6); - ret.add(a7); - ret.add(a8); - ret.add(a9); - ret.add(a10); - return ret; -} - -//----- - -class parser{ -public: - parser(){ - stop = false; - } - ~parser(){ - for (std::map::iterator p=options.begin(); - p!=options.end(); p++) - delete p->second; - } - - void add(const std::string &name, - char short_name=0, - const std::string &desc=""){ - if (options.count(name)) throw cmdline_error("multiple definition: "+name); - options[name]=new option_without_value(name, short_name, desc); - ordered.push_back(options[name]); - } - - template - void add(const std::string &name, - char short_name=0, - const std::string &desc="", - bool need=true, - const T def=T()){ - add(name, short_name, desc, need, def, default_reader()); - } - - template - void add(const std::string &name, - char short_name=0, - const std::string &desc="", - bool need=true, - const T def=T(), - F reader=F()){ - if (options.count(name)) throw cmdline_error("multiple definition: "+name); - options[name]=new option_with_value_with_reader(name, short_name, need, def, desc, reader); - ordered.push_back(options[name]); - } - - void set_header(const std::string &f){ - hdr=f; - } - - void set_footer(const std::string &f){ - ftr=f; - } - - void stop_at_rest(bool s){ - stop=s; - } - - void set_program_name(const std::string &name){ - prog_name=name; - } - - bool exist(const std::string &name) const { - if (options.count(name)==0) throw cmdline_error("there is no flag: --"+name); - return options.find(name)->second->has_set(); - } - - template - const T &get(const std::string &name) const { - if (options.count(name)==0) throw cmdline_error("there is no flag: --"+name); - const option_with_value *p=dynamic_cast*>(options.find(name)->second); - if (p==NULL) throw cmdline_error("type mismatch flag '"+name+"'"); - return p->get(); - } - - const std::vector &rest() const { - return others; - } - - bool parse(const std::vector &args, bool processed_arg0 = false){ - int argc=static_cast(args.size()); - std::vector argv(argc); - - for (int i=0; i lookup; - for (std::map::iterator p=options.begin(); - p!=options.end(); p++){ - if (p->first.length()==0) continue; - char initial=p->second->short_name(); - if (initial){ - if (lookup.count(initial)>0){ - lookup[initial]=""; - errors.push_back(std::string("short option '")+initial+"' is ambiguous"); - return false; - } - else lookup[initial]=p->first; - } - } - - bool found_others = false; - - for (int i=processed_arg0 ? 0 : 1; imust()) - oss<short_description()<<" "; - } - - oss<<"[options ...] "<name().length()); - } - for (size_t i=0; ishort_name()){ - oss<<" -"<short_name()<<", "; - } - else{ - oss<<" "; - } - - oss<<"--"<name(); - for (size_t j=ordered[i]->name().length(); jdescription(); - - // allow multiline descriptions, align them properly - size_t nl = desc.find('\n'); - - while(nl != std::string::npos) - { - std::string firstline = desc.substr(0, nl); - desc = desc.substr(nl+1); - - // print the first line - oss<set()){ - errors.push_back("option needs value: --"+name); - return; - } - } - - void set_option(const std::string &name, const std::string &value){ - if (options.count(name)==0){ - errors.push_back("undefined option: --"+name); - return; - } - if (!options[name]->set(value)){ - std::string err_details = options[name]->error_details(); - if(err_details.empty()) - errors.push_back("option value is invalid: --"+name+"="+value); - else - errors.push_back("option value is invalid: --"+name+"="+value+" ("+err_details+")"); - return; - } - } - - class option_base{ - public: - virtual ~option_base(){} - - virtual bool has_value() const=0; - virtual bool set()=0; - virtual bool set(const std::string &value)=0; - virtual bool has_set() const=0; - virtual bool valid() const=0; - virtual bool must() const=0; - - virtual const std::string error_details() { return ""; } - - virtual const std::string &name() const=0; - virtual char short_name() const=0; - virtual const std::string &description() const=0; - virtual std::string short_description() const=0; - }; - - class option_without_value : public option_base { - public: - option_without_value(const std::string &name, - char short_name, - const std::string &desc) - :nam(name), snam(short_name), desc(desc), has(false){ - } - ~option_without_value(){} - - bool has_value() const { return false; } - - bool set(){ - has=true; - return true; - } - - bool set(const std::string &){ - return false; - } - - bool has_set() const { - return has; - } - - bool valid() const{ - return true; - } - - bool must() const{ - return false; - } - - const std::string &name() const{ - return nam; - } - - char short_name() const{ - return snam; - } - - const std::string &description() const { - return desc; - } - - std::string short_description() const{ - return "--"+nam; - } - - virtual const std::string error_details() { return nam+" can't have parameter"; } - - private: - std::string nam; - char snam; - std::string desc; - bool has; - }; - - template - class option_with_value : public option_base { - public: - option_with_value(const std::string &name, - char short_name, - bool need, - const T &def, - const std::string &desc) - : nam(name), snam(short_name), need(need), has(false) - , def(def), actual(def) { - this->desc=full_description(desc); - this->error = " (Unknown error)"; - } - ~option_with_value(){} - - const T &get() const { - return actual; - } - - bool has_value() const { return true; } - - bool set(){ - return false; - } - - bool set(const std::string &value){ - try{ - actual=read(value); - has=true; - } - catch(const std::exception &e){ - error = e.what(); - return false; - } - return true; - } - - virtual const std::string error_details() { return error; } - - bool has_set() const{ - return has; - } - - bool valid() const{ - if (need && !has) return false; - return true; - } - - bool must() const{ - return need; - } - - const std::string &name() const{ - return nam; - } - - char short_name() const{ - return snam; - } - - const std::string &description() const { - return desc; - } - - std::string short_description() const{ - return "--"+nam+"=<"+detail::readable_typename() + ">"; - } - - protected: - std::string full_description(const std::string &desc){ - std::string defval = detail::default_value(def); - - return - desc+" ("+ - (need?"":"optional ")+ - detail::readable_typename()+ - (!need && !defval.empty() ? "="+defval : "")+ - ")"; - } - - virtual T read(const std::string &s)=0; - - std::string nam; - char snam; - bool need; - std::string desc; - std::string error; - - bool has; - T def; - T actual; - }; - - template - class option_with_value_with_reader : public option_with_value { - public: - option_with_value_with_reader(const std::string &name, - char short_name, - bool need, - const T def, - const std::string &desc, - F reader) - : option_with_value(name, short_name, need, def, desc), reader(reader){ - std::string reader_description = this->reader.description(); - - if(!reader_description.empty()) - this->desc = this->desc + " " + reader_description; - } - - private: - T read(const std::string &s){ - return reader(s); - } - - F reader; - }; - - std::map options; - std::vector ordered; - std::string hdr; - std::string ftr; - bool stop; - - std::string prog_name; - std::vector others; - - std::vector errors; -}; - -} // cmdline diff --git a/renderdoccmd/CMakeLists.txt b/renderdoccmd/CMakeLists.txt index 0b44b442c..8c0b59e5d 100644 --- a/renderdoccmd/CMakeLists.txt +++ b/renderdoccmd/CMakeLists.txt @@ -1,5 +1,5 @@ set(sources renderdoccmd.cpp) -set(includes PRIVATE ${CMAKE_SOURCE_DIR}/renderdoc/api) +set(includes PRIVATE ${CMAKE_SOURCE_DIR}/renderdoc) set(libraries PRIVATE renderdoc) if(APPLE) @@ -37,6 +37,18 @@ elseif(UNIX) # Make sure that for the target executable we don't throw away # any shared libraries. set(LINKER_FLAGS "-Wl,--no-as-needed") + + if(ENABLE_GL) + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--undefined,GLDriverRegistration") + endif() + + if(ENABLE_GLES) + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--undefined,GLESDriverRegistration") + endif() + + if(ENABLE_VULKAN) + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,--undefined,VkDriverRegistration") + endif() endif() if(ANDROID) @@ -48,13 +60,13 @@ else() set(CMAKE_INSTALL_RPATH "$ORIGIN/:$ORIGIN/../lib/") set(CMAKE_EXE_LINKER_FLAGS "${LINKER_FLAGS}") - add_executable(renderdoccmd ${sources}) + add_executable(rdcconvert ${sources}) endif() -target_include_directories(renderdoccmd ${includes}) -target_link_libraries(renderdoccmd ${libraries}) +target_include_directories(rdcconvert ${includes}) +target_link_libraries(rdcconvert ${libraries}) -install (TARGETS renderdoccmd DESTINATION bin) +install (TARGETS rdcconvert DESTINATION bin) if(ANDROID) if(NOT DEFINED ENV{JAVA_HOME}) diff --git a/qrenderdoc/Resources/icon.ico b/renderdoccmd/icon.ico similarity index 100% rename from qrenderdoc/Resources/icon.ico rename to renderdoccmd/icon.ico diff --git a/renderdoccmd/renderdoccmd.cpp b/renderdoccmd/renderdoccmd.cpp index 9d29bbcc1..8e6ae3d2f 100644 --- a/renderdoccmd/renderdoccmd.cpp +++ b/renderdoccmd/renderdoccmd.cpp @@ -24,857 +24,129 @@ ******************************************************************************/ #include "renderdoccmd.h" -#include -#include +#include +#include #include +#include "3rdparty/tinyfiledialogs/tinyfiledialogs.h" -using std::string; -using std::wstring; +RENDERDOC_API_1_1_1 *ConverterAPI = NULL; +RENDERDOC_API_1_1_1 *RENDERDOC_LoadConverter(); -bool usingKillSignal = false; -volatile uint32_t killSignal = false; - -rdctype::array convertArgs(const std::vector &args) +int renderdoccmd(std::vector &argv) { - rdctype::array ret; - ret.create((int)args.size()); - for(size_t i = 0; i < args.size(); i++) - ret[i] = args[i]; - return ret; -} + std::string filename; -void readCapOpts(const std::string &str, CaptureOptions *opts) -{ - if(str.length() < sizeof(CaptureOptions)) - return; + bool silent = false; - // serialise from string with two chars per byte - byte *b = (byte *)opts; - for(size_t i = 0; i < sizeof(CaptureOptions); i++) - *(b++) = (byte(str[i * 2 + 0] - 'a') << 4) | byte(str[i * 2 + 1] - 'a'); -} - -void DisplayRendererPreview(IReplayController *renderer, uint32_t width, uint32_t height) -{ - if(renderer == NULL) - return; - - rdctype::array texs = renderer->GetTextures(); - - TextureDisplay d; - d.mip = 0; - d.sampleIdx = ~0U; - d.overlay = DebugOverlay::NoOverlay; - d.typeHint = CompType::Typeless; - d.CustomShader = ResourceId(); - d.HDRMul = -1.0f; - d.linearDisplayAsGamma = true; - d.FlipY = false; - d.rangemin = 0.0f; - d.rangemax = 1.0f; - d.scale = 1.0f; - d.offx = 0.0f; - d.offy = 0.0f; - d.sliceFace = 0; - d.rawoutput = false; - d.lightBackgroundColor = FloatVector(0.81f, 0.81f, 0.81f, 1.0f); - d.darkBackgroundColor = FloatVector(0.57f, 0.57f, 0.57f, 1.0f); - d.Red = d.Green = d.Blue = true; - d.Alpha = false; - - for(int32_t i = 0; i < texs.count; i++) + if(argv.size() > 1) { - if(texs[i].creationFlags & TextureCategory::SwapBuffer) + if(argv[1] == "--help" || argv[1] == "-help" || argv[1] == "/help" || argv[1] == "help" || + argv[1] == "--h" || argv[1] == "-h" || argv[1] == "-?" || argv[1] == "/?" || argv[1] == "h") { - d.texid = texs[i].ID; - break; - } - } - - rdctype::array draws = renderer->GetDrawcalls(); - - if(draws.count > 0 && draws[draws.count - 1].flags & DrawFlags::Present) - { - ResourceId id = draws[draws.count - 1].copyDestination; - if(id != ResourceId()) - d.texid = id; - } - - DisplayRendererPreview(renderer, d, width, height); -} - -std::map commands; -std::map aliases; - -void add_command(const std::string &name, Command *cmd) -{ - commands[name] = cmd; -} - -void add_alias(const std::string &alias, const std::string &command) -{ - aliases[alias] = command; -} - -static void clean_up() -{ - for(auto it = commands.begin(); it != commands.end(); ++it) - delete it->second; -} - -static int command_usage(std::string command = "") -{ - if(!command.empty()) - std::cerr << command << " is not a valid command." << std::endl << std::endl; - - std::cerr << "Usage: renderdoccmd [args ...]" << std::endl; - std::cerr << "Command line tool for capture & replay with RenderDoc." << std::endl << std::endl; - - std::cerr << "Command can be one of:" << std::endl; - - size_t max_width = 0; - for(auto it = commands.begin(); it != commands.end(); ++it) - { - if(it->second->IsInternalOnly()) - continue; - - max_width = std::max(max_width, it->first.length()); - } - - for(auto it = commands.begin(); it != commands.end(); ++it) - { - if(it->second->IsInternalOnly()) - continue; - - std::cerr << " " << it->first; - for(size_t n = it->first.length(); n < max_width + 4; n++) - std::cerr << ' '; - std::cerr << it->second->Description() << std::endl; - } - std::cerr << std::endl; - - std::cerr << "To see details of any command, see 'renderdoccmd --help'" << std::endl - << std::endl; - - std::cerr << "For more information, see ." << std::endl; - - return 2; -} - -static std::vector version_lines; - -struct VersionCommand : public Command -{ - VersionCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) {} - virtual const char *Description() { return "Print version information"; } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - std::cout << "renderdoccmd " << (sizeof(uintptr_t) == sizeof(uint64_t) ? "x64" : "x86") - << " v" MAJOR_MINOR_VERSION_STRING << " built from " << GIT_COMMIT_HASH << std::endl; - -#if defined(DISTRIBUTION_VERSION) - std::cout << "Packaged for " << DISTRIBUTION_NAME << " (" << DISTRIBUTION_VERSION << ") - " - << DISTRIBUTION_CONTACT << std::endl; -#endif - - for(size_t i = 0; i < version_lines.size(); i++) - std::cout << version_lines[i] << std::endl; - - std::cout << std::endl; - - return 0; - } -}; - -void add_version_line(const std::string &str) -{ - version_lines.push_back(str); -} - -struct HelpCommand : public Command -{ - HelpCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) {} - virtual const char *Description() { return "Print this help message"; } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - command_usage(); - return 0; - } -}; - -struct ThumbCommand : public Command -{ - ThumbCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.set_footer(""); - parser.add("out", 'o', "The output filename to save the file to", true, "filename.jpg"); - parser.add("format", 'f', - "The format of the output file. If empty, detected from filename", false, "", - cmdline::oneof("jpg", "png", "bmp", "tga")); - parser.add( - "max-size", 's', - "The maximum dimension of the thumbnail. Default is 0, which is unlimited.", false, 0); - } - virtual const char *Description() { return "Saves a capture's embedded thumbnail to disk."; } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - std::vector rest = parser.rest(); - if(rest.empty()) - { - std::cerr << "Error: thumb command requires a capture filename." << std::endl - << std::endl - << parser.usage(); + std::cerr + << "This is the RenderDoc conversion utility to convert v0.x captures to a newer version." + << std::endl; + std::cerr + << "It must be able to find the newer renderdoc.dll. " + << "Either in the library search path or else a prompt will ask you to browse to it." + << std::endl; + std::cerr + << "Run either with a parameter to the file (i.e. drag the file onto this exe) " + << "or else you can run with no parameters and it will prompt you to browse to the file" + << std::endl; return 0; } - string filename = rest[0]; + filename = argv[1]; - rest.erase(rest.begin()); - - RENDERDOC_InitGlobalEnv(m_Env, convertArgs(rest)); - - string outfile = parser.get("out"); - - string format = parser.get("format"); - - FileType type = FileType::JPG; - - if(format == "png") + if(argv.size() > 2 && + (argv[2] == "--silent" || argv[2] == "--quiet" || argv[2] == "-q" || argv[2] == "-s")) { - type = FileType::PNG; + silent = true; } - else if(format == "tga") - { - type = FileType::TGA; - } - else if(format == "bmp") - { - type = FileType::BMP; - } - else - { - const char *dot = strrchr(outfile.c_str(), '.'); + } - if(dot != NULL && strstr(dot, "png")) - type = FileType::PNG; - else if(dot != NULL && strstr(dot, "tga")) - type = FileType::TGA; - else if(dot != NULL && strstr(dot, "bmp")) - type = FileType::BMP; - else if(dot != NULL && strstr(dot, "jpg")) - type = FileType::JPG; - else - std::cerr << "Couldn't guess format from '" << outfile << "', defaulting to jpg." - << std::endl; - } + RENDERDOC_API_1_1_1 *api = RENDERDOC_LoadConverter(); - rdctype::array buf; + if(!api) + return 1; - ICaptureFile *file = RENDERDOC_OpenCaptureFile(filename.c_str()); - if(file->OpenStatus() == ReplayStatus::Succeeded) - { - buf = file->GetThumbnail(FileType::JPG, 0); - } - else - { - std::cerr << "Couldn't open '" << filename << "'" << std::endl; - } - file->Shutdown(); + FILE *f = fopen(filename.c_str(), "rb"); + if(f) + fclose(f); + else + filename.clear(); - if(buf.empty()) - { - std::cerr << "Couldn't fetch the thumbnail in '" << filename << "'" << std::endl; - } - else - { - FILE *f = fopen(outfile.c_str(), "wb"); + if(filename.empty()) + { + const char *filter = "*.rdc"; + const char *ret = + tinyfd_openFileDialog("Locate file to convert", NULL, 1, &filter, "RenderDoc capture", 0); - if(!f) - { - std::cerr << "Couldn't open destination file '" << outfile << "'" << std::endl; - } - else - { - fwrite(buf.elems, 1, buf.count, f); - fclose(f); + if(ret) + filename = ret; + } - std::cout << "Wrote thumbnail from '" << filename << "' to '" << outfile << "'." << std::endl; - } - } + if(filename.empty()) + return 0; + ICaptureFile *file = RENDERDOC_OpenCaptureFile(filename.c_str()); + + if(file->OpenStatus() != ReplayStatus::Succeeded) + { + tinyfd_messageBox("Couldn't load file", "Couldn't load specified capture file", "ok", "error", 1); + return 1; + } + + if(!silent) + tinyfd_messageBox("Capture loading", + "The capture will load when you press OK. " + "This will happen invisibly, please wait.", + "ok", "info", 1); + + IReplayController *renderer = NULL; + ReplayStatus status = ReplayStatus::InternalError; + std::tie(status, renderer) = file->OpenCapture(NULL); + + file->Shutdown(); + + if(status == ReplayStatus::Succeeded) + { + // prime the pump a couple of times + for(size_t i = 0; i < 3; i++) + renderer->SetFrameEvent(10000000, true); + + if(!silent) + tinyfd_messageBox( + "Capture conversion ready", + "The capture is ready to convert. Press OK to begin, this may take a moment...", "ok", + "info", 1); + + // set up for capture and do the replay we'll capture + ConverterAPI = api; + renderer->SetFrameEvent(10000000, true); + ConverterAPI = NULL; + + if(!silent) + tinyfd_messageBox("Capture converted", + "The capture has been converted and output next to this exe.", "ok", "info", + 1); + + renderer->Shutdown(); return 0; } -}; -struct CaptureCommand : public Command -{ - CaptureCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.set_footer(" [program arguments]"); - parser.stop_at_rest(true); - } - virtual const char *Description() { return "Launches the given executable to capture."; } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return true; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &opts) - { - if(parser.rest().empty()) - { - std::cerr << "Error: capture command requires an executable to launch." << std::endl - << std::endl - << parser.usage(); - return 0; - } + tinyfd_messageBox("Capture open failed", "Failed to open and replay capture", "ok", "error", 1); - std::string executable = parser.rest()[0]; - std::string workingDir = parser.get("working-dir"); - std::string cmdLine; - std::string logFile = parser.get("capture-file"); - - for(size_t i = 1; i < parser.rest().size(); i++) - { - if(!cmdLine.empty()) - cmdLine += ' '; - - cmdLine += EscapeArgument(parser.rest()[i]); - } - - RENDERDOC_InitGlobalEnv(m_Env, rdctype::array()); - - std::cout << "Launching '" << executable << "'"; - - if(!cmdLine.empty()) - std::cout << " with params: " << cmdLine; - - std::cout << std::endl; - - rdctype::array env; - - uint32_t ident = RENDERDOC_ExecuteAndInject( - executable.c_str(), workingDir.empty() ? "" : workingDir.c_str(), - cmdLine.empty() ? "" : cmdLine.c_str(), env, logFile.empty() ? "" : logFile.c_str(), opts, - parser.exist("wait-for-exit")); - - if(ident == 0) - { - std::cerr << "Failed to create & inject." << std::endl; - return 2; - } - - if(parser.exist("wait-for-exit")) - { - std::cerr << "'" << executable << "' finished executing." << std::endl; - ident = 0; - } - else - { - std::cerr << "Launched as ID " << ident << std::endl; - } - - return ident; - } - - std::string EscapeArgument(const std::string &arg) - { - // nothing to escape or quote - if(arg.find_first_of(" \t\r\n\"") == std::string::npos) - return arg; - - // return arg in quotes, with any quotation marks escaped - std::string ret = arg; - - size_t i = ret.find('\"'); - while(i != std::string::npos) - { - ret.insert(ret.begin() + i, '\\'); - - i = ret.find('\"', i + 2); - } - - return '"' + ret + '"'; - } -}; - -struct InjectCommand : public Command -{ - InjectCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.add("PID", 0, "The process ID of the process to inject.", true); - } - virtual const char *Description() { return "Injects RenderDoc into a given running process."; } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return true; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &opts) - { - uint32_t PID = parser.get("PID"); - std::string workingDir = parser.get("working-dir"); - std::string logFile = parser.get("capture-file"); - - std::cout << "Injecting into PID " << PID << std::endl; - - rdctype::array env; - - RENDERDOC_InitGlobalEnv(m_Env, convertArgs(parser.rest())); - - uint32_t ident = RENDERDOC_InjectIntoProcess(PID, env, logFile.empty() ? "" : logFile.c_str(), - opts, parser.exist("wait-for-exit")); - - if(ident == 0) - { - std::cerr << "Failed to inject." << std::endl; - return 2; - } - - if(parser.exist("wait-for-exit")) - { - std::cerr << PID << " finished executing." << std::endl; - ident = 0; - } - else - { - std::cerr << "Launched as ID " << ident << std::endl; - } - - return ident; - } -}; - -struct RemoteServerCommand : public Command -{ - RemoteServerCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.add("daemon", 'd', "Go into the background."); - parser.add( - "host", 'h', "The interface to listen on. By default listens on all interfaces", false, ""); - parser.add("port", 'p', "The port to listen on.", false, - RENDERDOC_GetDefaultRemoteServerPort()); - } - virtual const char *Description() - { - return "Start up a server listening as a host for remote replays."; - } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - string host = parser.get("host"); - uint32_t port = parser.get("port"); - - RENDERDOC_InitGlobalEnv(m_Env, convertArgs(parser.rest())); - - std::cerr << "Spawning a replay host listening on " << (host.empty() ? "*" : host) << ":" - << port << "..." << std::endl; - - if(parser.exist("daemon")) - { - std::cerr << "Detaching." << std::endl; - Daemonise(); - } - - usingKillSignal = true; - - RENDERDOC_BecomeRemoteServer(host.empty() ? NULL : host.c_str(), port, &killSignal); - - std::cerr << std::endl << "Cleaning up from replay hosting." << std::endl; - - return 0; - } -}; - -struct ReplayCommand : public Command -{ - ReplayCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.set_footer(""); - parser.add("width", 'w', "The preview window width.", false, 1280); - parser.add("height", 'h', "The preview window height.", false, 720); - parser.add("remote-host", 0, - "Instead of replaying locally, replay on this host over the network.", false); - parser.add("remote-port", 0, "If --remote-host is set, use this port.", false, - RENDERDOC_GetDefaultRemoteServerPort()); - } - virtual const char *Description() - { - return "Replay the log file and show the backbuffer on a preview window."; - } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - std::vector rest = parser.rest(); - if(rest.empty()) - { - std::cerr << "Error: capture command requires a filename to load." << std::endl - << std::endl - << parser.usage(); - return 0; - } - - string filename = rest[0]; - - rest.erase(rest.begin()); - - RENDERDOC_InitGlobalEnv(m_Env, convertArgs(rest)); - - if(parser.exist("remote-host")) - { - std::cout << "Replaying '" << filename << "' on " << parser.get("remote-host") << ":" - << parser.get("remote-port") << "." << std::endl; - - IRemoteServer *remote = NULL; - ReplayStatus status = RENDERDOC_CreateRemoteServerConnection( - parser.get("remote-host").c_str(), parser.get("remote-port"), &remote); - - if(remote == NULL || status != ReplayStatus::Succeeded) - { - std::cerr << "Error: Couldn't connect to " << parser.get("remote-host") << ":" - << parser.get("remote-port") << "." << std::endl; - std::cerr << " Have you run renderdoccmd remoteserver on '" - << parser.get("remote-host") << "'?" << std::endl; - return 1; - } - - std::cerr << "Copying capture file to remote server" << std::endl; - - rdctype::str remotePath = remote->CopyCaptureToRemote(filename.c_str(), NULL); - - IReplayController *renderer = NULL; - std::tie(status, renderer) = remote->OpenCapture(~0U, remotePath.elems, NULL); - - if(status == ReplayStatus::Succeeded) - { - DisplayRendererPreview(renderer, parser.get("width"), - parser.get("height")); - - remote->CloseCapture(renderer); - } - else - { - std::cerr << "Couldn't load and replay '" << filename << "'." << std::endl; - } - - remote->ShutdownConnection(); - } - else - { - std::cout << "Replaying '" << filename << "' locally.." << std::endl; - - ICaptureFile *file = RENDERDOC_OpenCaptureFile(filename.c_str()); - - if(file->OpenStatus() != ReplayStatus::Succeeded) - { - std::cerr << "Couldn't load '" << filename << "'." << std::endl; - return 1; - } - - IReplayController *renderer = NULL; - ReplayStatus status = ReplayStatus::InternalError; - std::tie(status, renderer) = file->OpenCapture(NULL); - - file->Shutdown(); - - if(status == ReplayStatus::Succeeded) - { - DisplayRendererPreview(renderer, parser.get("width"), - parser.get("height")); - - renderer->Shutdown(); - } - else - { - std::cerr << "Couldn't load and replay '" << filename << "'." << std::endl; - return 1; - } - } - return 0; - } -}; - -struct CapAltBitCommand : public Command -{ - CapAltBitCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.add("pid", 0, ""); - parser.add("log", 0, ""); - parser.add("debuglog", 0, ""); - parser.add("capopts", 0, ""); - parser.stop_at_rest(true); - } - virtual const char *Description() { return "Internal use only!"; } - virtual bool IsInternalOnly() { return true; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - CaptureOptions cmdopts; - readCapOpts(parser.get("capopts").c_str(), &cmdopts); - - RENDERDOC_InitGlobalEnv(m_Env, rdctype::array()); - - std::vector rest = parser.rest(); - - if(rest.size() % 3 != 0) - { - std::cerr << "Invalid generated capaltbit command rest.size() == " << rest.size() << std::endl; - return 0; - } - - int numEnvs = int(rest.size() / 3); - - rdctype::array env; - env.create(numEnvs); - - for(int i = 0; i < numEnvs; i++) - { - string typeString = rest[i * 3 + 0]; - - EnvMod type = EnvMod::Set; - EnvSep sep = EnvSep::NoSep; - - if(typeString == "+env-replace") - { - type = EnvMod::Set; - sep = EnvSep::NoSep; - } - else if(typeString == "+env-append-platform") - { - type = EnvMod::Append; - sep = EnvSep::Platform; - } - else if(typeString == "+env-append-semicolon") - { - type = EnvMod::Append; - sep = EnvSep::SemiColon; - } - else if(typeString == "+env-append-colon") - { - type = EnvMod::Append; - sep = EnvSep::Colon; - } - else if(typeString == "+env-append") - { - type = EnvMod::Append; - sep = EnvSep::NoSep; - } - else if(typeString == "+env-prepend-platform") - { - type = EnvMod::Prepend; - sep = EnvSep::Platform; - } - else if(typeString == "+env-prepend-semicolon") - { - type = EnvMod::Prepend; - sep = EnvSep::SemiColon; - } - else if(typeString == "+env-prepend-colon") - { - type = EnvMod::Prepend; - sep = EnvSep::Colon; - } - else if(typeString == "+env-prepend") - { - type = EnvMod::Prepend; - sep = EnvSep::NoSep; - } - else - { - std::cerr << "Invalid generated capaltbit env '" << rest[i * 3 + 0] << std::endl; - return 0; - } - - env[i] = EnvironmentModification(type, sep, rest[i * 3 + 1].c_str(), rest[i * 3 + 2].c_str()); - } - - string debuglog = parser.get("debuglog"); - - RENDERDOC_SetDebugLogFile(debuglog.c_str()); - - int ret = RENDERDOC_InjectIntoProcess(parser.get("pid"), env, - parser.get("log").c_str(), cmdopts, false); - - return ret; - } -}; - -int renderdoccmd(const GlobalEnvironment &env, std::vector &argv) -{ - try - { - // add basic commands, and common aliases - add_command("version", new VersionCommand(env)); - - add_alias("--version", "version"); - add_alias("-v", "version"); - // for windows - add_alias("/version", "version"); - add_alias("/v", "version"); - - add_command("help", new HelpCommand(env)); - - add_alias("--help", "help"); - add_alias("-h", "help"); - add_alias("-?", "help"); - - // for windows - add_alias("/help", "help"); - add_alias("/h", "help"); - add_alias("/?", "help"); - - // add platform agnostic commands - add_command("thumb", new ThumbCommand(env)); - add_command("capture", new CaptureCommand(env)); - add_command("inject", new InjectCommand(env)); - add_command("remoteserver", new RemoteServerCommand(env)); - add_command("replay", new ReplayCommand(env)); - add_command("capaltbit", new CapAltBitCommand(env)); - - if(argv.size() <= 1) - { - int ret = command_usage(); - clean_up(); - return ret; - } - - // std::string programName = argv[0]; - - argv.erase(argv.begin()); - - std::string command = *argv.begin(); - - argv.erase(argv.begin()); - - auto it = commands.find(command); - - if(it == commands.end()) - { - auto a = aliases.find(command); - if(a != aliases.end()) - it = commands.find(a->second); - } - - if(it == commands.end()) - { - int ret = command_usage(command); - clean_up(); - return ret; - } - - cmdline::parser cmd; - - cmd.set_program_name("renderdoccmd"); - cmd.set_header(command); - - it->second->AddOptions(cmd); - - if(it->second->IsCaptureCommand()) - { - cmd.add("working-dir", 'd', "Set the working directory of the program, if launched.", - false); - cmd.add("capture-file", 'c', - "Set the filename template for new captures. Frame number will be " - "automatically appended.", - false); - cmd.add("wait-for-exit", 'w', "Wait for the target program to exit, before returning."); - - // CaptureOptions - cmd.add("opt-disallow-vsync", 0, - "Capturing Option: Disallow the application from enabling vsync."); - cmd.add("opt-disallow-fullscreen", 0, - "Capturing Option: Disallow the application from enabling fullscreen."); - cmd.add("opt-api-validation", 0, - "Capturing Option: Record API debugging events and messages."); - cmd.add("opt-api-validation-unmute", 0, - "Capturing Option: Unmutes API debugging output from --opt-api-validation."); - cmd.add("opt-capture-callstacks", 0, - "Capturing Option: Capture CPU callstacks for API events."); - cmd.add("opt-capture-callstacks-only-draws", 0, - "Capturing Option: When capturing CPU callstacks, only capture them from drawcalls."); - cmd.add("opt-delay-for-debugger", 0, - "Capturing Option: Specify a delay in seconds to wait for a debugger to attach.", - false, 0, cmdline::range(0, 10000)); - cmd.add("opt-verify-map-writes", 0, - "Capturing Option: Verify any writes to mapped buffers, by bounds checking."); - cmd.add("opt-hook-children", 0, - "Capturing Option: Hooks any system API calls that create child processes."); - cmd.add("opt-ref-all-resources", 0, - "Capturing Option: Include all live resources, not just those used by a frame."); - cmd.add("opt-save-all-initials", 0, - "Capturing Option: Save all initial resource contents at frame start."); - cmd.add("opt-capture-all-cmd-lists", 0, - "Capturing Option: In D3D11, record all command lists from application start."); - } - - cmd.parse_check(argv, true); - - CaptureOptions opts; - RENDERDOC_GetDefaultCaptureOptions(&opts); - - if(it->second->IsCaptureCommand()) - { - if(cmd.exist("opt-disallow-vsync")) - opts.AllowVSync = false; - if(cmd.exist("opt-disallow-fullscreen")) - opts.AllowFullscreen = false; - if(cmd.exist("opt-api-validation")) - opts.APIValidation = true; - if(cmd.exist("opt-api-validation-unmute")) - opts.DebugOutputMute = false; - if(cmd.exist("opt-capture-callstacks")) - opts.CaptureCallstacks = true; - if(cmd.exist("opt-capture-callstacks-only-draws")) - opts.CaptureCallstacksOnlyDraws = true; - if(cmd.exist("opt-verify-map-writes")) - opts.VerifyMapWrites = true; - if(cmd.exist("opt-hook-children")) - opts.HookIntoChildren = true; - if(cmd.exist("opt-ref-all-resources")) - opts.RefAllResources = true; - if(cmd.exist("opt-save-all-initials")) - opts.SaveAllInitials = true; - if(cmd.exist("opt-capture-all-cmd-lists")) - opts.CaptureAllCmdLists = true; - - opts.DelayForDebugger = (uint32_t)cmd.get("opt-delay-for-debugger"); - } - - if(cmd.exist("help")) - { - std::cerr << cmd.usage() << std::endl; - clean_up(); - return 0; - } - - int ret = it->second->Execute(cmd, opts); - clean_up(); - return ret; - } - catch(std::exception e) - { - fprintf(stderr, "Unexpected exception: %s\n", e.what()); - - exit(1); - } + return 0; } -int renderdoccmd(const GlobalEnvironment &env, int argc, char **c_argv) +int renderdoccmd(int argc, char **c_argv) { std::vector argv; argv.resize(argc); for(int i = 0; i < argc; i++) argv[i] = c_argv[i]; - return renderdoccmd(env, argv); + return renderdoccmd(argv); } diff --git a/renderdoccmd/renderdoccmd.h b/renderdoccmd/renderdoccmd.h index 59acb01f0..10da52f98 100644 --- a/renderdoccmd/renderdoccmd.h +++ b/renderdoccmd/renderdoccmd.h @@ -24,37 +24,7 @@ #pragma once -#include -#include "3rdparty/cmdline/cmdline.h" +#include -struct Command -{ - Command(const GlobalEnvironment &env) { m_Env = env; } - virtual ~Command() {} - virtual void AddOptions(cmdline::parser &parser) = 0; - virtual int Execute(cmdline::parser &parser, const CaptureOptions &opts) = 0; - virtual const char *Description() = 0; - - virtual bool IsInternalOnly() = 0; - virtual bool IsCaptureCommand() = 0; - - GlobalEnvironment m_Env; -}; - -extern bool usingKillSignal; -extern volatile uint32_t killSignal; - -void add_version_line(const std::string &str); - -void add_command(const std::string &name, Command *cmd); -void add_alias(const std::string &alias, const std::string &command); - -int renderdoccmd(const GlobalEnvironment &env, int argc, char **argv); -int renderdoccmd(const GlobalEnvironment &env, std::vector &argv); - -void readCapOpts(const std::string &str, CaptureOptions *opts); - -// these must be defined in platform .cpps -void DisplayRendererPreview(IReplayController *renderer, TextureDisplay &displayCfg, uint32_t width, - uint32_t height); -void Daemonise(); +int renderdoccmd(int argc, char **argv); +int renderdoccmd(std::vector &argv); \ No newline at end of file diff --git a/renderdoccmd/renderdoccmd.rc b/renderdoccmd/renderdoccmd.rc index 9288b81951949ce179546e82bfe9e2c07056ce74..3a848802bba445da7052eab19e3a1d86bedf92a6 100644 GIT binary patch literal 14998 zcmdU$+in}l5r+GEfxN>keX~X!N|t=u+*wB}rVbEg*$xa4TFI1+=(Lo)wu8J-UNXu5 zb+I(l!y!3CDG3+EXlD9Q{db+Zx_b2Qe=UTCkcI8=IUI*UxD402`r$@phbp@cU&2v1 z)7xtJqkdU94IjgWu7S#LbU#tqKzI6m(bKV>Grd9WbGTBQcKAd1L8C0h`va9;sP;^) zPh#8FNdI>D6k4%0Js-q&{n!uMFT-BwhJ)}Xtc9(x8+u_stgCcQ&pV+L-m9dmzuRF& zB^^Ec_+Xg7pQH187B(q%Z;{BOh^_;8?Ezti6>&3aYygdgiFU(!{U$fykZ z8Ug4jaqRc&U}^56-WOvaemXra#_ruwtxt94`e@+Bv{8L=6{yVHj@rsNXyP7 z>uc#(7JibhU+B&KPghUojjqGP3hlp+95b$=k6HLJ@hK;w_%dwBn#`AUrTK5(CUaf_6LhW;AQ@Hjcih(mhe#OG*!;?6;!K)Ap;H@17{K!tEq|Z1n9o;+r^E zI8vOijYw%PQrQb{MThz9>It5gskeliH3uI(P`gX5(AeETze`WZ?*Gtd*djE$~74nK!w-JeB%JRWkvXNHz-B_nu^-F;p@ zpFNFm5PisVQ8wyJx-W$n8i#k@){_~&(i=8Mj0A6)pS38j9kWWLs6QR?*|fm1VMGAZ#4z9_v6Y%yz-^BKkAO^IY$grg-45?N;)67oS?<;e|$K zW$_hYUb^~8BRFp{#>+~jC=#9ljb z$CJu$I`$pKHs_I(KZ!nj-p_GWVdwlX{5iqxc1RS+nrD___6X;mMeBT#NOONG_trK3 zkw!fe52s_8#JeR)4%>LDJ9dI5o2+^AYd-fyzBek~iSe-HEv+#-(Y}dUn1{FGnZ0Fy z7}?j`4-?U|k|9C!8pJ*0#;T5P=)Wed93S}-GZkZBu)5t;)AU-8QSiU)O27!U=ZR){ z>wVR4%10eUe_d=(Y;6&>xAps>=8k6OoPfUBTM?(Xx9F!H9%3%yE3CWR14PS}vv{TU z`{Az@h|*c-`kX%%^A(O54XLLM%y%|DVvPCxF&~imeO$)L>$!717SG%tqjkmH6!q15 zTb%{`Al-zmTeraaS~siQQ}R zlPvCgzA9S3j(Z(quuP{H#OhyS41cAkBT==pEzX?=!?xs#*rQzNoqY*=rz6Gt^x*uA z9JEFLS$rq6lw+a2Md|d_`H>u#qwAl_2cxD|Il>0Z)T zsN%hDJMYuF#oiu1 zLEa*jL%IE8p*<0epF`#&>*q7d0TuHvUQP2F^que7`7F8L^@}KS2Y7X;PtgfYA*!7WQ@BJ4d+qaQslp@1Vzk&M!uh9Z~danzK)VpQ8(!IQg6rA!kv)!K0` zEj^P?prx$!XzIrjN1Ae@n&vc)5NGf`TB;Mq3IE$1iP22QuCkJ%FGHJ<&z1D!Qh11a z`O2-{=;JB1hm?>+6$ZY^!;X8>2r?j8s(lBFFDn1)p>diEw=~Fc3&4sZv+qX2Qp)!wC_NzG}_|%j)RWzF-x?gGKe$_Rg z9$!F_@}j6Wv+;#*&Yk8o6y*2V4V_5Rmr<9!XO5#OiZadmXmX$8T+C7UQ&Tifv%Vd9 zkDe^%qqxFX=jGq*D4gar$>b<|syKwr^=R zL1a;_t%yZbcR^I7Ss&GCL{Y>u8=ppL*2iPtGO;T0{|41QrYVw=>ut~}_$76z7uvF8W1yfPpDW96^agM1-vpyy~I{VQ{p1CQeNi^Lv{|6ZN B{WJgo delta 72 zcmbPMx*=eLn2fm|gC0W+5Ee0{GUPF&0LdaCna_~SP|A=AmI(ri6$3>|filTpHc{D03DF2F9-513C-4084-BBDD-1DEE8D9250D7} Win32Proj renderdoccmd - renderdoccmd + rdcconvert @@ -101,7 +101,7 @@ Level3 Disabled WIN32;_CRT_SECURE_NO_WARNINGS;RENDERDOC_PLATFORM_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ + $(SolutionDir)renderdoc;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ MultiThreadedDLL true ProgramDatabase @@ -109,10 +109,10 @@ Windows true - psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + Shlwapi.lib;psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(SolutionDir)renderdoc\api\replay + $(SolutionDir)renderdoc @@ -122,7 +122,7 @@ Level3 Disabled WIN32;_CRT_SECURE_NO_WARNINGS;WIN64;RENDERDOC_PLATFORM_WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - $(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ + $(SolutionDir)renderdoc;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ MultiThreadedDLL true ProgramDatabase @@ -130,10 +130,10 @@ Windows true - psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + Shlwapi.lib;psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(SolutionDir)renderdoc\api\replay + $(SolutionDir)renderdoc @@ -145,7 +145,7 @@ true true WIN32;_CRT_SECURE_NO_WARNINGS;RENDERDOC_PLATFORM_WIN32;NDEBUG;RELEASE;_CONSOLE;%(PreprocessorDefinitions) - $(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ + $(SolutionDir)renderdoc;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ true @@ -153,10 +153,10 @@ true true true - $(SolutionDir)$(Platform)\$(Configuration)\breakpad_common.lib;$(SolutionDir)$(Platform)\$(Configuration)\crash_generation_server.lib;psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + Shlwapi.lib;psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(SolutionDir)renderdoc\api\replay + $(SolutionDir)renderdoc @@ -168,7 +168,7 @@ true true WIN32;_CRT_SECURE_NO_WARNINGS;WIN64;RENDERDOC_PLATFORM_WIN32;NDEBUG;RELEASE;_CONSOLE;%(PreprocessorDefinitions) - $(SolutionDir)renderdocshim\;$(SolutionDir)renderdoc\api\;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ + $(SolutionDir)renderdoc;$(SolutionDir)renderdoc\api\replay;$(SolutionDir)renderdoc\3rdparty\ true @@ -176,14 +176,13 @@ true true true - $(SolutionDir)$(Platform)\$(Configuration)\breakpad_common.lib;$(SolutionDir)$(Platform)\$(Configuration)\crash_generation_server.lib;psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) + Shlwapi.lib;psapi.lib;ws2_32.lib;Wininet.lib;%(AdditionalDependencies) - $(SolutionDir)renderdoc\api\replay + $(SolutionDir)renderdoc - true @@ -200,8 +199,6 @@ - - @@ -216,7 +213,7 @@ true false true - false + true diff --git a/renderdoccmd/renderdoccmd.vcxproj.filters b/renderdoccmd/renderdoccmd.vcxproj.filters index e0601464b..f5acc7c16 100644 --- a/renderdoccmd/renderdoccmd.vcxproj.filters +++ b/renderdoccmd/renderdoccmd.vcxproj.filters @@ -3,9 +3,6 @@ - - 3rdparty - @@ -17,21 +14,12 @@ Resources - - 3rdparty - - - 3rdparty - {3979a11e-8029-4886-a51e-a2a9bb91d69f} - - {a8ca84b9-239b-4640-95e9-f9bd141ef465} - diff --git a/renderdoccmd/renderdoccmd_linux.cpp b/renderdoccmd/renderdoccmd_linux.cpp index 48e5e7b5a..850ecdb65 100644 --- a/renderdoccmd/renderdoccmd_linux.cpp +++ b/renderdoccmd/renderdoccmd_linux.cpp @@ -24,432 +24,8 @@ ******************************************************************************/ #include "renderdoccmd.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(RENDERDOC_WINDOWING_XLIB) -#include -#endif - -#include - -using std::string; -using std::vector; - -void Daemonise() -{ - // don't change dir, but close stdin/stdou - daemon(1, 0); -} - -struct VulkanRegisterCommand : public Command -{ - VulkanRegisterCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.add("ignore", 'i', "Do nothing and don't warn about Vulkan layer issues."); - parser.add( - "system", '\0', - "Install layer registration to /etc instead of $HOME/.local (requires root privileges)"); - } - virtual const char *Description() - { - return "Attempt to automatically fix Vulkan layer registration issues"; - } - virtual bool IsInternalOnly() { return false; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - bool ignore = (parser.exist("ignore")); - - if(ignore) - { - std::cout << "Not fixing vulkan layer issues, and suppressing future warnings." << std::endl; - std::cout << "To undo, remove '$HOME/.renderdoc/ignore_vulkan_layer_issues'." << std::endl; - - string ignorePath = string(getenv("HOME")) + "/.renderdoc/"; - - mkdir(ignorePath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - - ignorePath += "ignore_vulkan_layer"; - - FILE *f = fopen(ignorePath.c_str(), "w"); - - if(f) - { - fputs("This file suppresses any checks for vulkan layer issues.\n", f); - fputs("Delete this file to restore default checking.\n", f); - - fclose(f); - } - else - { - std::cerr << "Couldn't create '$HOME/.renderdoc/ignore_vulkan_layer_issues'." << std::endl; - } - - return 0; - } - - RENDERDOC_UpdateVulkanLayerRegistration(parser.exist("system")); - - return 0; - } -}; - -void VerifyVulkanLayer(const GlobalEnvironment &env, int argc, char *argv[]) -{ - VulkanLayerFlags flags = VulkanLayerFlags::NoFlags; - rdctype::array myJSONs; - rdctype::array otherJSONs; - - bool needUpdate = RENDERDOC_NeedVulkanLayerRegistration(&flags, &myJSONs, &otherJSONs); - - if(!needUpdate) - { - if(!(flags & VulkanLayerFlags::Unfixable)) - add_command("vulkanregister", new VulkanRegisterCommand(env)); - return; - } - - std::cerr << "*************************************************************************" - << std::endl; - std::cerr << "** Warning: Vulkan capture possibly not configured. **" - << std::endl; - std::cerr << std::endl; - - if(flags & VulkanLayerFlags::OtherInstallsRegistered) - std::cerr << "Multiple RenderDoc layers are registered, possibly from different builds." - << std::endl; - - if(!(flags & VulkanLayerFlags::ThisInstallRegistered)) - std::cerr << "This build's RenderDoc layer is not registered." << std::endl; - - std::cerr << "To fix this, the following actions must take place: " << std::endl << std::endl; - - const bool registerAll = bool(flags & VulkanLayerFlags::RegisterAll); - const bool updateAllowed = bool(flags & VulkanLayerFlags::UpdateAllowed); - - for(const rdctype::str &j : otherJSONs) - std::cerr << (updateAllowed ? "Unregister/update: " : "Unregister: ") << j.c_str() << std::endl; - - if(!(flags & VulkanLayerFlags::ThisInstallRegistered)) - { - if(registerAll) - { - for(const rdctype::str &j : myJSONs) - std::cerr << (updateAllowed ? "Register/update: " : "Register: ") << j.c_str() << std::endl; - } - else - { - std::cerr << (updateAllowed ? "Register one of:" : "Register/update one of:") << std::endl; - for(const rdctype::str &j : myJSONs) - std::cerr << " -- " << j.c_str() << "\n"; - } - } - - std::cerr << std::endl; - - if(flags & VulkanLayerFlags::Unfixable) - { - std::cerr << "NOTE: The renderdoc layer registered in /usr is reserved for distribution" - << std::endl; - std::cerr << "controlled packages. RenderDoc cannot automatically unregister this even" - << std::endl; - std::cerr << "with root permissions, you must fix this conflict manually." << std::endl - << std::endl; - - std::cerr << "*************************************************************************" - << std::endl; - std::cerr << std::endl; - - return; - } - - std::cerr << "NOTE: Automatically removing or changing the layer registered in /etc" << std::endl; - std::cerr << "will require root privileges." << std::endl << std::endl; - - std::cerr << "To fix these issues run the 'vulkanregister' command." << std::endl; - std::cerr << "Use 'vulkanregister --help' to see more information." << std::endl; - std::cerr << std::endl; - - std::cerr << "By default 'vulkanregister' will register the layer to your $HOME folder." - << std::endl; - std::cerr << "This does not require root permissions." << std::endl; - std::cerr << std::endl; - std::cerr << "If you want to install to the system, run 'vulkanregister --system'." << std::endl; - std::cerr << "This requires root permissions to write to /etc/vulkan/." << std::endl; - - // just in case there's a strange install that is misdetected or something then allow - // users to suppress this message and just say "I know what I'm doing". - std::cerr << std::endl; - std::cerr << "To suppress this warning in future, run 'vulkanregister --ignore'." << std::endl; - - std::cerr << "*************************************************************************" - << std::endl; - std::cerr << std::endl; - - add_command("vulkanregister", new VulkanRegisterCommand(env)); -} - -static Display *display = NULL; - -void DisplayRendererPreview(IReplayController *renderer, TextureDisplay &displayCfg, uint32_t width, - uint32_t height) -{ -// we only have the preview implemented for platforms that have xlib & xcb. It's unlikely -// a meaningful platform exists with only one, and at the time of writing no other windowing -// systems are supported on linux for the replay -#if defined(RENDERDOC_WINDOWING_XLIB) && defined(RENDERDOC_WINDOWING_XCB) - // need to create a hybrid setup xlib and xcb in case only one or the other is supported. - // We'll prefer xcb - - if(display == NULL) - { - std::cerr << "Couldn't open X Display" << std::endl; - return; - } - - int scr = DefaultScreen(display); - - xcb_connection_t *connection = XGetXCBConnection(display); - - if(connection == NULL) - { - XCloseDisplay(display); - std::cerr << "Couldn't get XCB connection from Xlib Display" << std::endl; - return; - } - - XSetEventQueueOwner(display, XCBOwnsEventQueue); - - const xcb_setup_t *setup = xcb_get_setup(connection); - xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup); - while(scr-- > 0) - xcb_screen_next(&iter); - - xcb_screen_t *screen = iter.data; - - uint32_t value_mask, value_list[32]; - - xcb_window_t window = xcb_generate_id(connection); - - value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; - value_list[0] = screen->black_pixel; - value_list[1] = - XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; - - xcb_create_window(connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, width, height, 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list); - - /* Magic code that will send notification when window is destroyed */ - xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS"); - xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0); - - xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW"); - xcb_intern_atom_reply_t *atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0); - - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, - 8, sizeof("renderdoccmd") - 1, "renderdoccmd"); - - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, window, (*reply).atom, 4, 32, 1, - &(*atom_wm_delete_window).atom); - free(reply); - - xcb_map_window(connection, window); - - rdctype::array systems = renderer->GetSupportedWindowSystems(); - - bool xcb = false, xlib = false; - - for(int32_t i = 0; i < systems.count; i++) - { - if(systems[i] == WindowingSystem::Xlib) - xlib = true; - if(systems[i] == WindowingSystem::XCB) - xcb = true; - } - - IReplayOutput *out = NULL; - - // prefer xcb - if(xcb) - { - XCBWindowData windowData; - windowData.connection = connection; - windowData.window = window; - - out = renderer->CreateOutput(WindowingSystem::XCB, &windowData, ReplayOutputType::Texture); - } - else if(xlib) - { - XlibWindowData windowData; - windowData.display = display; - windowData.window = (Drawable)window; // safe to cast types - - out = renderer->CreateOutput(WindowingSystem::Xlib, &windowData, ReplayOutputType::Texture); - } - else - { - std::cerr << "Neither XCB nor XLib are supported, can't create window." << std::endl; - std::cerr << "Supported systems: "; - for(int32_t i = 0; i < systems.count; i++) - std::cerr << (uint32_t)systems[i] << std::endl; - std::cerr << std::endl; - return; - } - - out->SetTextureDisplay(displayCfg); - - xcb_flush(connection); - - bool done = false; - while(!done) - { - xcb_generic_event_t *event; - - event = xcb_poll_for_event(connection); - if(event) - { - switch(event->response_type & 0x7f) - { - case XCB_EXPOSE: - renderer->SetFrameEvent(10000000, true); - out->Display(); - break; - case XCB_CLIENT_MESSAGE: - if((*(xcb_client_message_event_t *)event).data.data32[0] == (*atom_wm_delete_window).atom) - { - done = true; - } - break; - case XCB_KEY_RELEASE: - { - const xcb_key_release_event_t *key = (const xcb_key_release_event_t *)event; - - if(key->detail == 0x9) - done = true; - } - break; - case XCB_DESTROY_NOTIFY: done = true; break; - default: break; - } - free(event); - } - - renderer->SetFrameEvent(10000000, true); - out->Display(); - - usleep(100000); - } -#else - std::cerr << "No supporting windowing systems defined at build time (xlib and xcb)" << std::endl; -#endif -} - -void sig_handler(int signo) -{ - if(usingKillSignal) - killSignal = true; - else - exit(1); -} int main(int argc, char *argv[]) { - setlocale(LC_CTYPE, ""); - - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - - GlobalEnvironment env; - -#if defined(RENDERDOC_WINDOWING_XLIB) || defined(RENDERDOC_WINDOWING_XCB) - // call XInitThreads - although we don't use xlib concurrently the driver might need to. - XInitThreads(); - - // we don't check if display successfully opened, it's only a problem if it's needed later. - display = env.xlibDisplay = XOpenDisplay(NULL); -#endif - -#if defined(RENDERDOC_SUPPORT_VULKAN) - VerifyVulkanLayer(env, argc, argv); -#endif - - // add compiled-in support to version line - { - string support = "APIs supported at compile-time: "; - int count = 0; - -#if defined(RENDERDOC_SUPPORT_VULKAN) - support += "Vulkan, "; - count++; -#endif - -#if defined(RENDERDOC_SUPPORT_GL) - support += "GL, "; - count++; -#endif - -#if defined(RENDERDOC_SUPPORT_GLES) - support += "GLES, "; - count++; -#endif - - if(count == 0) - { - support += "None."; - } - else - { - // remove trailing ', ' - support.pop_back(); - support.pop_back(); - support += "."; - } - - add_version_line(support); - - support = "Windowing systems supported at compile-time: "; - count = 0; - -#if defined(RENDERDOC_WINDOWING_XLIB) - support += "xlib, "; - count++; -#endif - -#if defined(RENDERDOC_WINDOWING_XCB) - support += "XCB, "; - count++; -#endif - -#if defined(RENDERDOC_SUPPORT_VULKAN) - support += "Vulkan KHR_display, "; - count++; -#endif - - if(count == 0) - { - support += "None."; - } - else - { - // remove trailing ', ' - support.pop_back(); - support.pop_back(); - support += "."; - } - - add_version_line(support); - } - - return renderdoccmd(env, argc, argv); + return renderdoccmd(argc, argv); } diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index b9ce300a5..8d96a2872 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -24,813 +24,9 @@ ******************************************************************************/ #include "renderdoccmd.h" -#include -#include #include #include #include -#include "miniz/miniz.h" -#include "resource.h" - -#include -#include - -using std::string; -using std::wstring; -using std::vector; - -HINSTANCE hInstance = NULL; - -#if defined(RELEASE) -// breakpad -#include "breakpad/client/windows/crash_generation/client_info.h" -#include "breakpad/client/windows/crash_generation/crash_generation_server.h" -#include "breakpad/common/windows/http_upload.h" - -using google_breakpad::ClientInfo; -using google_breakpad::CrashGenerationServer; - -bool exitServer = false; - -static HINSTANCE CrashHandlerInst = 0; -static HWND CrashHandlerWnd = 0; - -bool uploadReport = false; -bool uploadDump = false; -bool uploadLog = false; -string reproSteps = ""; - -wstring dump = L""; -vector customInfo; -wstring logpath = L""; - -INT_PTR CALLBACK CrashHandlerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch(message) - { - case WM_INITDIALOG: - { - HANDLE hIcon = LoadImage(CrashHandlerInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - - if(hIcon) - { - SendMessage(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); - SendMessage(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); - } - - SetDlgItemTextW( - hDlg, IDC_WELCOMETEXT, - L"RenderDoc has encountered an unhandled exception or other similar unrecoverable " - L"error.\n\n" - L"If you had captured but not saved a logfile it should still be available in %TEMP% and " - L"will not be deleted," - L"you can try loading it again.\n\n" - L"A minidump has been created and the RenderDoc diagnostic log (NOT any capture logfile) " - L"is available if you would like " - L"to send them back to be analysed. The path for both is found below if you would like " - L"to inspect their contents and censor as appropriate.\n\n" - L"Neither contains any significant private information, the minidump has some internal " - L"states and local memory at the time of the " - L"crash & thread stacks, etc. The diagnostic log contains diagnostic messages like " - L"warnings and errors.\n\n" - L"The only other information sent is the version of RenderDoc, C# exception callstack, " - L"and any notes you include.\n\n" - L"Any repro steps or notes would be helpful to include with the report. If you'd like to " - L"be contacted about the bug " - L"e.g. for updates about its status just include your email & name. Thank you!\n\n" - L"Baldur (baldurk@baldurk.org)"); - - SetDlgItemTextW(hDlg, IDC_DUMPPATH, dump.c_str()); - SetDlgItemTextW(hDlg, IDC_LOGPATH, logpath.c_str()); - - CheckDlgButton(hDlg, IDC_SENDDUMP, BST_CHECKED); - CheckDlgButton(hDlg, IDC_SENDLOG, BST_CHECKED); - - { - RECT r; - GetClientRect(hDlg, &r); - - int xPos = (GetSystemMetrics(SM_CXSCREEN) - r.right) / 2; - int yPos = (GetSystemMetrics(SM_CYSCREEN) - r.bottom) / 2; - - SetWindowPos(hDlg, HWND_TOPMOST, xPos, yPos, 0, 0, SWP_NOSIZE); - } - - return (INT_PTR)TRUE; - } - - case WM_SHOWWINDOW: - { - { - RECT r; - GetClientRect(hDlg, &r); - - int xPos = (GetSystemMetrics(SM_CXSCREEN) - r.right) / 2; - int yPos = (GetSystemMetrics(SM_CYSCREEN) - r.bottom) / 2; - - SetWindowPos(hDlg, HWND_NOTOPMOST, xPos, yPos, 0, 0, SWP_NOSIZE); - } - - return (INT_PTR)TRUE; - } - - case WM_COMMAND: - { - int ID = LOWORD(wParam); - - if(ID == IDC_DONTSEND) - { - EndDialog(hDlg, 0); - return (INT_PTR)TRUE; - } - else if(ID == IDC_SEND) - { - uploadReport = true; - uploadDump = (IsDlgButtonChecked(hDlg, IDC_SENDDUMP) != 0); - uploadLog = (IsDlgButtonChecked(hDlg, IDC_SENDLOG) != 0); - - char notes[4097] = {0}; - - GetDlgItemTextA(hDlg, IDC_NAME, notes, 4096); - notes[4096] = 0; - - reproSteps = "Name: "; - reproSteps += notes; - reproSteps += "\n"; - - memset(notes, 0, 4096); - GetDlgItemTextA(hDlg, IDC_EMAIL, notes, 4096); - notes[4096] = 0; - - reproSteps += "Email: "; - reproSteps += notes; - reproSteps += "\n\n"; - - memset(notes, 0, 4096); - GetDlgItemTextA(hDlg, IDC_REPRO, notes, 4096); - notes[4096] = 0; - - reproSteps += notes; - - EndDialog(hDlg, 0); - return (INT_PTR)TRUE; - } - } - break; - - case WM_QUIT: - case WM_DESTROY: - case WM_CLOSE: - { - EndDialog(hDlg, 0); - return (INT_PTR)TRUE; - } - break; - } - return (INT_PTR)FALSE; -} - -static void _cdecl OnClientCrashed(void *context, const ClientInfo *client_info, - const wstring *dump_path) -{ - if(dump_path) - { - dump = *dump_path; - - google_breakpad::CustomClientInfo custom = client_info->GetCustomInfo(); - - for(size_t i = 0; i < custom.count; i++) - customInfo.push_back(custom.entries[i]); - } - - exitServer = true; -} - -static void _cdecl OnClientExited(void *context, const ClientInfo *client_info) -{ - exitServer = true; -} -#endif - -LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if(msg == WM_CLOSE) - { - DestroyWindow(hwnd); - return 0; - } - if(msg == WM_DESTROY) - { - PostQuitMessage(0); - return 0; - } - return DefWindowProc(hwnd, msg, wParam, lParam); -} - -void Daemonise() -{ - // nothing really to do, windows version of renderdoccmd is already 'detached' -} - -void DisplayRendererPreview(IReplayController *renderer, TextureDisplay &displayCfg, uint32_t width, - uint32_t height) -{ - RECT wr = {0, 0, (LONG)width, (LONG)height}; - AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE); - - HWND wnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top, - NULL, NULL, hInstance, NULL); - - if(wnd == NULL) - return; - - ShowWindow(wnd, SW_SHOW); - UpdateWindow(wnd); - - IReplayOutput *out = renderer->CreateOutput(WindowingSystem::Win32, wnd, ReplayOutputType::Texture); - - out->SetTextureDisplay(displayCfg); - - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(true) - { - // Check to see if any messages are waiting in the queue - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - // Translate the message and dispatch it to WindowProc() - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - // If the message is WM_QUIT, exit the while loop - if(msg.message == WM_QUIT) - break; - - // set to random event beyond the end of the frame to ensure output is marked as dirty - renderer->SetFrameEvent(10000000, true); - out->Display(); - - Sleep(40); - } - - DestroyWindow(wnd); -} - -struct UpgradeCommand : public Command -{ - UpgradeCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) { parser.add("path", 0, ""); } - virtual const char *Description() { return "Internal use only!"; } - virtual bool IsInternalOnly() { return true; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - string originalpath = parser.get("path"); - - wstring wide_path; - - { - wchar_t *conv = new wchar_t[originalpath.size() + 1]; - - MultiByteToWideChar(CP_UTF8, 0, originalpath.c_str(), -1, conv, int(originalpath.size() + 1)); - - wide_path = conv; - - delete[] conv; - } - - // Wait for UI to exit - Sleep(3000); - - mz_zip_archive zip; - ZeroMemory(&zip, sizeof(zip)); - - bool successful = false; - wstring failReason; - - mz_bool b = mz_zip_reader_init_file(&zip, "./update.zip", 0); - - if(b) - { - mz_uint numfiles = mz_zip_reader_get_num_files(&zip); - - // first create directories - for(mz_uint i = 0; i < numfiles; i++) - { - if(mz_zip_reader_is_file_a_directory(&zip, i)) - { - mz_zip_archive_file_stat zstat; - mz_zip_reader_file_stat(&zip, i, &zstat); - - const char *fn = zstat.m_filename; - // skip first directory because it's RenderDoc_Version_Bitness/ - fn = strchr(fn, '/'); - if(fn) - fn++; - - if(fn && *fn) - { - wchar_t conv[MAX_PATH] = {0}; - wchar_t *wfn = conv; - - // I know the zip only contains ASCII chars, just upcast - while(*fn) - *(wfn++) = wchar_t(*(fn++)); - - wstring target = wide_path + conv; - - wfn = &target[0]; - - // convert slashes because CreateDirectory barfs on - // proper slashes. - while(*(wfn++)) - { - if(*wfn == L'/') - *wfn = L'\\'; - } - - CreateDirectoryW(target.c_str(), NULL); - } - } - } - - // next make sure we can get read+write access to every file. If not - // one might be in use, but we definitely can't update it - successful = true; - - for(mz_uint i = 0; successful && i < numfiles; i++) - { - if(!mz_zip_reader_is_file_a_directory(&zip, i)) - { - mz_zip_archive_file_stat zstat; - mz_zip_reader_file_stat(&zip, i, &zstat); - - const char *fn = zstat.m_filename; - // skip first directory because it's RenderDoc_Version_Bitness/ - fn = strchr(fn, '/'); - if(fn) - fn++; - - if(fn && *fn) - { - wchar_t conv[MAX_PATH] = {0}; - wchar_t *wfn = conv; - - // I know the zip only contains ASCII chars, just upcast - while(*fn) - *(wfn++) = wchar_t(*(fn++)); - - wstring target = wide_path + conv; - - wfn = &target[0]; - - // convert slashes just to be consistent - while(*(wfn++)) - { - if(*wfn == L'/') - *wfn = L'\\'; - } - - FILE *f = NULL; - _wfopen_s(&f, target.c_str(), L"a+"); - if(!f) - { - failReason = L"\"Couldn't modify an install file - likely file is in use.\""; - successful = false; - } - else - { - fclose(f); - } - } - } - } - - for(mz_uint i = 0; successful && i < numfiles; i++) - { - if(!mz_zip_reader_is_file_a_directory(&zip, i)) - { - mz_zip_archive_file_stat zstat; - mz_zip_reader_file_stat(&zip, i, &zstat); - - const char *fn = zstat.m_filename; - // skip first directory because it's RenderDoc_Version_Bitness/ - fn = strchr(fn, '/'); - if(fn) - fn++; - - if(fn && *fn) - { - wchar_t conv[MAX_PATH] = {0}; - wchar_t *wfn = conv; - - // I know the zip only contains ASCII chars, just upcast - while(*fn) - *(wfn++) = wchar_t(*(fn++)); - - wstring target = wide_path + conv; - - wfn = &target[0]; - - // convert slashes just to be consistent - while(*(wfn++)) - { - if(*wfn == L'/') - *wfn = L'\\'; - } - - mz_zip_reader_extract_to_wfile(&zip, i, target.c_str(), 0); - } - } - } - } - else - { - failReason = L"\"Failed to open update .zip file - possibly corrupted.\""; - } - - // run original UI exe and tell it an update succeeded - wstring cmdline = L"\""; - cmdline += wide_path; - cmdline += L"/renderdocui.exe\" "; - if(successful) - cmdline += L"--updatedone"; - else - cmdline += L"--updatefailed " + failReason; - - wchar_t *paramsAlloc = new wchar_t[512]; - - ZeroMemory(paramsAlloc, sizeof(wchar_t) * 512); - - wcscpy_s(paramsAlloc, sizeof(wchar_t) * 511, cmdline.c_str()); - - PROCESS_INFORMATION pi; - STARTUPINFOW si; - ZeroMemory(&pi, sizeof(pi)); - ZeroMemory(&si, sizeof(si)); - - CreateProcessW(NULL, paramsAlloc, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - - if(pi.dwProcessId != 0) - { - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - } - - delete[] paramsAlloc; - - return 0; - } -}; - -#if defined(RELEASE) -struct CrashHandlerCommand : public Command -{ - CrashHandlerCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) {} - virtual const char *Description() { return "Internal use only!"; } - virtual bool IsInternalOnly() { return true; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - CrashGenerationServer *crashServer = NULL; - - wchar_t tempPath[MAX_PATH] = {0}; - GetTempPathW(MAX_PATH - 1, tempPath); - - Sleep(100); - - wstring dumpFolder = tempPath; - dumpFolder += L"RenderDoc/dumps"; - - CreateDirectoryW(dumpFolder.c_str(), NULL); - - crashServer = new CrashGenerationServer(L"\\\\.\\pipe\\RenderDocBreakpadServer", NULL, NULL, - NULL, OnClientCrashed, NULL, OnClientExited, NULL, NULL, - NULL, true, &dumpFolder); - - if(!crashServer->Start()) - { - delete crashServer; - crashServer = NULL; - return 1; - } - - CrashHandlerInst = hInstance; - - CrashHandlerWnd = - CreateWindowEx(WS_EX_CLIENTEDGE, L"renderdoccmd", L"renderdoccmd", WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, NULL, NULL, hInstance, NULL); - - HANDLE hIcon = LoadImage(CrashHandlerInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - - if(hIcon) - { - SendMessage(CrashHandlerWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); - SendMessage(CrashHandlerWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); - } - - ShowWindow(CrashHandlerWnd, SW_HIDE); - - HANDLE readyEvent = CreateEventA(NULL, TRUE, FALSE, "RENDERDOC_CRASHHANDLE"); - - if(readyEvent != NULL) - { - SetEvent(readyEvent); - - CloseHandle(readyEvent); - } - - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(!exitServer) - { - // Check to see if any messages are waiting in the queue - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - // Translate the message and dispatch it to WindowProc() - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - // If the message is WM_QUIT, exit the while loop - if(msg.message == WM_QUIT) - break; - - Sleep(100); - } - - delete crashServer; - crashServer = NULL; - - if(!dump.empty()) - { - logpath = L""; - - string report = ""; - - for(size_t i = 0; i < customInfo.size(); i++) - { - wstring name = customInfo[i].name; - wstring val = customInfo[i].value; - - if(name == L"logpath") - { - logpath = val; - } - else if(name == L"ptime") - { - // breakpad uptime, ignore. - } - else - { - report += string(name.begin(), name.end()) + ": " + string(val.begin(), val.end()) + "\n"; - } - } - - DialogBox(CrashHandlerInst, MAKEINTRESOURCE(IDD_CRASH_HANDLER), CrashHandlerWnd, - (DLGPROC)CrashHandlerProc); - - report += "\n\nRepro steps/Notes:\n\n" + reproSteps; - - { - FILE *f = NULL; - _wfopen_s(&f, logpath.c_str(), L"r"); - if(f) - { - fseek(f, 0, SEEK_END); - long filesize = ftell(f); - fseek(f, 0, SEEK_SET); - - if(filesize > 10) - { - char *error_log = new char[filesize + 1]; - memset(error_log, 0, filesize + 1); - - fread(error_log, 1, filesize, f); - - char *managed_callstack = strstr(error_log, "--- Begin C# Exception Data ---"); - if(managed_callstack) - { - report += managed_callstack; - report += "\n\n"; - } - - delete[] error_log; - } - - fclose(f); - } - } - - if(uploadReport) - { - mz_zip_archive zip; - ZeroMemory(&zip, sizeof(zip)); - - wstring destzip = dumpFolder + L"\\report.zip"; - - DeleteFileW(destzip.c_str()); - - mz_zip_writer_init_wfile(&zip, destzip.c_str(), 0); - mz_zip_writer_add_mem(&zip, "report.txt", report.c_str(), report.length(), - MZ_BEST_COMPRESSION); - - if(uploadDump && !dump.empty()) - mz_zip_writer_add_wfile(&zip, "minidump.dmp", dump.c_str(), NULL, 0, MZ_BEST_COMPRESSION); - - if(uploadLog && !logpath.empty()) - mz_zip_writer_add_wfile(&zip, "error.log", logpath.c_str(), NULL, 0, MZ_BEST_COMPRESSION); - - mz_zip_writer_finalize_archive(&zip); - mz_zip_writer_end(&zip); - - int timeout = 10000; - wstring body = L""; - int code = 0; - - std::map params; - - google_breakpad::HTTPUpload::SendRequest(L"https://renderdoc.org/bugsubmit", params, - dumpFolder + L"\\report.zip", L"report", &timeout, - &body, &code); - - DeleteFileW(destzip.c_str()); - } - } - - if(!dump.empty()) - DeleteFileW(dump.c_str()); - - if(!logpath.empty()) - DeleteFileW(logpath.c_str()); - - return 0; - } -}; -#endif - -struct GlobalHookCommand : public Command -{ - GlobalHookCommand(const GlobalEnvironment &env) : Command(env) {} - virtual void AddOptions(cmdline::parser &parser) - { - parser.add("match", 0, ""); - parser.add("logfile", 0, ""); - parser.add("debuglog", 0, ""); - parser.add("capopts", 0, ""); - } - virtual const char *Description() { return "Internal use only!"; } - virtual bool IsInternalOnly() { return true; } - virtual bool IsCaptureCommand() { return false; } - virtual int Execute(cmdline::parser &parser, const CaptureOptions &) - { - string pathmatch = parser.get("match"); - string logfile = parser.get("logfile"); - string debuglog = parser.get("debuglog"); - - CaptureOptions cmdopts; - readCapOpts(parser.get("capopts").c_str(), &cmdopts); - - size_t len = pathmatch.length(); - wstring wpathmatch; - wpathmatch.resize(len); - MultiByteToWideChar(CP_UTF8, 0, pathmatch.c_str(), -1, &wpathmatch[0], (int)len); - wpathmatch.resize(wcslen(wpathmatch.c_str())); - - // make sure the user doesn't accidentally run this with 'a' as a parameter or something. - // "a.exe" is over 4 characters so this limit should not be a problem. - if(wpathmatch.length() < 4) - { - std::cerr - << "globalhook path match is too short/general. Danger of matching too many processes!" - << std::endl; - return 1; - } - - wchar_t rdocpath[1024]; - - // fetch path to our matching renderdoc.dll - HMODULE rdoc = GetModuleHandleA("renderdoc.dll"); - - if(rdoc == NULL) - { - std::cerr << "globalhook couldn't find renderdoc.dll!" << std::endl; - return 1; - } - - GetModuleFileNameW(rdoc, rdocpath, _countof(rdocpath) - 1); - FreeLibrary(rdoc); - - // Create stdin pipe from parent program, to stay open until requested to close - HANDLE pipe = GetStdHandle(STD_INPUT_HANDLE); - - if(pipe == INVALID_HANDLE_VALUE) - { - std::cerr << "globalhook couldn't open stdin pipe.\n" << std::endl; - return 1; - } - - HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME); - - if(datahandle != NULL) - { - CloseHandle(pipe); - CloseHandle(datahandle); - std::cerr << "globalhook found pre-existing global data, not creating second global hook." - << std::endl; - return 1; - } - - datahandle = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(ShimData), - GLOBAL_HOOK_DATA_NAME); - - if(datahandle) - { - ShimData *shimdata = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, - 0, sizeof(ShimData)); - - if(shimdata) - { - memset(shimdata, 0, sizeof(ShimData)); - - wcsncpy_s(shimdata->pathmatchstring, wpathmatch.c_str(), _TRUNCATE); - wcsncpy_s(shimdata->rdocpath, rdocpath, _TRUNCATE); - strncpy_s(shimdata->logfile, logfile.c_str(), _TRUNCATE); - strncpy_s(shimdata->debuglog, debuglog.c_str(), _TRUNCATE); - memcpy(shimdata->opts, &cmdopts, sizeof(CaptureOptions)); - - static_assert(sizeof(CaptureOptions) <= sizeof(shimdata->opts), - "ShimData options is too small"); - - // wait until a write comes in over the pipe - char buf[16] = {0}; - DWORD read = 0; - ReadFile(pipe, buf, 16, &read, NULL); - - UnmapViewOfFile(shimdata); - } - else - { - std::cerr << "globalhook couldn't map global data store." << std::endl; - } - - CloseHandle(datahandle); - } - else - { - std::cerr << "globalhook couldn't create global data store." << std::endl; - } - - CloseHandle(pipe); - - return 0; - } -}; - -// from http://stackoverflow.com/q/29939893/4070143 -// and http://stackoverflow.com/a/4570213/4070143 - -std::string getParentExe() -{ - DWORD pid = GetCurrentProcessId(); - HANDLE h = NULL; - PROCESSENTRY32 pe = {0}; - DWORD ppid = 0; - pe.dwSize = sizeof(PROCESSENTRY32); - h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if(Process32First(h, &pe)) - { - do - { - if(pe.th32ProcessID == pid) - { - ppid = pe.th32ParentProcessID; - break; - } - } while(Process32Next(h, &pe)); - } - CloseHandle(h); - - if(ppid == 0) - return ""; - - h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ppid); - if(h) - { - char buf[MAX_PATH]; - if(GetModuleFileNameExA(h, 0, buf, MAX_PATH)) - { - CloseHandle(h); - return buf; - } - CloseHandle(h); - } - - return ""; -} int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nShowCmd) @@ -861,56 +57,5 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInstance, _In_ LocalFree(wargv); - // if launched from cmd.exe, be friendly and redirect output - std::string parent = getParentExe(); - for(size_t i = 0; i < parent.length(); i++) - { - parent[i] = tolower(parent[i]); - if(parent[i] == '\\') - parent[i] = '/'; - } - - if(strstr(parent.c_str(), "/cmd.exe") && AttachConsole(ATTACH_PARENT_PROCESS)) - { - freopen("CONOUT$", "w", stdout); - freopen("CONOUT$", "w", stderr); - } - - hInstance = hInst; - - WNDCLASSEX wc; - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = 0; - wc.lpfnWndProc = WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - wc.lpszMenuName = NULL; - wc.lpszClassName = L"renderdoccmd"; - wc.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON)); - - if(!RegisterClassEx(&wc)) - { - return 1; - } - - GlobalEnvironment env; - - // perform an upgrade of the UI - add_command("upgrade", new UpgradeCommand(env)); - -#if defined(RELEASE) - // special WIN32 option for launching the crash handler - add_command("crashhandle", new CrashHandlerCommand(env)); -#endif - - // this installs a global windows hook pointing at renderdocshim*.dll that filters all running - // processes and loads renderdoc.dll in the target one. In any other process it unloads as soon as - // possible - add_command("globalhook", new GlobalHookCommand(env)); - - return renderdoccmd(env, argv); + return renderdoccmd(argv); } diff --git a/renderdoccmd/resource.h b/renderdoccmd/resource.h index 9c8e4c9f4298f1ead53b9707ac6dda074dcc9d39..85dc566281e74765466056b51eca5fc8cbc1da07 100644 GIT binary patch delta 378 zcmYjM%SyvQ6g{bVDJqyE2r3Lw5noNBLEIKMb>l`??qaJb#MHJvC|DOwdHHY$GVmHsf*qaht%>a~NbDcV&~HfTuX~ywA$smqA5Ur1qoG2J zmN`~ADHG8{8@KG5MD?5IDTdteZgMKf)%^wgJL8}+&1vJFs8$qQ@rtuvS%>~DTF@b< Wduzi8LxyJ*XQSW!kFGHwG{RrjZBCc~ literal 2324 zcmbW3QEw7K5Xb+|CVq!YeKeLr)#_slXfGZI0gCpCSnMgLLUNQ=WBlssZ+4*`x_3~s zId*q$?>DnEv$OpASyN5lX{ovztEIMjJgFO{YAR+n&=1-}Jz#B3kvf`cqFi$=crslh z8zEb0srR~K*3@HKq>sAPj3-BaP5%Me6v>2DOJk@hKzQVZz?}tf^{s9jNX!gvc?p z7%Nn{Pb3QE7Kd6g&7Op+9l`CZlZT*@ru^%NS*H&wg6TZsV1h%x?TwET3&*cko7x zPs%I|%e~#z>;X30xv{Deri7(WDyo#_$XgdXt5g=vApoo&GotcckSNO4OKR$ zT2HCUGwSgt?K$85xh+ywe06t()%%Q_U`f5VJLAUP7E7cHW*LN>-s<)({ahFN%y`1u zg=6~LXKhKgs`L^5>XG|Hs-(r-?y;D9JYw{QeYRGyoT9MQygEyX&RzXI z$6F_G68NFhJzjCf=rg??y}DQ2!soh3^>G?gmFynwvd2Ce+UOdgJ7L~tH=C`l!;)$g zBKw@MjJ7+miW|Xg=!h1s8D;d8*jQCfw$T0g2;W;F_JAl^HgB`qyi+e!X#Zcr^1;V+ GbN(BBl@ezF diff --git a/renderdocshim/renderdocshim.cpp b/renderdocshim/renderdocshim.cpp deleted file mode 100644 index 87348dee9..000000000 --- a/renderdocshim/renderdocshim.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2014-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -// This project deliberately references only kernel32.dll (ie. not even the CRT) -// so that when inserted into an application it has as small an overhead/impact -// as possible. Ideally it would be present only to be a pass-through hook and -// the first time only to allocate a little, check if this process should be hooked -// and load the renderdoc dll. -// -// The no-CRT restriction causes some awkward bits and pieces but the dll is simple -// enough that it's not a big issue. - -#include "renderdocshim.h" -#include - -struct CaptureOptions; -typedef void(__cdecl *pINTERNAL_SetCaptureOptions)(const CaptureOptions *opts); -typedef void(__cdecl *pINTERNAL_SetLogFile)(const char *logfile); -typedef void(__cdecl *pRENDERDOC_SetDebugLogFile)(const char *logfile); - -#if defined(RELEASE) -#define LOGPRINT(txt) \ - do \ - { \ - } while(0) -#else -// define this to something to get logging -//#define LOGPRINT(txt) OutputDebugStringW(txt) -#define LOGPRINT(txt) \ - do \ - { \ - } while(0) -#endif - -void CheckHook() -{ - ShimData *data = NULL; - - HANDLE datahandle = OpenFileMappingA(FILE_MAP_READ, FALSE, GLOBAL_HOOK_DATA_NAME); - - if(datahandle == NULL) - { - LOGPRINT(L"renderdocshim: can't open global data\n"); - return; - } - - data = (ShimData *)MapViewOfFile(datahandle, FILE_MAP_READ, 0, 0, sizeof(ShimData)); - - if(data == NULL) - { - CloseHandle(datahandle); - LOGPRINT(L"renderdocshim: can't map global data\n"); - return; - } - - if(data->pathmatchstring[0] == 0 || data->pathmatchstring[1] == 0 || - data->pathmatchstring[2] == 0 || data->pathmatchstring[3] == 0) - { - LOGPRINT(L"renderdocshim: invalid pathmatchstring: '"); - LOGPRINT(data->pathmatchstring); - LOGPRINT(L"'\n"); - - UnmapViewOfFile(data); - CloseHandle(datahandle); - return; - } - - // no new[], need to use VirtualAlloc - const int exepathLen = 1024; - wchar_t *exepath = (wchar_t *)VirtualAlloc(NULL, exepathLen * sizeof(wchar_t), - MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); - - if(exepath) - { - // no memset :). - for(int i = 0; i < exepathLen; i++) - exepath[i] = 0; - - GetModuleFileNameW(NULL, exepath, exepathLen - 1); - - // no str*cmp functions - int find = FindStringOrdinal(FIND_FROMSTART, exepath, -1, data->pathmatchstring, -1, TRUE); - - if(find >= 0) - { - LOGPRINT(L"renderdocshim: Hooking into '"); - LOGPRINT(exepath); - LOGPRINT(L"', based on '"); - LOGPRINT(data->pathmatchstring); - LOGPRINT(L"'\n"); - - HMODULE mod = LoadLibraryW(data->rdocpath); - - if(mod) - { - pINTERNAL_SetCaptureOptions setopts = - (pINTERNAL_SetCaptureOptions)GetProcAddress(mod, "INTERNAL_SetCaptureOptions"); - pINTERNAL_SetLogFile setlogfile = - (pINTERNAL_SetLogFile)GetProcAddress(mod, "INTERNAL_SetLogFile"); - pRENDERDOC_SetDebugLogFile setdebuglog = - (pRENDERDOC_SetDebugLogFile)GetProcAddress(mod, "RENDERDOC_SetDebugLogFile"); - - if(setopts) - setopts((const CaptureOptions *)data->opts); - - if(setlogfile && data->logfile[0]) - setlogfile(data->logfile); - - if(setdebuglog && data->debuglog[0]) - setdebuglog(data->debuglog); - } - } - else - { - LOGPRINT(L"renderdocshim: NOT Hooking into '"); - LOGPRINT(exepath); - LOGPRINT(L"', based on '"); - LOGPRINT(data->pathmatchstring); - LOGPRINT(L"'\n"); - } - - VirtualFree(exepath, 0, MEM_RELEASE); - } - else - { - LOGPRINT(L"renderdocshim: Failed to allocate exepath\n"); - } - - UnmapViewOfFile(data); - CloseHandle(datahandle); -} - -DWORD CheckHookThread(LPVOID param) -{ - CheckHook(); - - // this makes sure that we remove the reference to the shim dll and unload from - // the target process. That minimises the impact of having the dll inserted into - // every process - FreeLibraryAndExitThread((HMODULE)param, 0); - return 0; -} - -BOOL APIENTRY dll_entry(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) -{ - if(ul_reason_for_call == DLL_PROCESS_ATTACH) - { - DisableThreadLibraryCalls(hModule); - - // create a thread so that we can perform more complex actions (DllMain must be minimal - // in size, even this is a bit dodgy). - CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&CheckHookThread, (LPVOID)hModule, 0, NULL); - } - - return TRUE; -} diff --git a/renderdocshim/renderdocshim.h b/renderdocshim/renderdocshim.h deleted file mode 100644 index dc6e6b4c9..000000000 --- a/renderdocshim/renderdocshim.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2014-2017 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -struct ShimData -{ - wchar_t pathmatchstring[2048]; - wchar_t rdocpath[2048]; - char debuglog[2048]; - char logfile[2048]; - - unsigned char opts[512]; -}; - -#ifdef WIN64 -#define GLOBAL_HOOK_DATA_NAME "RenderDocGlobalHookData64" -#define SHIM_DLL_NAME "renderdocshim64.dll" -#else -#define GLOBAL_HOOK_DATA_NAME "RenderDocGlobalHookData32" -#define SHIM_DLL_NAME "renderdocshim32.dll" -#endif diff --git a/renderdocshim/renderdocshim.vcxproj b/renderdocshim/renderdocshim.vcxproj deleted file mode 100644 index e6344a4e4..000000000 --- a/renderdocshim/renderdocshim.vcxproj +++ /dev/null @@ -1,203 +0,0 @@ - - - - - Development - Win32 - - - Development - x64 - - - Release - Win32 - - - Release - x64 - - - - {6DEE3F12-F2F8-42CA-865A-578D0FD11387} - Win32Proj - renderdocshim - - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - DynamicLibrary - false - true - Unicode - v140 - - - - - - - - - - - - - - - - - - - $(SolutionDir)$(Platform)\$(Configuration)\obj\$(ProjectName)\ - - - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(ProjectName)32 - - - true - $(SolutionDir)$(Platform)\$(Configuration)\ - $(ProjectName)64 - - - false - $(SolutionDir)$(Platform)\$(Configuration)\ - $(ProjectName)32 - - - false - $(SolutionDir)$(Platform)\$(Configuration)\ - $(ProjectName)64 - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - Default - false - false - ProgramDatabase - MultiThreaded - true - false - - - Windows - true - kernel32.lib;user32.lib - true - dll_entry - Default - - - - - - - Level3 - Disabled - WIN32;WIN64;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Default - false - false - ProgramDatabase - true - false - - - Windows - true - kernel32.lib;user32.lib - true - dll_entry - Default - - - - - Level3 - - - MaxSpeed - true - true - WIN32;RELEASE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - Default - false - false - ProgramDatabase - MultiThreaded - true - - - Windows - true - true - true - kernel32.lib;user32.lib - true - dll_entry - UseLinkTimeCodeGeneration - - - - - Level3 - - - MaxSpeed - true - true - WIN32;WIN64;RELEASE;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - MultiThreaded - Default - false - false - ProgramDatabase - true - - - Windows - true - true - true - kernel32.lib;user32.lib - true - dll_entry - UseLinkTimeCodeGeneration - - - - - - - - - - - - \ No newline at end of file diff --git a/renderdocshim/renderdocshim.vcxproj.filters b/renderdocshim/renderdocshim.vcxproj.filters deleted file mode 100644 index 1de862269..000000000 --- a/renderdocshim/renderdocshim.vcxproj.filters +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/renderdocui/3rdparty/ScintillaNET/License.txt b/renderdocui/3rdparty/ScintillaNET/License.txt deleted file mode 100644 index 80e563d93..000000000 --- a/renderdocui/3rdparty/ScintillaNET/License.txt +++ /dev/null @@ -1,21 +0,0 @@ -ScintillaNET is based on the Scintilla component by Neil Hodgson. - -ScintillaNET is released on this same license. - -The ScintillaNET bindings are Copyright 2002-2006 by Garrett Serack - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. - -GARRETT SERACK AND ALL EMPLOYERS PAST AND PRESENT DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL GARRETT SERACK AND ALL EMPLOYERS PAST AND PRESENT BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -The license for Scintilla is as follows: ------------------------------------------------------------------------ -Copyright 1998-2006 by Neil Hodgson - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. - -NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/renderdocui/3rdparty/ScintillaNET/SciLexer.dll b/renderdocui/3rdparty/ScintillaNET/SciLexer.dll deleted file mode 100644 index 39976a576f298514d0fa1001b9ce93257a25dfc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 648704 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 z%0A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 BwPB1~ze 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%0DG}FTvo@5bx>;NFIlFBG5{(HvG9o5)r(mp+)uX4 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𝔨~uMXXjKlaS)+2^-^XNJ9<^D{viarrAsLbpQs# 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%0AUtNiuZC~0oKAN6YK<(NNLAMe z;CadduFZs3t7nmr;CW;G^SQC%PDb#kGmGkufuMsc`q5fNuH-zZR={*>A?uVyd{Q&o zI~qMB!A^;`i1vFn`d>)Iqv53+B)pok$On4c8fmKusMR|^AX%2r;WWC$sX}h4#F4wC zM*jr)Djj=@oEm!P~sdtD%l4*?GoGCi9Jt8ho zAOrjqYwoA);sLkiXfvUI^8gB_7OUA5{Zw*@BTP--wv z{rgVuOYW69fJ)Rq4G7kO4B3P9Mr4pqdF>qrmpkZuN0d24u_6z8g%Z>Lvm-mXuWy>g zH6@I&mKvp{eeBCbG%DWMa`kVd=IWAZ(KxvenO@lf`Br-6G{n6i4n>VVx>8r;QE(#n zQ$T1dhDz+}a@&u1=LO~V*^*3*u;-Pl$4NscjS&f`Ty--^qLT<_Qq5eIMi(Gg%cqDF z=Be#W~9fRR;sY2_||WyeyyI|bF{ptJ}c9zd-_d3${SRChl^0osT59fNPijPyK?E~ zjk!WQVn&}(&5HvjMh`%QTWLMG<k*^SjwrdIL6libzj|cCG$IxZ=$?T-+7fr){zU$rT8qScy=v1QE;1ckxS z3Szj`tT-a^(c-R7qu)~lu4OEpBVwse+(tr(IzWC>AjE^y%A+v)r58@5tv9}c6Cu8t zn*9BBGuZ(r@buNTGpf{UD_E2>+hko?BGc5*`KWNAtk0#nt?DQ_2GTjpm2BRKsH!R8k6aZ@9C9C^hlO?0aE$Z zc(KKk_kMdEZ;t{$&eGtA$8KB(XNKEBMtB^aK-004wDfXM^h_jUrp#_iD?YLG!+9XJ zrgZns#{{p)|FNMZ%ZAohHne_SH#E2H|AuY2fSrk@=&=pUZRWkO4V`*n8QRNX)v-Lk zn5g+a#iw)jHZ0-Pl7*Sz>`m?D?1kcy<27e*EZODR!z8w3GXjG zie+?Ii2wiifKPwQq1DL;?0$nhTCF$Isw?5FG%PbmYH8yo=i9}e7ww}zG&QzI)@FY! zp0fTP2b`f9l2vN22f!-Wd$DLTPx8=CO$u_`zQbHxf@IA1GZ&vP?aEv{sJTT} zkk1*^CEax<8t&p>C_yFZZ3>eke00G&Ut<~0B79I|s~67VpJ=6iS^t>;4N#wQk(Fz* z*pnjtX`IEwmFjA;XT`CkoxYlDm=qsy;U(f0z_1mw-S!ybu$rwHM}P<~d`&&N%=mRz zA-r30f^Ki@80zGfAOZisTQ#EbqTuBHn&v2A%T%}u-#f8fq!ooyRhIIvy6!%xgNMe+do6q}ILQ_38s zC%55NulSpp+?sW94Q`qZ>jD-$EW`tvg($O^>kAWD9|4;fpAdEjoMXZxWcFOBvoNF< z!zFy22F59vez=6(;a0_s{TVLd?dxFrY4d+bv_9xZ70_@A=baAUpWqVuCBo^-CETNh z?ca{y-ry1*5H~{3px?U<`%RIN;HOw&Bb<~W)U80^?%76 z`pQ@AyluI^WEr`w-I^V?4LUYh%@hX{f5PJ0MKMM>XjvgS1XwC)2RUV()mGJ5;W-U&Z-`(Wz1%_x5z>a>169 zpi=E$A0AR3XC=Rp+FkJ+cT%x?03*(i4vc!`HJFYz1A zON6!ueL&Xbdn#$l_wf?VkrU}Jhtt$ zGRA7@C)I|R_^xWdNw!aCWVPWXzN}7yhJU34*zk2U$YZotuo4cgq>)_(K}~pms{5X zbL%<++t6LKhx@0DkZ=^gQLo$>UzU6HQdF9w__lTTLT+PS=6vYVkYzZE+5*LaYPrY7 zt$iP##cURqqGuRjaFw!uWNrk=aLgB_{)wX0f4-;G@1dO`;J#IA>&*rijJRb`4`Wna z<}7$9OP|#pPqtdV3FSm)FuCz26zcA&f`rupdEbds_XCMtLdGS^qWZND0WZR9tjk&GQ=*qYLv&eU(tQ&J;@AS@K7_NggDjAwI2xgO*LwG~U7+^CCH%!)g$bBp$&j ztn;)277dLYGB>Qi?_>*)rCEUuI*@J!e@lA0bd0O=tiWdwYq0=p-&Sr{xhk0#D3mg_ z-`sD4kC7%`8MX0pPdPZBTAksG-0elyrAr^&Pb}3qL))8_Dq4Yi$U9o3yGf(m0*Xnx zh?oQ%(3wf>*T%&ZohkNzb z&IJ*UOM?vDm)C3zStoSLg;KSmZXt73n|RArD+a;sv-4Jn-12W{a!*+`Cf0klm}0L~ z>-nDDI(bY?bXQkQbb3SZE2ZB`8^=$yzY!0R%-w;+_46T`wJNVKEfy_ADpD%M`4#G| zQRW_7w1sL6#7RWBhA0l zoh2Bzs)gT+@vXblie6NuKD>@*xVvKoyTU1hbf4#{)usCU$(HoBD$k@B(TXw1wbb>R zFYs9^!@yJOGNa=JGFKfh)D23h>l+;=kcCRcA$SWG$P)Dz14*vyKR-Tm7~laubsL3R zFR#iQcs%;2la*&;&hxQg2Hhgdy7%ukz zd4_E%&1H1y`7)msJU3NFk5yodXOl#4LwbQ}M`A=y@iFq1c0MT)Vj0Rsk*ztF#nv1f z;Pj*UB|hgIP{fsczoh73l3-^vi=Td&8x`BJ{GTe3X3y2}+Nf=*&|PRn3I3d?Hi)`y zsV|o$@G?%;+2}IE8CSFOOx^lPW-_j}!!3j4z?@EhT?Z#1R|J+sBUtq7ebF&wn}tlU zsU@-qU2EB&>Wz=~rq;UL@xoLJrHPTDzShfj-hfd0v5yA-$^A6**xv>pb^npu>o2`9 z11WZgC~0~=ZDfN=smme@y@?r_6}`2nGcM!tYFeKqJvBA5nLanQk(6VG)ATI*`Z-Fa zgCS>o*Rk~g>XIYeYV?*nS5`)rUbF#XXaVlUbbv*>R0mkJHxnT9JfD3z`Su4b)gGUi z30GV~W!Q?eHG+I~n=Z-eZzjgC=XA(M(pSWuQYDZi9NlDl4n*qi<&J~><@tJtYe$6C zY@BL5Q%lN8iu^-ZtH=kzv8>^8*`CLnh@O|C>r!Pa+d0V`9dqjR8Xpk3n|{!fFvCc_zC{%C4ec_YTtW=UVqx>%b^u27*jb=igJ;V|MW_smI_grLs=V(OOJ> z^yXN}{#ouG>~OdABsM>C9$5&sMx%9S`jiE(^wCOf5g?ya(5Ed+uH=~-jKG=Un(1(6?k2i8Lry7=V^;>0{gXrd58K>i%q{V zseO@qPm5aNMX^KqqPJ6E-=yd*u9{;{W4czlYKT3G0Hkm^dB3<#Z?V&&7bhC0E+zxn zeN58A&WIrrVOA`8_Sf;9u|BU{IZ>qxR4e@xQ4F8{TF)2S_=kw);fl49{S`D4MoY;g zyP%}N9$9jUJ-h_-S12$HE;+{@STfY^UvjB!L2~U?l5ck}>Ex!A%mw{?(2GIO1-%F8 zb3m^F9cMt0O1tB}EUxu{b=t;DMmSfjDNDk>St@fsI;LcVb8%xsw+80|=r_@!nzK?2 zH`m?rCLH5I%Q30f82l_PGnN;u=V!{Al#4kI_6a4fXv_TVYnK4D`R_|gVrC|pe>&uo zFG3<-bRE=;)oq0=_xR&HxIrdTQ0z{G&}v5|;Ol0msk!1|9Bj1uA4`Jv=$r8Ri$vd! zH@%cgRAIHu5W5Fnhy=RypP`C}nS_(ij;VVmoQxT$<>F}8mwc@8l8Me)jSWc?L%~f_ zLdC;Q_qwFWlSHy%{#^fT5+f5lAO3YshgjKma@Le3Q$Qcx1$*Y}M+a&rNs&dML&}`g z$dD}?U#Z5_n7C0=fHTs10|##RR_XcMpRU9PIiO^hLUo& z+CTne%xj6|b|X6EZ=#vwm0zc_0-rK%<4yf6vX`&o6SwR1rp=F#LDA9Z=+&oEXy7um za!mSEQxQDL>F-Ll0e)sv;KC=VeA(XT_YqZEf`P6X}ohuq&e+s0DqKN+(N7ff9x@85exNaUF zQ?)atmpuLNiih!1-YNxT$JARFvpw{Tya~R^Yp4|zNq1@@SjpQFC#&<7t0%ytYB(P) zK79KqD9&qIQl(mu+3X?E%U;npQKvt_k4;cqZ%%O5F8wpejhi*{P?-0KFKxlh=-#KuIRPJu;4Jg@aNK0%MJ;j{B}OLn^2{BG{-ykNNC7H%-MUN;oXI z>YAw?SS+>YY}zR7;)=)BBm=l=(q zwOAB=%*O<~hy8Dj#%}BwVFh~8271H_{D~DuSNy`Gdv51*ynh|4_&V^IrJpHb|KpXW zb+vmbwNkxz7wdmVhG`1b{)sNkUYux$V*oP~?O134lN0TjVE{#&4tWi`+yI7|hLPz7 z2GG~E3P7#~I0L0R(k%7Bl^6zSot@mS37p%(1^$-g_ULC`j#xR+?H$3jBe4`lI7y|T)uq$Rmy<(Xx7iaa zT5g~3p*mG-9{eBb(MW$^P5+|sz|40_2_kDQ!3zU_vPXKO0`y`79YAot3HH2fd_a$x z^Vfok7Dl9!*E4?Ol5QUsFJw@tKEN31y(UR*DdIY@vs*-@p@{&RayGGQ1Mn#kIsWP0 z_wox5n|6X2#VRtI6U(>JaairQ}6>T>jcZYI37*s2>m@r=u35oNkxAp z#frSt)snd&MXzR>v72^oEFm_F7J9<1zra$9@d9a$JqFxvaX?wwk9=Q3g>jUQHOGl@fCIU;eRG*4~vizMhXd>SWJw{AfOC9{+*W=uvG z%P}pN(qq9V`3pJgr49U6hhBe}pSrU}8n;X`4L-_u@=jRNZ-~py=K3ZM+~Ri2)w``I zqTDqCdiCV9#8v0JSE$?g!VmfgqoX1py`4`2kVKFDrN=jcf z5?W1Ag=V&>Q`~ehD#CU`k^Uz1FB+FV4BvGKxFLUIIRrEkbmG4YKFG+ylB1D>eRZ;y zgXP;(ejOLTMEFk%-A)T?#L4U5A;xRAoG=lza^c%zPDT7Y92+CXRhpfHn%w@0EFJ$B z1;~2rfxm!VruWnbV8HO^G9dau-y=4Gqd(gc7k?<)9K@mR*xk`?zeB>UJ1$7-_vH)y z_E5A3!E;4tx`xe+!)6LBQ^PKc!%75}tzo0$uzZ2# zYS^GS48C$(ZJ~yxdN8qCb0~_E${{+Zr*mz{IRq0Hiz~{P%lz#mQ6s2e_Yob>1SmI& zuL`yL6EP8?#S@Bm)r%~HCS4!G+>DC7$M%BA4s4=|J!@+A75kx9kL3E9@C5wB%e{$& zo41tC3#rVd>bhJkvV_|?E@9&R>3nAQ2vn#THVD8)N0VzZ@E|Q;8bvrV>RFItFG-4~ zz@(G>Oi}%Rc}f@rPCs1gaV{_GSyueb(zhex-a8x=l-kYGA*}}Ar|wpFyX~5IY&!RzNQVri$>e~J9-WA;>ozO$QD=0Uj?Ronr=auqv6u3sj{5d?uhZm8AHjNoQ<&82#?t$RP@zT~!FCSTWE_wLqTrI-xR0dAD9 z=)k2ow;%vp_=};sD9qe1ra|TR+%HUYsuJq&gHCl3wa|C*i z5SnvXJ30$mAlYb>1$8%q>CuTRlc5vS7nQ1s-9NN%1|L_7VB^$Ebp~f5RWFBOj|;O> zpNrilE3l5aK-144D2fzUbZgXoqs`H${f!(%=7|HK!*viM2f22 z$f#ASS>9#Ksg~YKiq0fcP%h>Ny0g##`+&M<9die4^Jl_q;kUdFTk`aI+_ z2Wl0y1nh6X^dOk7AK{dEb@>Akl1~|AlR}2Zr*{6_>?H`F=q`&eev~?p#}`zl$ot?( zHy21ZLm}kT%j!IEk+fs^jxFfWis6s0{1m@fsKBL$3-0t%#n z1(JBQBwpp5=@szSxt(+z-8IoAGeYl)u3JC3*gfM#vtRq7*ShU;j60Tk&;zIHBGpg$ zq;p1SUWmZ#k)3lrDo%CsQ|zp+%i%gw2>p+d&sIasOu#%(>U>-@GZX@rXceJt5N)0z zPeZghr-a!jR@0~E;q@ofu5Uz0gRjqLBP%pd!;*<+>Oq}pC>dejiSD4=alVRv3*3&25y9;kZ;y04 zCfLI;YB2<&50=pv)@vsoO({dlD1Y+BN$PBhkFIM?8RCP@FXZ|@m^Fy@Xo3RNdPS12 z6a|L3P*w!86R!!3t}>_yW?2CtCVIkIv&-UlhX-kL?IzYlm71IYHVSZu29EZC_ARx0 zG+;;^Ft7H22K0^tD(X^eAK(d#$?J(sL)rf93BV3%w9gW-5w&d^vX>REA3RyuOc(v! zD)mMj2}>TaDW06zGjTjjDd>bhiv#A=rk{{xYvO>bYO^%pjyPZfX4P{v=*D=~_6T5k z8a6Ef>syLo<6`8})%&rfvcBU8QZ6#9Yg&U>Ug3w1s{y;N4<76Fdaz;C(M zO7pD1^#aVt6eeCC5&eFhNB!FoGT&RI9381JH)!wRs z%M(ChhS#ppz#k-lI|bONffWhh^8#$r!0`#-&jt7*q_iqEJOOMH-~$@7j|a4u*FLHN z|GvT-*2T3?YCu~YFthd<4cH$COs;)V1O6BX6xD9lfZxXf!)kYFz=k-WZ|z!e;${I^yA9J>V#HjJKhAULqP zO%9Z~Q z0?3&(|9l0A{~vMh10Gdz^^b3oO|pSa?g9w}39v#?G@#LdCTyZX2m~d#A&@0Pz*dZD zN)_Q=KqZiPvoxE_3T?H;{*|Jwt+w^;D-f+<{$K)vib@qH&YYP!bB?EcE9)B39jv+!J8a&9r*Zn;R@ zaqOhjB=uJCS}23p_+vDsrlI_2B#~TEha2hXd%2M zs^;PnP*Wl3t>WbRjw<;BKs4DS>anFt6h=!E->#J6KqFRw|B&wg3!Rzs82?EDNr{&P=zi9xX1Fa`?{y=XYg?&)}L;I4z*a9JaxL z-F`zaBw#Zrl|rdt5sf1SsIv@0x7v!{fNOmakq{T2r0K3P_J0wd_J3#Dmg!X89n&s5 zDRnl^Nc*$NdfM_Q{;3=kZ-Dk2AlRr45#_V%1m6#32&~-53AzR8Dy>A%OHum$^Q>c~ zGh7<{LG>6>(GPgkfMY`{E%81P@WPfVD%<&spLMudI0FwKIrEr zRJh&~IpBeTIQSsM=`SsI$CC5yFZ zAx36WHLjQ3BasN5mm<9+y!sN*ez@18kRnGmyCy;cf6^0ZTxXEEbDbdbt=LdnEqFC( zE758DEl=94l<=evUVmi`%r}zmz_iJ)wB4g8y{a$i2f~sLpvq8ef2rCXtK84iT^%9a z3!_Du8`m2oN9*Zc)t9ammhLkmUB1pqXHh5sbtK;@Og(CMisY_EC+E4vM#ycmo*Sh9 zN#NzX5vlQ{Q6SG+QCHl%c5t?Lb(G&ijz3qAojnUZ4^0eq^Ld)i1Acd%QAx+Zi7K%K zuro7g!`(e9vrT!3Q?W6G*4LZjj53ou5MGx_de+xaDMXWx!mH6tFQW1zjF`Qk1sXJ& zCg158ocp~axqpvmBQpxrxP}+VO*SkVI}yr$r-!^vA&ro+*^_#Rk3s^3^SB;D=Y@@( zuz$l=>LFt(q=#^p@(}qh(3%U^oWB7;)R1>ZG;0~9SJ7=a%Lki;lS;rrsFkb<(k)Mn zsA$lRm0~6sgvm$#92!kMdSyh3#7FTI$;%@9J5nU%!Gv5$R9Fn;BMOyK4nuxkM;=7T zB=a`f4CLQmf&7?`oIuE@@vkw}Kz{TJ_+}bDm3dCvL5V%2~H0BrX&)5H-bLjViHL~q<7X~+$olRNLN#`&QqCa2g5vu zEk#7gj?ha2e9adG@#c;Jhi+#x03xO|iqb$hBEVSvWDx;gK(cjeE@HEvx2DdKRsv&| z(bhO=5O>;dLZd}sy_5;s6|9$gf`IP$wPGaykDev?;H$&+k$j7urMn(ks=an)CpA*^ z#y>+j$m&~7hYqMzN1%Ef1ZO(Me4A}R+}v{IOMF9f1pz;xfF<$=20}SUklb`L70r@7 z8}U&5x7kbrOjNQR*eDH4aIy&Yg%V5?36kdko}-l`_;Iu$zI#%T&SH5;h$KG`P;&bv ze1w9_mA-^qDPV~lO8CD8f|)uG$_?GgrBvruH4p%KLQLQ>c5BHxJ=IU4!CBqEbc ztCu@QkBq@(@^5Mk301KoCeM~)uDK%H0|+6CF>X!1Iq1TDlGFYNd2vILbFPTIS&t0X zXYyGoa!3Tx`bF*;*1y1a>ye>LYx2D#Mo%{TwcTJ+!~2StuA`z>M74f}^3ugjG!b7h zJpL{W5QtU=1d9*aB&AVd+K_?ClCZL+$YKkAG84>P2GS7h#!5y%-C-wa0MLvuZ4y#Lc}J1XtWt5Dt7}U zCY%UK*#*fkoC2#dXb#8K!3OedCeiz7C+TnBJB>T~IUB$ciB>LP81 zOVFgoccGINT!VVUF$j#uSc24gg~H7eTajsOMBW0rI5Jv%CR2O4#cDb^yxs`SWj`=N z2l++9z%67h5gJ=Hc#)qxtrrUK?fC|>)&C_`h|@>5Q|T(@BmF#$-E%8%Rmois8j$2f zwv%hnlczC-std)%9(9%eis^ls{t8cH3ye5_n~zk~z<1V@p_7U1Me$i7J#jNIpeOY( z&)v+uY)>4ABPy&H#_@%%jg3Xq`x4Q!5p@!KSVX-~a-R`>-Nt&+e!dg9c z*QQ|dm;$<{#7Ix9rz9}d`Dd$vL^`w?L}x0K_@RyR1!s}T;2E%GjS2Q`kVm}{cH`#4 zky13t2(nG@a!Am=9OntttNk}Rnw1PerkucuUx4mMH9Q^`XppB!nXT7Tq{t8{NQ@>r zv(A$jbJAV5l~N`WG65B&g>3R2;3XOt2JVyum@~FNa`1TN`cUk50nP#cR1zr-&cNJ2 zqL1Zx`X2*lQ10Mu^0AY*Zlz4EJBht5J|B|YHzVs%f;C7GJBIt+67ENU*7G`6&pdE2!_cEvxM|P|2Xc5dtG*6r&j|ZeX1XH5b z*u$i|y1J`R?9E%?(1An}TM*l2u)u2J+w`egK!tgZzim&5x0QGcI@!fe?m>!G; z0^%y`wCWz7I1Ek|!dX{L%;g)4!J+2!YgbRD%_S92txw^nI{&3Dh%X+&T_Sw?a z`%mHQw*YS2l~ne5Fc9STkaG$w)d|9uEE0nw3Jt_AOjTQYiE0#?%&KD}IaRA>MEhnq z4-jTHP)!<~wl3thv&mjFnS0-cMWedU#w$^W!smbiebj*JllAygre%rl1$WXn(5=j6 zm`{7J#gOVv56%C^#QiL)t#9If24A>o4yD{=4VoXR*qzMOoaPeoq=~!KMeks-Qxw>q zvC%Xywlu*6scpQdW?v4*F@|v(tgTeVEd`^o^P7c&b1fXqmveR+s4zPS|I zmpvvWDwB9milcso5s(Nsb{NEjAi0m?jYApb@+OUT@Eb?FGQx!p$>;m7LB@Q)8eq5? zP=>HiF&c;)JdF^j-5h~YCCN>zAhw@FWIoowqKJR+LC;koQdt3P7a+fUF|V@od<@X- zCC)Paz)^h2o}mma6l9+!uP_s!J7y~6_JlkI!ECZ^A0N4e;4L@*+uqIaB3f?R8SRP|;7`z~muUi|r3tno znCeYVwvEIoa8$a83XVz^lqaSuVcrctv52f_*USGCA`-nyRPSS224?V%; z+e(`mqK1jRG;S4}PB!+!cR>(}fqfie%kogRQI7{v(!?8({Xh?)In6hQx7@h!oQiZf zXXV0~;=RhEzRH;lINWMt=fln`;T%;oie(4!sd5}z5QfSTU#)Yaie0ZsqVcICa%#_ zucn@whI2G*0WF#+_UYoa>VV_o`t3MN(cL!l86;C2CepF8VSs+rLY)5gnU=U@n3jmS zJiG@7Sg(?wclOnS%OYGrgbw(IXYXAeei7lDu|vjQML3-;TX44AORBAxnUYev0DTMQ(`NFv)bYNkGEM%49>26+6#))))i(ufTWG?I<+~!y`q_PIo>FOxV zW2ja-rdAHKze3zWRdf4duwr4@7bBA>mnBD29ZX~>ux}0u*r@*a^#jG26Iah=m}|JVgC;M(2Pa$6;|haOt8&e zeJVj&j56FSxgW#`)0D&ht3;i!?TE#14~@P?bR9Ag(Lp96xOMrr+21EnuZO&fh#{*G zO(L+)jzB@wAY}rKx#doTyFrBIas}dZxsOS87chWxt0nh8@f4`BlAGZJwFb9}|G=B8 zaRnK!KghnP=hemopF#IQ-~v66Zl}8%pBI6*>w&-Ifm04~%zcj(gVwR;AG&&o;7mbnFOI6Iu%$fEbctj7^uXynaFW10q6bdmfmVU}x*kY-O|HgN z5%@M!z^^e}T#cC`kd!JYcQRw)YP5gMbN{{`*vbR*1!k!p_-7tCR|HPi z1E1!Bi$vfgJ+O`kE*F6#c%ZTxT}%YTiGc6A8f6jiPaIHVy-@6GtPuexML@o*u^yIP zP=D|902!>H*909DVHxEhdrbuM(^k?9aYfNc>SX^d+?IxUUjPrd2Zn?o>@hh8mQLUU zL3rZqgxwcz2<1XZslw43Zf>qqDBFZ7Q9y(z*|(El5-4Y$@+08LbrjL_ghs=hCW;R!?(Ge2z{t`8J@-ks+wj5R22I>BGr+SEF{S^lD)aeYGYZbcB*lRt;znYIG#+qG*)ik6@Y75&ELzB?2a&^&i zgtj1k64}4wPT9D42_SAF;6I`l(&lCw?S0zu%f`=!TORRkb?G(KW6DrD)l@kzRJ`y< z$g+TAvqh?#CB_Y1fT6k}uhQ3Hd4ay44Ec)8y-mM(k*;MVde;WI#C4F}C_<8m7~NA+ zK-#Nvi@^a3)P+$kB=M8I&g;qL-vsKnNo*!KJNoSi`buQC@GrO?0Znuu03M0^10GNW zo*>oL;6+4B6o{)twDBU5&4y4IT5IrpeN#rAme4MN0ug>5pdSA|^V#Tz@P{9te z!NCK?5cOXqVT+9;FeJCa;i1Tz9s~pcTEg<>NnejZS*?^vz7mhu#6eKZL5g$OSQUr8G>PLidMJxRpN)VA+=>zly^4BJ( zOYClLend&7FDtvBf60TW1<*2u+%Ohw7!d5`ySQ*!_cgdR$~}|q5CQJv2*?1khKV}s z{A}-LK43GNk-$t;W-9u^%+=Qbn(BRR3h(qZg2(&y4nH)9%n{VbtG#1a9YJ>@45PzO z5gp!qk~+MwT%%)DuIC-@Z_rQ?n)At^!hq4b$H{&Zf{||t1GbsRQ$w)hVX$o+_CN^M z6b7Ru4(x)4V9$oZgopGSL$LZVm~fjtECgE-2789**M*a5Q3huitP%?l*gp)xri8(S zFZb6&F!H)?luvl?-VuV)U98t>(WWE7*Y>6ma5#WQ#20y`Rp~G})d&|}+vn@ySbw7v z`rZwTC_J>^WFTCRh{SU$g~Rlbq0D}TI2y(QaZ|f*3%>T!QcBOK)X7d`uaWmx%9|%4 z8uLE;jq3!a&Ud;8<(3!)7bRScOE#l=-I`vx;L2Te~#OOPBx)3cNP2?};)Wgt4qB-PcTta!baDhe0F zC~h^)^L7MIH1U9J9*_<0Vbi*}oo|$Kib+WX%5{BfvG&kfjCk>+&|-|w5TyE=$yZ}^ zDo2Nu;3K*C+40LJHg9DaLqcb7Q$PVJEG1*lF;jYc57uB%DW1zle}cJTvyjI;q;+H} zgAex2=_Iki($2$}Y)F74ZCEQLPFlfPSpvCrDC3@r;D8x|<A+}yuyi7B$I^)~ZM|_5iYWKQs+h_bp|)AVj)PQ{-waJAgi2V^Av22{ zCk}Sui>&0Qt|oU3?x@Uie6#AG4dyYq5M!$>{_@=MN{JpRCKM^kUqC3=%9CLc=(^l# z3hV_3vG&G&+L*Sg=tA_ddEcVi3T#ygF=Xg8A7B1Sgv1TJ1Syw2FiwDTn0MHC07+Jc zt(r0HX^C2d8$z|N`WoxZLU`D7w5=NL$I2XXm^qcL5hz%|2Xd6aYHUIV+Gaw;Ba+q& zV@|p7leQi80qRqT3M>lZ=#GBlHy4AxJalKhNYO@-peNQ~sp-B(exRoNdilHj!0SWY zTLCHYu4va>z$aur!-bVAU`z8EG2i^HH zo-pn3EFNUqp@x0G6D{a|9^dNyPjVlob=oFk2z1dX&LwO;koZ%*8Foo=sYm<7QC%;o zJ5cYA^19XQut<8FxjzfQjQW%HGxN61rT|a%lk8!Har+O1u$(@G{f8M*r2lm0qOkwK zFS@US=Zufd?f)U)%d$RTf)y*6-_W&z_e2F7&f203mul*&=&}?2F-)pB+ zVeGb#Qtv+p<3BJQe>5xT@)n$fvHTijhr?q3)%^Re684Y?_ye8RDuYW{Ir^&}Y{59$Bs~IQ`e>h0z29o`k=+kR`QZ&PG+_lx z{vAG%nD;UGtM2qvV@JQoQ61PQVc>u)7xSGUvf#%74niI*VMo!ah=}_rc6-4o#5O7S zP>h8x_BS1PXKl3woz=8qdV9f1!pM5hv(TEe@DyBn6usF&C(i3-~D9}4N(CSFcT$x}~ zqR+PahC}Gp_(_&}e-GI_vAK^aWc1~Ejr~d)dr%4`$2acVi{cl0TfpW=cZuL&@4ZU3oz4hpC zpytpa?;XL#twxs1(_z{H>qtw9cC@*}f}ILWR|}^#rD2fT5;g6h{7&5gxmW}${=r9G zT5I!Xw$i~zwLz~Fom#Wjm31(tGp1YpCP*Z|lhvlSm}^fE)k@j~PW=1yh=S#tFFQ0SoJS!f_gZjAgKFOJ`ac(H#o~WZ?*SU` zIWE0}4l_Dvp3y-8|Cjx7Jeue#(I1og`r{)(f1>x1Ucbfr$R&S__YvxVRy~i=4MS)U zyeC)GgZwBxqp$q2yfmVEqKxVRs$M-O5Mv6e=UTmbhKlMz_iy)%5S3gZUfO0yo0hfe zAIng<-WG5#8ryhqw?LDw!XzzSt|#@Wh?s(b#}hM5+%o%vO_exXl+Z&Tg-wD zfyJoJ3B_ttf|ES}*|_Uy*{G(n{199{1vv-u3w!AnE;7jyeVFu*FAlVxkA3mC3AU)$ zpTYmVg~(o+q$cv9swnOk;2rn_auQikL^D+;tc1apsf5hM+%lK9sFTrldFAra2{uxx z@+h6``$+!~F91ejk)_?V90_O%o8&?1zimGDza%tW2WcV(( z@ckF>%BWJdkSe3hGaKkKysBU~kd+~I$k%PNEm2FCiISq8YBpF*azb#8nXQ|GC~Ae- z)Hcgvf=fnX*Qh7pP+)r;5ksJ0CVQOvV_0z49`<|p2D*e&rUqg z;du_v0Gn!PBx3A01MsEr^MdK-Sv;@3!N7g&}qJJ7n7N*w+!O0S22#>;91 z)nVXz<(qoE>vMYaHc0PlgTzZ`pX))sY15EPu8-TK)v>ShLtJBfy8Qu!@VVGOP@K6GjP;ax- zG3ps=S?O`=`C&1T_F>R)6u%Dq7=E4j1@JS0&|y@vnNMJGzaX@sa8C-qqra*{6On;oRuE0MPJc+GcI~(o3XFH zN-1IM!C$na_%3rCU0v8{vOqvRx;k2G#dYx3RT36JJ*+W{*cMnERs}YM-o`_JtB1-r zHV31f-YJd2l)1=$2hSWVA&2=c@hmfz5MJtSXyPqHTfi-j@DTk z7M~--+(B$r>Y}Bs>NSv|mbO+|D+8(E)rY_`*)-5iQY-P-9%4zJf|FqGcnh)wDkZ#_ zFd(+Fk-!vulW=zfq3h_VCd@5`pwSvVElRmzP!ojN??fpR2Az~g zlhialS{aGJA=ADS1J{AgX2@WJPAczdxc}d}byU;49coilYgY>xnn_M=h$h)CO8F8q zF(MuBYQZwmBtKiB0YK@$jnFnq{|%(S2dcULdR=_@zvh?sXAaCSU&=$Di@-1Ue2mF%PMvw}2z6SA=2XTvWQKRbRC@yo<-27YLp{|Ee%GSh-f@P9de zGJf?GVzkZw4Zo~Pu1p;XMxx@b0p}q_wsq4W+GP}3Jw=w_!el=-58-I}Z}ks4UXHi2n~8Vc&kVNn2$E~DnZTy9DfJ0FbvVi+FW1sv3T#mj zZ;4|ex53weL5i%PBFT3+j8wpYP3#7d6jvdFpa@-e8`Ry2f060I)+$@&BFduWChUwf zfk1412yz_-w(4Q9_@ljzV#Fv`Y&??P&(GTnI*2h{mdOFcZb^o&UWbX?pg}+9q@Kw! zu+eZ)vu&0YDxAuF?6@zBBtE}3!6pyY67N+KZ0^F9N<1sh z10IQ&j@U{Wz~L|j(g%kC50TCTBRjJ!=kr%a!$N7{%4lQ~V}qM`~n z4=n7j(*+5(%Scc=pjbLE0ZH>D&W~Jr^ZzD$^S{adzRR;0U7!Ztfhf3Hr=VXKAn?DUpWS3cjKe zEJVUzFi5bZ^Y`xpmVZS+|1MxLvLB!eERB>s28o4b4v;<6%K!5oh$}T>01S{l4z|Ke zFWMkpABKOvE#fdF@V}y=UmFm*LB#-VP!@>_Qd^~Zm>8J~0{<_lAoPDj#rx2>I)hmw*;>Dc-6lvGWC}~$& zR0Ob9fTID9jsPYd4aANCI0j%TEO9IX&Qk_&0!3SCc06pB*8tTFRC9!sc8HW>0gjCT zChtOs4gW`FaS_1x3vfKZ@dMCt2dBg0c-X?}umIH(A*E3wr38QzB7l1!--#w$kc&*vjd!0@WHJrJsnD5&=$(0G0(f3E-p%;DrJ#0W1wb2VGCr zR@xj7+lY=b8%kx1kkVk05`0dT4T%7zvmL}73h>Yf;I{-A&Ya4I4M4{qfugNUc08QS z>mwPc$q`agMM^0Er$hiR7ht%KDH|REOxm*`a|FO62B2dcrz6$za4M%G6{x8ZQlfjj zNNFU%k%kjVjsRZ;@Kq6F?-Afp0FN4g4mz08R;D=~PLr#UQW{Xx`k`XgycVF*0FAy9 zv;?3r0FAj4G##L^0FCVj5@S^v7t<2+X2u1_1^Bc9+l^_Dc}ES7m3~NvzQOc8w=afp z-sa=y!p@V9;*;|Cq+Q=iyNXX{e2by~9`ThHuRIidMfngpeGbs)SAt#x=nH_pxDvD- zpf3UXvL8sN?{Uq^9K}plM79iA!!FBKaxZ~2g+zQv#1{cfXZrwu1@Ko9z+(j153oNX z3Ao2ia+&j#qxh6T#;FJi{T*1y=W8VNbp-G(0X_}z=?LJT3Gf+!&kR6@%*p6<6n7eA zbVf*Mo=E5$B=k)L@QngYP55mDuuXu^0(^D=GQK7`&3VpIe2xZ9@i~8D99RX|?;0pj>hyacf z;EMoX9Ds~}ki_QfaTNE+KM;MiCmeGDhQ@o!EvN~chZbMD5(K`m5{IV6z2VvOSh87b z@dGSQS2LP1-VQ*6`8UnpnF&GKZ^POR{}=myforRp^D{^BXGTqY7M>U%osxSh2t{7- zzQ_k}|4{_{Jp?ueaDQ+Ym;=C(2C*^gA0e^L`K6=yOM?s=)BO|rvq*@6j7WodivSNa zm{$t0F_^TfC&TY3_8Vl-xb9EJwIZQYAS2RXwg~V*gV_h!5Vc_p=163;k@)C5 z<0w93kU`_RKN-)6ggQY+q`_P(zyl5D?+UOnm?M#KJ166;qxh^r294|fWQ-IEVJsI% z8p{`;`G(>SG?tGEurZb+k;827NTd`19gzm}Dghp7Fqa6h zF_o_XzMn1OC?nYz+8FWIP5G&H0t1_$z~qNE7)&k&rQw z_b1~P0Ul_;j}TyEz(*qE95gsJ=V?drX@iVN6ZzY~LTwlmd4DqgBESO;_^kqL4ERW7 z{D713t)uu`gN#TM`D~GpF_HHtW1;{LG~h{D6@@Scd?Yfyz@16WdEQZco{wk@{*{p? z^4Ece{yETqe@1{Y;8#W(@U;Sr0l$)F??`kk<#b$d6kjl^Bho~k%@bN_OyvEmW268N zG~h3spW7w(F$mZ`a_FNu zPdJKC@Jc)Z{1XvI*rOufqsQZ$dCd0lTjqV1Mz_y1lZsM zk;oX#$@tn){Ix+wB!T|(Z+UGPGC+Sa+5~tYKJa@1Huyj!GU|Y$Ilplff5STmc*4p^ z5`DQy$q)ki({Y;s55x$@3b4TlBGJ+F4bkyWNAW+6>WC!Je*i2{Xb1uQ$=EHxhCtsR zyiI_Oi9Zq<3MZr6QQU2i5lNuGTO?%20R8jH6ySmQzz_j8_&_8wPIrd$0;vucC;AQT zx@elcTYUG?pn_>9Xo&B^Ufb}D7CxdN!MAv4Vp)LO&L{ZZz;r-MqauJ?1Q!=(rn-~9-n67>`ZR1MgZG-QLw~fO0f#P`EFBakmv<%0>Me(-j z_#TGuON-)dR(!we#8L5rc$%9xdrgz8NHk8EM9>Dind{4l4 z7xL&p9wvPM8hNb5_ac1rJ=JpG4IhD~soP$JCPfOVRX}AcI(WEhB>VG3Xt_thBkNn@ zYJ~5{cOL6%I;nN8g9cAWeX5`1m9UZ5 zlV%1^%E%Oqp+7*XfLvdb+rfn{VyV#FDUpXXkY*-SE^~BUo-7SAd>#% zb(iabW@`u46Ql`Bh#U#n@uXb&b-iRLb#l!@t`!o1aer=g_@ zmBp<0=%d~hO}eH+g^_2VH(+WBH1=@N$k-()gu-XrUfg%V)tl7|py#c=A`TtlM3CXQ zuY|oZfyND^E&fEUmW~{8fVc?fcjzpVR(ps7c9~OsH2!L;&(Q%SjxO(Ac}Z*a{SskN zTQ?3eZ}OB|nyW1qN*X<50_mVS*^B5mqyV(Pwhy4(B^`WJ2msF%nD{sd+5_@nu6-(M( zl%xe3J2#q4_>PlJ0EMu#fNBlNL5s2ipi8;6~n$F6^(sX zyk+1LhOXpWWZh1PurxS+p|$JX@%snA=}DvzqmQe3Cel-dQL$Nwe##>Kc?lHA(EldX zpdRvS#^OSY^ighlg=S8#P&+nOsDX{%<>?j}l|ux->8!K?$Q9DWl&#RW#dAM?feLB$ z;VBi;hNcQ>LF`K$aN%%;^!}TFAe}sUZe9@f+16KANN3;7BR41;2UkcRV3d7K9lt`l zA^2GOtEaG3K=s13id8$Jwj|@lf}h!woX#?5P+4sp-Jsy?o5=ZSh1AjK6 zTSks~KC21X!`|LO@jW7b6R<<=v-p48KG*kapAKHO2<>CrM1>A(9|i406{xolRbqtp zp%c-8+Gi{J`M~WHC7SW?Xk8A8Z=+CrP- zeg689TAhp=PRcM1yORxr>aD}?z|EF%cPnT8qqT1{IvbLc>W569_P%Vn8`ji{l9khx zNOb*3$3;b>xNy5vWUX@6FR=s{arv-5m8DY7$J^3D34ny*x5UNzLEU2Oi$67vZ?Y%!nsM=ir;COOH7k&hV4 zw~Jc|_j7Gf)_PhDZ}!V0n|(ICTJaj~-yga`BQDVJ|2_E6 zyKdDWp-k}>b;x~IeJGUsJ^=^g_iHS!lG27DbejfJ&_fLmM?sERsC8i$O@_$U7B#I! z9szkQk>8ua#~{q8XO}Ks2Gvs$)Ta2n8-fkriH5{Bk%FS9?NjzPOpigV)P{;66ilb> zgZrr$=>F8Qh8Eus4&sjTY}}n))~dDh|3bsbuHN5aa#h8bWi>&BJ^R8koY$qWCvFVM zuQ%Zp^6P=toC2%-MJe0xCg%TFh!sO#or4+CqcAwK_7t6TG_S>7IOvo?{OAxGY|h|9 z3p%+zqUnMH$-PuL*2=g31og``NC*g62vk`r*O89fKXCmU%$`hHKg!0G6Hn)N)Uu;6 z3mv#he6#TY_6l;>;VGM&2u2S|f;+2&JQ}R)AC|u7o2mPs~ zEEfrt`3_@hhZ#vF9`_kXA|MMML1+XSSz}R$rtb zm>EzYekyhsZmXIR=BhH4uwlSAl8mDel7B*V8Y0D9Ei#ga7|5ag^-6}e zCYTMZL|U{2XEA#a)nA6IMkQe@<-xH{utfFAF;3T$Am`ynEWyx zzuXeb@X!iOJC5_Gc}EAH-U7>xQ}pfbz>YwB>_ogrL1x`fz#YfY4DGRp@jt z924PGQrf|kDS%;e&c?$K9C4LNo{Ty|DpU9WiMpO0P_zho*qRJ7;mQf!f&D42jSPZyvd*HbQ+pFjBkM|XMNRCCB1ZN1IJIzj} zq8Md#`{_}7;TN5B)qV^!j4q_wsvY*ffuv7i9P9VX$i=pLv19E+r7ks(C^fZPHR17RguO{Y0n_@|I42Pzze)yryC-$QkEDgob0`8!4O_gnn5RbvCiWmo9^gAA@$GTRQd>QDA4`2 z;9*+d#e$IX)~qHSPd#PlQZ4*8?45*0^Hz79eGVcn7~wKVyh{!baj z^2yp#Z;i{xt<)II--t26k2;%J+ZO*t9bc-f1H<0 zNSi98hae(8G!HV!L#1~7TbfxRZH&k7ZUk*~A!y?=1U*!dkADw3@o&w&__tvt01qH+ z<3kABxE5g>H?H*VszI9G*XjSA$_{j*Ioi9;U(qsiM0kE1l4fl-jt}%Nzn&&8Iwf(f*OrRT2vu4jxx)$N?UF)k@1DG-nXS`XgwHOG)>ql^e zW_DQ;h0577-(YmkszJe&WYqQ!y1GU;ZiPZ#)_GF@s{rTH0%fSdYja{v;M!}(;*yIE z=-y2X-OwQdV=$d+ooXPcyveWP^(De5MoQ`X=;bi?4m%wGaax$x#eN#PK&gue;`-w| zcuE)mL1hxn;Qt|I%~zyG3fV+jFpM;$X!}o7+!K}}U6+KEF%e?FzDsuS8ZKp&w<3$a z@o7cX=_90a3Fl=NgkUhFRL;dG7}pW;9gAqe!^WTkmHRnIL12m*7>BUv+>Cj;3{nRB zql;d&U@1$+?R?xrVt0Uz!nZSa21?oUm|06%JqlUM7;Y++vL*=k>b_L{E+)w^@N11x zpxCq|bjs-9ySVT~b~{e-?M%Ld^4e1tTx=X!Nl#`aehZ=p5s@hrRK~@TN;AatN>&Gy z?L;n#A`41gm9Bjdj2w{H8uL|)ZSP4SlxeVQvRcyOkqmYvaV^==yXqS?FBQEIb}8gh zmGs7b3$iIESURkVMm45TC^4BTd*xB$&$XCGPz5zq1;n4hg>qu2pr=aQ#?TIuZW;<~ zznz39xAx$E24h5AFcY`UaI*{-%npN}R*L&(2ndiBi1Oo}>Z8~m#Jl6-s=L^3*uTk% zm%qlxZNXb98haK&p7`MV#)UQQsF6fY`EeySr{JiZMCp`6$T-SVh5b|i3)mjDpr&f8 zPbTBBdI-Ozp;tt~Nwfb8Ty{w12pwrULWf3M0aQ~39UMVi6tkl+u;~x$Gwr<8G^?UI zwkndDw2~I`A-2Rhi1*{<9m(c;IsNCYpO$9w!Z#X^oGvP2nmv=B9 z;NF2S^w_EubuKqd4B>hm%nB77TXLKy!NmmTM{B9J+LASuEI_!lII=2)34}`Reaxl? zdch^FeX0M|9Jap4|`C=i*v3z?^+M_UZj+{{ySO1;=C zFT>pB)9rh^za|XnBeJ zMnugIrck)Lk4_#C!cL+|F{S1#vdTj%MWwv2?Pp(zU|bgQ6k7XJ_1bHqVhpNYq;C|n z(1HR!ikM_rCzw-WmFmcMg`Vs|_9K9NBN2jyO@PK;Ebv${#04#X9Y`F`?*<+AK9(GSfXq#M7yZ39&9+>mmVDW6QHlMH!ZuV}lz3{>dujHf8VUz$lOnDi+{B_#frNu@MdP7!IeO)Y# z?R-c3s&ftQ(?D%=Qvm!*%9-9@o#FaR`=wnmj{R$gXEf(Ky-y|*yvjbG&G7Mo+yJXU ztz>Ly| zAhvS}X%k0Er+V95K-rvcj*^pV=EjY-HEfQhWc@?VH%H4U6lA9$BvijSjw;L_U;j(~ zLS=m&9yfS3w!2RvncslmtOM8ackL+(@zy0#q?p6rd+h4Pk!uIl%uO0?^A_82nsZ^~ zS}T3py~Q2%Hh)Z;$u!;Z&Z;(S&n?S(YcV^3<^2JY>9eV?k=h)4IssiVu$|xdn!QpU zt!`Xll1FH3E3tC4;8L#%NH~{b_v6`GmB_{v>oW{cJjzMORDLb&7A*9xf=JX;!xt1% zZ7=l_vJFv-ll8LggyflBsc~#X1L`?6xv{9m0@>t$LQ_s6gOhg?ch*^*4Le&UbXzR@ z0M??Tb7}VK?N!FK$I>gR0aIZBd1jaQ!0oBH6XwrVdoL+N!%;erm;adB+rw@7<5pT9 z(7%u3;y5S3k8|2W+w7<8hK($AR?cu0i;FEsduV~I^Kg^n=v9*7nf+BXBrNT02QesE zR#Q&nN)%SA`w&tqoKY8X>u(k2=+HPxq){QG$GDrXv!>R{*v z9RQ~uvv5p*!1o8dhb1!>$!J9pKXrs@Hn(YXz`3e>wusKz8n@Ks0h6@&SsBIS9Kr|zTRX(j9w6)K$fN~T2 z9=c9doM#4{i`u*%842A}q1{yB$;4h3wwCWyzR}JySn>{X*O)bPV@8|v9nEXbQ}P>N zEY3~7V!SiPywZ!*YAlxgIZC%S!_0;t3R3lySo|>_%!Yzz30CzOu`2)XbEZ;1k=zR~ z+DSOaI9N&pp=lQ%2+5U;XdsZy} zao}n&tW@GK_4Spj3HC*hkJ=E~!}w?p5&p~>B78KB@RHz%#)w80nf#d`Hf1giXISvU zs>oh@Q53g?RZ%Qv8fB~#{BX3?fhoL$^*|8~JO9Zf04qbQF0oRyU0Hi91%N8d41zh3 zl?19O^0VcF6#B!L0K|+MnG?bleIS{l>hw%P-4gO`cJ6SOgI;?-q z;E6Tii)G^#8_L?IBlyazq}CdhvyEsXa+f>7ZFdofNkD|D>J6c`-6-02h!&6H4F(bM zPWII)AmuFU!ENW+=Dy(fDOhdiP2FC~_R;5MZH#rh?11=;UNNNQf zIdD`d_aLL*W-3!K2_9Y}CPDJpTZY|vQsGCtU;w%FtlMZbH^G_!!&^>>m{Z8%&yR zf^t!@71J;JCpXuG-RMTz!A|K!h}MY=M+K)Y0lN?aD4Fxn5l#_8+tSwUw0n*5EDv`E zr!Eg+VojFF_qDfEdIV3xyv7hoP2@TF{yLjhWtH2g?1!O+R=LkZ+nBWUM;~pUwIuVW zK(4Sr6rJtaknGv8vTf6TH0g}CO?P4F&uE`jN&Ev`WgC@<%h|+F!$k=kIAb@QttABP z>tj*inY9AzZ_9S7D7**PtYCk`%u!~rsub!pn?O!0`J08%lgRD`q1aNeG8ca#Az5sV zik*8c!1kdUnXmMR-t1#LCb5~4$uCaOjc0zfk^Wz_{x4s8~;dw6Rwii(I(YuvBCEod&n0{1q7vH72R`1u^RO2mh-E3pOoZban%~!<8AE+Np$hXs3JnqByRPuAP5aOZtc}Zw%UUrv z96^V#G&S%EqVgQZfNRGh8b%*fGXB9w-v^Z){DU77eW2zMhDn=BIqaZ8hjnHiA)4UR zIFFD_GUh5JeLEFr2SK*e*lUlai2t)89tRzS#p8`X(V!TPX1SL zzu;7gu1)18fIbj7IQ(>|Ix&Ce zYc^#P=}tgpU$A9y3^_?S0dz7iN2^HsJEfASOg@0)Y{rMh2RaKn}rW^;wWKWB1 zrU&Ke&~dZQuHPJML0T0#X|rWZejaVAtzso!H)Y`Tx(Vj2FTcp{egR$42*7%_gVHkA z7x(^=uPM8fdMmPe;^~Y$|Uwm8PaXClWQyXC;p!A z=u}|3(aH+(Nrk~0|J)+HcFnTVa?d5z)llj%6LXulFbXzc=A~u?=D@%V%;=7WD-}fT z1p7y8U>C?=r0%yPSJ3T$1bcaEcTgUscK5>0OtacC7RN#tVw*eSV$4sOS`uvj*v55_ zCfKlbX_u3$qDxAO*|hfkA{yHEP$!QE~p;)N8RR4F~m^$f*J5f~+vJ|0KFz5cY#^3qp6` z_UoZ7bMU3xxpf*s-S~H!=we~<*As83OVysL!I%mg@A_s$Ruk47WKhWKeHP-UXXj!1 zzvm?VchlO_1D_w)aZ|3Ae4zsCRX!+-Y4Zv0zE`}giA@eT1WgMAO5`tgkwuQhvK z0)$pW?icYw`y|xQZXJxJ=`3r$vb2=VqR#LtH4e4IDBAuVPA6|;wa(_=*ya;)G1i^D z1*5e$&reU^sQiNPMiO2!@H)mecZ+uR>R2u3^V4f2_rs{HtOJgZ;GqO>4Z}R%y?Yg>nkMU?Brw)l2vm-`>!>+4tAbdz9~Yc(3I+ zG=_XX3xT428s2LzTn{^_?Pk%)+QuHw9-_t3D|uIhP|aPxqCnq02+`d1`u(Os(%v_{ zGcAWb{M&asK%Sk9u%_tAUUPY}1fyhAc(U{r^d;~F={-C_p2}$p5jRI(SaYFLo>_BY zg`8S*VXfpQEe%l~QhoHb6Pja%GJJ*}h>1Wnm+wV@MD5so&xGFXz9;eC5R-e0GN$IS zs3}S+_H*^Ps3AS>O5o&Xag3V<#&cB7!HsA#-Wh!J2xB>RYUuersqQv;KRh$(PDZ(^X#Pjw4?q(B4LUSa=C?6Q0#Hn5O{Wv z$6bdPeWV6C!v;4F@@zyea0Yo&ULFJ9ou>vKqeT~%@q370sQc1tzeJ6ga0tQ)g*`bv zxsu>iGxp2~7Y=Op(8zy4NyUH&LooFrI3_DY^!7yQzzwM0N_@@uFUmko?(xzb?Y~}S ztEIXJ!6qJ~x9;IqZws8RTMY3FnKwTPkj9np?pooKt8f#1Lp%*Ac)BSPpmyhMh>PJhTAwt} zzsFl}HluBpP8W4u9@(>#8bbaqI#;~*c1=#E>VX>PLLG&&QE_&P`Ud>2+4^^;#q?p|xsb=2I z-p3us@Wek;_s|poDv4vu3Os~AtnrG5a~Xt4yW@ghdU008k#?Kcy_G(2xWl$Pb>^;JL!e(`Tz*e@vt(D3lUC#=W?G7IjZ-ms>N56I zM*;Huig=2#w4e@IvH7V0e|S&v2NyOgHghqcV)JuNJn&D{`+vEG&vjaX*;{1xc+VlI zo##giv0_5d=Ja^HG}mG2hq)MZK^X-hoWN7~FLYqxBPt*iUm+GC6dP@%`ijM;4a3r^ z7dn~>ZJcy}@^h+K?4MRe?HvJy*wU(K_69M(eO9d1ryw>GA>~+IJs~)isy3u^5mO%Q z;D%Jg47UCSgjXn)v)AzSWEvW3SZRX04aL%c5y$%* z#*!DVH|J!hV$Z{I5PmTZ;68IkbD^W9ItqH^sh;vcPI)?a+M_{r#q23a*QOpv{o%m7 zd}0Z<+ft>cnrK2azd<|;3-5HHK-P(iA>@i?K7u#QsOrdiZ&6nll;l_4>YaJJCC>zb z33pSzQv^P@4+k-6?WRLG5b_UkvQDBKK?&_9Dhg@_KGJa1TYfI5{G9wETtJ-@ZA98z z$c-eV4&s+nH-oT}5`nRlA~2@biP7ax{GY!1O;{qd=YVS;8tu4i54I{Ej*&{ z2}-d#fZdBb!ic|xh{wH%;q3Qw0q=2Klq=igiE_v!{;QlU>k8t*sWCGG@pdSGA&X8< zzaS57Hm;;3r`)cXOG^B4I4T7hgocVu52ieW@}LARmWnQ1hImZE3v?FBy!W3ZH7Z=c zdW-pgCi*-nDw2U)3n@+ne~93htOf z-Ktab>_?4o`?@4QMv8|mb8L^(vV!iDR!C=>ic4rehjc49YAx!g8=G0Ye5>wP1vNjUH9VcPhNrLedXSr`P&o`W;ajzqW+*sGaF{a31Zb3Zj;#=# z_ESkt(^|5QHGdT?TRbDZbIf-t0eF&-ZoamTDq<(}dN0 z!rb+4R-r{bVY>;+X%rN5Ko7APA@BP15VH}|?2FNZqWgkkdC>TS2w^2yh1Sviup)~( z$7*}tY`j{YheEmtH9wD&9`PFeyj_k%-U*AKO7{w>$B%E8r}6BEv_~{~_;f;G?Rpz2TY6Oftz#as~((AV4sIQUf(OU=t>25GF)rFfk+{ zN`T%ADUDhc&H=OuOgx#IljEqjS8na2wsO^5eB`#Yet=dWLufw0LIMtCpfhPYZ!j5Kp6u^PPjvaL8lmdY1;fRr{Qc2UFGP?&-Y^pAy;;` z>{4~WfYUeVhw8o~n3}5ivrtgFawa|pf~Z>IsZY<8U7|7;NM`joot#wn=fHS!GsJJ) zpYJh&Y;iSLU7sGPDZ3;_gUyQC+a9=7Q`RNI58NeG>ur0WD^KbGdV@;!CA7cn5}s$L zXh;d=J%}zl*d;WFZd$*BPql700B#gUJw>!ZP_K=Dx&XgwzV4N9RT#Nc!eu9JAGS=! z)3h~-`2j{vhU-xuNDnW6naW={vV(B~ta5XOMY|4wpzE?==FJsRS~TttEEOhDGvJBK z9Z{xXDlWLVvi~s?w2I4P7uVq8YEmUGu5^8%l>h^X6@$J|Fkql0AY$uIraLS0ceHT!WMuz= zEVS*!AkkTO3Nl6Xp5`02k}S~-YixL`H0c7?vMF z1Swo@Vv~V}hvlJkWY#Un7pi9p3gpf%h$I)O_n9H)ZB{RVO^<{_#8qfRihp5JerSW0 zJ&noNJCQ1{tslszc*w%x8${w#kOKFH-hAfoqh!gH<3UcUnxO#Ao1PB(;5#Vr?82mx z&0pxC=5Mg)vxj+(G$K7n9=XY!#z%BR3iD%)A|nKGIF<0nr?9d8rA+-etkPOgfC+*o zK3M>OX#mRr;3&`muXFpQf_^fgG3tD$vTV%u7K zj~iIj;1$iX$8Ky}YrUh}o#24R>%PwbbLCT|gq5y<7`un4nete70%|YN7ylVPrgm+5 z!P#~mOXd)o5Gm{~N`S%=9L!-0C6sWHMvVY{@V4%`vsKrG{qAewfh)l4>GQ)Qo;$^* zQ?PTSdh9)|<*Dv#<+cDE`{H)*)C2b6NeghPMT~;D)3fq`;!c-YpCfX?@!UrpdJN|6 zIlK@xf;7vJhGMz{W-%56$v(V%wjFQSzE5fN0V2TGb!-B}NA5UE_vTp^QhE}Lfl+eA zye!LV6d>kc9SXlGvTENWO-zGom=BZ=U6=Wj=mC8@D7kU@c6l15hi0jDKcx?gcxZ5u zp+~SAP)Wm{S3iq!ywm}XTa%>|zrVT=gAhZgkcTcI^aKxeA@s#xkoYPBO%`I(O-0@& z%Qb{X@g&4++khlZ7S5LIj0t;dWB*2LnDiVi%(lc}IDI~R?7=Sg(#tsDy|jaVcGAx- z{0x0nwXmSm-k@j-bpmm&(wOi==~N zoruBw>Q5NVkOF%_Rqb4Z(YEzYaje=<5mgFPu0Z{w6@Lgz3)!ouu?it++D=SFx=mY# zRl1LwxSf8qqR^%l>T%uCtN$UZ8m$$mP-z#$n`9O(PR$cXvj&L%gm3A}5!Bw^M{U|p zKiar`)Y0wqqs8r`u5PEFu!j;HeMuw(lBw{BSk-~+f7&Ip+#M3!9JAniVDGv+Nx)}z zDz+O!R1U@pK4Psmx!Zv#@Hq1Zw8gOY&l*XCMZ$XRIBWEK z+Rv7;g0s_9NSpSY;^EeWKfFQ!)bygSW*b@qKrrMcnSw^)#IrjLAs`ugA>G(+r_-w#jM-K z6gfBvT!q988?dX?XZ1z;qhN11zaut(+(hqaHF3?fO@O_3<2JM1%b^J<3(T@0zpx) zdS5_=KdX#!nATq@=fM{?C=x6fbD}oA9ffJ44~7jrD3xA(FBwc&C7sI zAMN_?h7{?qNK*(l#V`v(b`ZF~;KbhYP-+SRirEeR(P?G-!I@F6wvGFr^4aC=Uy}?MtEge%>rvg?)$RV1_on`W!i& zg0|V6zw!e8?>oH7BnMOEK#R+hxM2d?ZOw9DTR%gxxIDcZr{dkrbx>1r%DHQYRZ8I+ zrzRXRX}Gj|)uL;{Z{f_VO)0uY-LJ!f4Q<_l?R1AxnvWxu7+Vd`J|I;$#iFO_aJId1 zIy(biaJM_js2|!OqU5<2(gegn4|q9vuBJxpXP8w!rI{2jntICMrG3~uLY_!ViloUH z@d*OyB>u!f16;b&(^g(FI z5unweK#^I3qh%y>JDTXS%MiL5Jo?c0*{4s^ayML?7bhqt{#}C$YO&_=*%bR8OXUB$lke{#Ln&kZ;Va(}K+vxC3gE;{7?C6YM6YYCEWc->t_ZyyAY{EMT!nRBFZ zAzm|x_BS(8sPbkuezga@eNLE}q$D?i^V6%X@b;|{OT2wQ67Tl*Jt%s-eVfHRZ{Koh zytZJ#M_tph4Ub=KbQ&^)?LnsMnf(z)$@i@Y9=j zFQr5m2KWn=h8bOihcsUG5%j7ViqC*2OkycK0<5TR?_SCbiKZMp8hLH7sDgPa6m5;X zno#yaDMk-MXRRaiE7YXrP?TU8;2Gjhm#V- zDLz^l02ZMp8N33O*Q)YXs(zYth~dP`due9SlRrX=Q0{+Fc&Y}+OQB{Ja5(CNkzJ6m z6>FBe+J%}s5hpzPB)-f2Kisld?*EZE6%7-7KS7jtFCPV!!?jTJDz=4SD}EFowO@UK zx21oU;QJ}qwv8OZjKQr4J5S4e1p>@Jf0tEcEZC`u%UF;g`Lj za~bI}>n!>)q5-}5rZ<4E*sV|N>#k1a(#fj#U4X4>s58|1Xg$s2bql_~P^`WI-vqU+tr9_jkGfZYH7 zSl=+zrV6xaM1{U#6=IXHV-u%6wNBq2^sx<*hy=$1Z_-e+8?tF{7@Uo9C^NiF1>YQS z%=8w9d~=Z4?>FPO0HPZlIhjq6q2)L@4+2`m@zD?GP%b;@2=-vzLe$0);zQHKQ9ULQ zrE>(g1t^R*4C9E#sRLhYp6b$@$CohVkH5Aw>Tp6IF$9l+?$*bgBeep2CzQBE?%yDd zk$Yn+W98m>;mItD?@f{B09C@{9^Qm~FVH%~IRm25F}EE*4->e3CSl)__%qJKDo3!s zHlc_->`ND$HsMixSZ5XcFxMSa9(dPt}_iXcg%)x3xlB%1ce zNW>08P>^qSV()i_QA`M!c)(8-#$ZS8M3l<+B7GwY&g0m6}a zabUl}?>T(^yg2);$Jq$tWny{m zytWP2TE1aw*4k~fan`lXo{25a6otqrs7-GqnHx4>2>3=j|0r)Ut~FBOqA}Sh3o$u+}ixiK|5b|HNtsBAU8jj^`ILN^yPk0B*5PWrntA?itLc%GM!rQ-D zT;=UwF5V;WU4qg!H}TzuRtIiF_3aAO8{Yt=Xr1I};(O$SND}-W5{6d|(a-vFE@Z1S zX{l6X+#4j#p%InekIKX4M%nCCEs4t!$Lrrj5c(^7bY&^J{Cer%BN`WJ$)w zBc`kk%CKrX(DP!w3wm;x2HwO6X!#j^7^jWM^gJ>NZwcYD!6N+rh+R|~LvjgLe^Ly1R{VSb*OB%@&YW+gki zewb|35?HQ&1D7DpP}!@4t{Sk%p+WmH3~B{hl8Y3^&LhJ9Sp143#aRz|5GW=*2%s_xrwMp@KC_WR#b`>^*H z$QJsR;;-d7VsI@rJKQFDwaMUJJ;f`pb{h2d;Ws4?jl0pH3TTq)2pZ*TTYn59;CdC6 z|E@)=yfSCVcY4cuvg8FKCM2#P)vOYXUR^BRJbG~7DA_P%?_tQ$iuq~}VL>CZz0dzkT9($p&%H1&au!m`IlaGHLpJpCfIr? zhC(e6HYUu~A!6WHz6}dm5pyRNX8HrvSk<{?=@=X-Fldtq8c8Z8d%kE~T+G@Z0wDOs zXk%S;O}%un!o0YIZNsvGdCF2{ej<2w7>&bv35A-onEe_Vytm9R^)EMy*ORY{AJQV@ zj5_hwVyM@?2t`(YB9RuORi-Os(x*AZo4^`g#kXnH8UtG0WU->ffLkzhO7BIxLvyJ@ z_5x2uK{6<oi% zcyGC0B7su(wb!qQ1WPWWwCqp}NyNawXVh&n7k84F8x=4CzfmH_>CS ziw?Q%wZ>djfa+>avs0pGOpx7Ytk{v5W z=W17$Y9I3tt@yw%l4HRiwoh@2a?gH;EE5tr(?Q|>-sPmFPb{Iqh`{sHu zfx5JKXT9?@x`9rh4{bpZd82RVl}D|(4IOHcE>mAHgJKbHqZLiKGdosX4D*Zgp>CRw z#HlQAw%$ot3rF|#&V?Y27wM@M&!&Zwm~ulg_*7)i4Hg4*kv#^sUTMTAgCm%LNc3do zy%;l-oMH$WBhoRK?7H>%Nn~ILhLo%KK=_4gch}>Jw79T#(m`%3_#l?ScCy8-%uT~g zLoPQ4ealReOpqD_Ynx=I3Jd*JS6Lj^5!ur^XrGT-Z{2W*>bVL9t`^$5J!UQfqg1 zyFMhwv$m-`%L!&4TozUD#xrVnJig9BC*9Ov6qzb){9S83bDK~7{pYM4Ts5$E^k)xo=Zuw zj(zk~@{OiFxjnq%Jy$6e{d{Yx3d1@B?lB-_I5rp_ z+(vRlMtmty2pJ54b`WhbOILt9t_Di7AgKz82LIbn1GHgi?z8Fu4+S=u@d;85fQ%S5 z-wNNgB(D7hEr2gAkgi`1do1-i!A>3lhHg6ofWbm_F?F_{^R*Tar%1=y|0{4g0nom zkKUKg_eb6zqxW0pKNWfZDZPJh{?8)sb@V=Y{+m(Z{K#m~66U`_?=h$!4S_MhH5Jy- zu~KEr8ZCx8SU@i;SKrIwD}2SVhfGn@EeEN)=d)h|s!9B7P)aExN-wYN6%l5KEn!{)h^xCJ3V*scL-`@bL&D_bzgP5 zyPPl^FU9P;3ngm~-xV+`8{v8Od!s|VV_vZ*}7Q?62@0aLM*Qi4^k<3rys ztPBgE0VRdz{E>=S849(5tibxas9shBkjdPdPE&@jE%+V^U4Uu> z2C2eu_qzYUuoSQps|~P{jN82;_5L*L-31}IFk^3GrBXu%?WTLI*nlVM+8dW$Zuu)_UsCyaYmN6G1Q3D;D#uNiV3^OK=iMt8*c3?*y#<^g@33i=nG9l$l znqGh{G4aw7{2@X~4wDYB?-?Q zP~iz{SQ&bLXbj|Ko0^5)3la;9h20NFJCBvXSV9t+bHm-enrC$uzG z`WZOV!IUEJ#IWM@_EZe4%L4+_Z9#7b5E$~|T58AubT14*4_bSMC1@ZMO0*7t4t4`y z8fJjhG7QWtip$r(O8SNlpHQu|6FwXa03_T?B-`${IYFJN7w#kOwA zt`2oU$YIl*;mTg(b-+1aQ}#0b67VxZ*^7*8itqT%x5BSOA$th7*Z>_;h$7V`Qu#tn z7>-fU0pkuALu1!rseqmOPC~G?)gvuG>iif(T+L?wgB{^xONout%mDG zX&j3rf0KR_39l1<_0Pa>>0Y&xFu!JN>>95#_hEn;K%GmqK$ za|tu?XFltHj#{{kUE$B=OykcL>|_31%}(>@8g`sN*RjL=c|U95&xhC__)}!B^XF#v z8h=)@m++(}yyXR`vTYRm77=i)jt6TgxRnQ=prFWuL>96i@!&HQT*-saQm~K*pQm6R z557pj`8@bC1#jZP9TfZy4-!j(CG%iC1xNAVK?+9mU^4~#{|B|~JqmUq$eY|sZ|C`k zJrsPO2Z_36@A2Rn3I=$vgMx4IU?&A%<3UEj7kTg!1-J3w2@2NnU>60q^59hpiagj$ z!5{G;Eq%6<2T4|j74jgRzE~a)l1U{tA3@$^vdYA6arw-V+Nk(X);`voN&w~9#UPmM<5C3D(_PjN$bFa@GzLxuih<*ATXLP2(TOXCGy_U8f$s3g8$ z%a_uIHYse9g%D$hy)AMa*~uop28daE$so_apGY<69Z6N|690p&jIJR%irZ_ZrK8S2 zf%kP*e1g?t61Mn~CY#$igbl=Xy|3WIOH@eceR}WY?+*>WH}iKf^8QjKLfDKP>vqux zp68{_h}%v-a7(IkdnM2_S)3J5X~kPnYG^J6q1z508laVCV!xX~jSpgOEhQIljZU}1H=>$MBOD_MXx?dZxePK%N27R%zc-mf$&8HoX^ zi2kQekQG^BZ#@yNj!r|r{}}uk77h6`B*qqqGUOh^4p3I!m~!42?JRQec0_5doDPq? zoq*DDKel)HM7pduCL!FI@1QZ-^(wrqL;f?mTnYQS6r=AFO?OHfv7VhRh=yrr-y=Yv zI31uM%qUzOmMe?y7+4-8lknwA6bQn>o&+lp$2;>kBN#u}=-=%h96|22$wK4zk$N({ zRoHEX&2F-d4!4^_<8^|@>rcoP8LxNs@uK6+=E-tj)E3y!Gf9ct4}xD?*1#W1y#B(r zAzxTbFcU#AI>K0$^uKWUk)VzTMLb6d*kae%9@tiukAfg;l18z6cvgPcZBpOY?f?Zw z?ua>yZ0!9y&4q+xbQ8Il;n;k(1bIreqiQ2=2vjq_9>9eG82$c58D?+FS9DiU1b~Ao zQsTOGbl~5Qtx7%|;%;KFpslzBkdoQueTYplu#}bQ7OSs*Gmt!8hOD2! zTEgjmGnkGQAgHyG$c4q9&F#u@C0DdTg)O)xv(553qu7|w=Ay5<_1c(jG|ni35DaU_ z(_!ZQ0kq&C=*lxnQHM63Eg7m|8G>k>-sA{VfX;oY`;1!D!DgdN}CX0K55 z1YVd6{24XperHQoULpigP^<7vAYV0w=ESI%Lt{k%58b&5HLH=@by>7$@}>zj`FMwu z7sA;u@FC%uNse?T4T{?#{4^Cu8^xD{*E%2dhpr-j2-IF@Q{SXsI_tfCam0c5CF4zv zHZ{qcVXS9tUH+WfqN}x@FJwqJR78m4iXJ*)V3h{<$6LGvkS=*6n;`s4)0>Z}Y)Cyqd52s8gx|L#G=Xr4f%qG6*@)2R}iJDS+#B zJhR@UVG^F`#tB8fwb# zXoR;@{4PwUfK8)11ntAP{Bth3LVn2Jb`v!^;P>Srk;~)QFuiWf z!Uf6;G-=*1<1J#yl0E4XJp|Wm-eVByvAuBB#QJC7=}AGtXqBIZn@NL9N2e{Hgc#p9igtl@D6qA zTf4IZ2yK16v%9!>T~R!4X#HIp7Np;whhozM+#q1S8ptnRM~+&;E3@78p-}Vl@G9c7 zif%OK`)lS>=5Lx>(QbN^61qOzdRVjT8>9}}h*_cX<*iS#zHa$M+b|s3t!NA7#5U^) zy-C9onv)q>_|Pil&?3J=&%SG<;Lvm@Aska-SNV)?{)GbeDiP8wUx^Cx2{*j)(9Dg5FWg4EQIbiODC zMK6{W5ItGpSXWEieEZLUtH{0QfHaYf(etw2w<67mqb?p+ zRjf@5lIR*w8-*9Me?cNXAqp$ipf0e=KQJ2wyZ_-14@=&orPnKPOl9sI=B zBdC2CF`ld1IfVmT$>_Ziy@y`@9xsk}4cj|FAr)67!quo0!;SB0(XPg-7`5>w`ceTe ztwq%A(wFLgM`svma)r5AnM>bT_J|LbiV4eCHh`l_@pI@L@RW@6PixgP#*Zzo?!ZhLi}o*okdI}!CMxQL@HL-WIXj@#=g z^Ld3y)vN8Ht%NVoQC`q@0RCX_>v{DHtq6@yMfN3DjS1)BjqL6GmgHo`3w|^^ULPd# zWCV4hJ%?y}@^L3O8$noEY5;!Nd~qqvtHQM;xqPw1*^64`a9xo`x%xMfjUq5tqZG1< z@Du&TBwIt(0PoP&jbqqG6tAD9CLjb?vS8#Vk^QLsWi&KhS<4dz-_wBFawzD%4Lwss zIb1Z|jLUlg#oOTZoE`ZIUr;QaH~I!7VJTFWL3gmFJLdvBwxt2Nro$sWoQqMd*ON#3 zmwz7$Q92*p`$K#yNQbRjGB<=~<9Y@A0F?u2OTY@lbq@YDP7q^_9st^{!s z){k*y>Sx%Q;9vQf0J?BPybTJGx@scSRcGMFiz}oKs;gR|uG*zGKp_?O?bSwln%cC* zTz%Dn`#L*antg-%DvV>}i(^oI)eiMl0qU#Pjj>D9@nPb!v_#kuLIgtgo(~{n`GG+_ zq#jpKQ9Uc6+&Zj@1%BMbr9&27Fa;*I*aD@&J4PD}gRwD@*g1%eC>8^p01Cv4U~gbJ zunK$b-|DESoPm{QKRcd&pRZ>r|d=N}gF8 zMJA%yltg@hwSH^~R%|xm(sjd8BvfK$xCy4?CE*y@N}(Gw*weoQt`YK!O+Cd-0f^#r z*h(Q~v@#O0)(z2sp{7TXX~V%Njsb8zf;oe4)`3zSglw^96#K~$=BE+;jcHvj`p#A5~ zBJ|U1I;;lR&9q{w66ITGsaK@vMkv5+FmfCCW9yb0fk$c+hP0G&Yond@nQmOn)tlUQ zQx}F6)~LY)&@Aa6n#!!}o*?dAF$>jj!~%>c`jVUW{+se1iSB7{ z%r!!jeNCn97Zqz(^@I$$QDFM?#?gBme>bTI47uiR%hSM@##Le>?7vDvg~`9b2p{uP z@8Wfg7!#bjKf$<0q}hJ^pAl&``O?hchj(1=sZt`DlByVYFT53Y7Wh3U3J4Enu$ce= z@?8Ncj*b2eD6J&+Hp+p=@(1**;~=&}$!vqA8jNJs2^z}u0EB(IggAYwzPdts{QL1{ES^l`A`WzWf z!bCQF$9c>akkT4+qcZSGjj29|Bd9@cG$Gca6kQ@y6PL)MkQRe9v++S~gfJvLJto4p zyF(LTL`7A?I5oD`I;;@I)4R#)Iv{XoZA#JACO2-IP&PF9w=98;@6@7R5Xk#I@IiAG z=8I4*iw5#4hnq^69+G>rHb$A?g1A?H;F_7X->bsTW^*8D&JB4I%SlubGlV*-e#2iX z3%utlqwI;xy#~As909v`-;|Atq9EmK5V{m{*&m#SR4EwZk-! z1M59#DeiO=D>91NPp~lqZGxu>d<09&Fq#G|k!1MYoX99YghrC>a+X7T*6C>kG^xka z-IoeWC$?=Cw!*jD`dFZbbj+(3&v8U!6zo?Y@A*I-!0fn=SEjwqFw{sHSUZ8K`MZG_tBieA_8x ziP(QIHoz?E6)lPoGn|+d@HC~7G+npT#@sc8%`p*M&4i3Xk4*3Ri0X%Bt}1&aFod1N zC>q#=K2TQ`8HMcShrbEga?&tN!j8nR5Hum&y0UmAZf%9`dIYz=wS!KvtPBqjulM5u z!9mvt?3a4HTaPaU1?_4V<8@T4HgIGM+)Zd!^|YIg3`4Z0rhH}vXJ8n91qGPI@oRCR zdXz22-hhvT=iK{m8^o+%-ynz{FR2)}s$^sbgm4GCahdT2IHh3gK2HqOrr z0=m-ftcTAs+8gTq*%{=s!EA#Za(Xiw15}?_P{LN?j2dZav_UIT-R*hMoqj$b_g<@< z<#H!h%>aoMR~NGwQsaHKiwDA61;i*4)g!b~Y~>q;Lj(7lZz8yN!Y0y)@AUPh9_nn; zU}v{380;+J^WL@MD!JDU<+I*$X*@SGi=72mOq|B~4j(Cy%X04z#L05+0#Q$*OI$=! z9Y88AW0;BB$cG03H`;aI^noAYBij}210!TOXh*w;ZwSepyjlmZ$s}iEg!#u}_B}rM zWP>6OQo+T=?C2|CDCuV?*ua4ax@)=}mZ2L=BGQSpw>9I}F2&;A+;a{zc45ysZk5Ig z!amVN_Gzp==S;^3ZOhPU6{1~ZnE;{0FxUR~s4mDa9dqqFWTECWO!d?e{UncyhU_Zf&i%>rjfN_1#r5+qNG*&m^UQ<~2n1TH70MlM#hP@_^_ zVo^Va09^GvCKVL3=O`te!GT|&(!&E{8vKVnh8LV;i^KdB?rRX9c}mIuQcUTpu=Az5 z9CO-Z*^fyvbhu7|vym-HWKu&Ki;HrYj7)gd0G2cf+H$ssnh;uQ<|aE5v_!7E(E-tH zM=U%(m79rY6uENeN7fQtIdP9d4}u1U*pO~71G2Qk9SVJmxr}K@_FwrE60c)VzC1Vq zvk{C)qLo=)ABmq+7mSj%rv8ync0@@Z%Uj5oQ!yL+DVhSIgIudb!mI|VB?kkaKrL0H z#aP(PjzNU>dTkO42<4i&FD;rewSlXmXwQA^V2<p$-L4HMirsv+MP82ea0=* zz|*cwaUO%Pp0Mq}-B=d|#TBvqpiCybef3C9cbX0t&$2!xbEOfoZ(hpJ58dTN)$0fN zAgw627}9=C20G&pZwxW-T=+~j!BG=glYwR4t_tJG+63P`B+}mDqe81Tve5smW7I+N z6Y<=JwaWuS;-!6W$y3R!1ma zGe0iDh8%9@2zie@!Q(iEt+$A-x7Jy&!d)Q{$a<(YmXQ$IU(l?t%fsG;m7b{PU2`_G zAA>Ogd02;?*~p<^Ag1% z)eMsDC8^$!I8Uxjn;8~@|TfmH}- zyQ$f06l`VGATHSJtY4$@_v%N?)CNp`fnB}Zo>gF#EL_yLp|Ic&4lwjITR1=%Pr1{o zEHo?k*^3JDmzS26-U|udP%G>kvJWZ&cslOHSywkIf4K5qS3F(MZh-M`;sjm>gEqpf zjlngne%pGpoSgw=6mf|+DgChMxLvf~E{!RyxT;wTE56W7g%#bQv76~KFh;gV1HQDe z?BI(8f^;j*-a}9!MJdcv7cMFS;Be@@#i@bPXHrbBn+nq^rK-a1s)Tcvx{AWm}jZZuTI{zSlb>M--rNzEn3ll z7OXouIB>KfS%J^hX74$e>c(Zcl=CV{vNGfVP|+3gpRE1ymHgiwkd zm-GViVG|MLj<2u_K*NMQ4jvAzLPpy5l<1X17OBFd0k(BQ1Et!H#SGxYuc0k~RBa0U zDjIT7E%-v@su%7YuyRX#+Dj+a6Sl(!T9LSp(O6c2?H0B_dIp^lsWWha43~IPhl?}x z1;30+_(1s0yRtIHm8yXcXfe9+7l!nu&SOv-yA~Ns2tRiRWbsBa_6v^;I2Y)&!(mYs`w8axK`R%SW&cP! zv%jUC4?&E2u$`kZl=8v|w zpA#53*x4c5A6=-n2Q>3Ex)3Vnyrt9+ATnrI7ns#pVR!#NG}}9k7$VT{0~>aX>r2sE z-C)SZ4mx9hXe%CR&SS0v(rDKqiCi$i#I;??H!BY9w(15Wl404P9JnmKI5yB>v$fia zV3rTg8*Ff?WmQiFv?-=zw&SLj>L$XeiWQlCC&f+_V>`NPWx0}PKAAsF@U^NI9GS)dP1qqguHtK9oM?9iD?j%j3>&GolYa>Aw>1A#}MjEqw(joG+>(@2V$g)WxJ6E zM+OV~4NuI`c=(WzjCDihRtzl1;#P_}vCJm2AW9%I<_MlT)kDN~l?5zPFi5XdT3uXQ zef<=+A1T0Peq}Hr%cHzVy%edrd|1iX2(h{)8E^?_gj~R5dggV5nYDG*Ujo*)ZdwYr zJFep}evCqZ@&(^lW};2(;@rAL8EH}Vt-ZDG0cbAgRhUb~@p)Jx2YOn`<*(~<54<~+4Qe6;R%up{Hd z_52WVf5_wTRt*?xZK?o2;Z5$VblKRrD8UjZ=Bq;8l7wlL*v%8)3T~^AqvxQcIQml3 zX>o9tMoFhr(g{3iVk9Y&fx$@0rpFN>#YmLH53yo1RhZiwVp$cf;SlQ-3bBxWS%}Box4I=Tr$FS*zw6SW8-uE2pB+SIt z8PRx1-MG6j3`TTP@U@~B#Or+S{3%{=2o&CG(FD2IymbsJU!QQN@Rlvd z`*sRBRS;R-7~!o$!ajvwA;BEa9)2crs?{D{01GH)Q@fU<3f+rlqf65k)-Ib3-fmQ7 zY~2`Ds9lyYZ6Vo}h`dc-nBK09?rHx;h4F5zb1VBLtRDdOKq;h`b+s{C`%qqjL|9m) zh>qUq01)vUeHioEI5ePC_FN*)Dly5S&ahw|qM*%%(~RI#G5r{ypsYXD>u|BxAZ!bm z>WMACWL$>U2$-;y%YPpz$oc{H>2cZ(1UWH!Vjl+`urIA_{&7CQdVH*22-+V3pa}#( zAe7F(_wP#2P6Qh?HeKLgJ}AAZP3xfg%Z=+kG^-(>i z)WE$fLBn&ASyO(6X&w5Mv+fzL$WeoJ^Aa6U8zRS4=!(E%ObiaDwfLs*)3k*WKM`!# zME2~{gS(6iL0gly2;4ha%q(WY=VWlDm;HPy=t8#T44tr=QizrYU+fVJN`ULC++;A7 zZ29bsH5j<^WE?!p?FQlq@40f|Ht?Y^HIs*G4m^bvIMKxu;}F7O zR0K}$c4TZQX46lHXRDZHV-R48qBC+x!j5auPN3Lgwt-R+$mLU=Pe5KJ402=G8z_E= zGT4qh!$55`+cx-_Wg@73@U60Q(PomJJ5tD!KMOZWU#~`Sb|L!}@j@}sy?on(0PNT_ zj>bAQv%IzwXF2$27|&d&0avc@QaE|A+HZm?2Rfib)m>DVK6CP=%;D581S;%`=RIL} zUR5vsad8k!46TgvZ^}PU!MgXgo(iM>6D6p9_4@3NbHg?*IVR}aRWIg0D3p% zK>&>n& zX%5{_y2+6u84A;ULGt&5A}ArCZ(Zu!V|Be%MpmF_H^ORs|NHI z4+D_@0}WOuWuk#5-b@gM!DrDl6OXH2+eJI+KhVr01jZMJf$>Sz)1g-SyVRqpM|2?m z3^BHJibi-EG zCHLh>Ff{R=T69$@H7lba-`bZVSrDVZzYZC^yO(_kdn1F)rT-QPbrBl>|2Kr1gFX{N zrM~~a3ZYVi|38gT^U%TnjtG_7<(ia@-~ZMKH6IN$@n#MoREqoWico1-zX72xLG(X} zQ2mpKA=Jtd6sohO7?&*WS_rA-f~WknzY2ul6N>b#;(0^y>`*)}E1nk>&-03Bm*ROQ z%aevvrln@^NU}qw!(=c!8XIbnLn+!>7X@>Gc9;XSX2(IvE?zR-rfG$*XVgXACimHd z$CE*Y!O7MBB&)-pchuWw-4qRS;SMMdd(za{h-BbABg|%6O0^bntBBT=J1T5ijovunr>n5XeyuE_<_CzJ*PzSZt3^A5 zq?M0~wF%i-TfsnkWBi7=ko%1r8fs$}Yq;avh0f1ws5<{Q<$ymDLYtmMo9cojz>mCC zkRrV-O@}LOkDgQP){;>2pLxl)NXe0}Rh`-&ZfHQ3>{#J(@Eb!F=HP2MAubQPmEdBc4{^wU(ToRU|FXa=)<= z+{zwHrD?$3a~H-%alb)57JhmbDYVjxxY9dh=)L-mLY_<8hst5Hay)vTa$ifFu&>L% zWOi$HUp}N0w#Mp1`mttty8!P1P|cQ|B|KGz?&zN`2MZ7mdEP)hcX@9$h*$mYgJ5L6 zK{pR<8?KyG_w&wU;3Z@gJzE92N|Sq6R?&-+$>dJTDtcKmrMr{oQ(eMSQ_;HlyEKg6 z6SEL}dpTB~99*rqcS2gVh5@3h;(OZP-ct>oBKJ;wAz@d@hnFkvgIPs8b^G%Wdh*ne zYu%lJs+}e|unaDc6;BP7@H|Sm59SS%jk+VxEYtb~^@_i04-Ru7&pZCIJ!;Vra{q?` zqvIQ{Q-s|Mk!!g z)qZ+ADm+fdqJ8^srMDxSa9UE_&1h~g9?{P3a@R>|%7PyEdlPYY+0KOa?r>P5i7Fv0l>#{bOrO{bVDM69mQ>11^Iv702m&LRGDmdiZL7V{9{j6HF z1027i=W%m(H!Rm5RNOE77easkMHT;xUKVzb#-UhV3!wPz0k!0se@+z69A;M+9ZcRp zc{rwHiEO$in#y55)%|jm{J@J*Ab7+SE>3}+CfkAP0KeM8LC$>!Ikq05ACDf3;3K!G zfu43@cNaME?h{6lmNlu$!(C=kd)otN0v%J@KC?lM;zZ#5ls0BNuoMn5F zl*^tIk=b>h*fdHlIzb}LMnm_L%5_}dlDV|0K$Os+7ArxP>ag5iarDb zQE`8`KuahOxj)q4dh!E8D<}8R+`}W@`c&NUw3KIIwYi%i7m9hjT_?QZ_}LrU3KoRs zg1o~?o9AhQNgSdTcOzP_xDS;po+H|1Oe;k5pQ)GEHXHJ$VU)cV$|$crXi(hm$yGZI zf^R++rRoMV!*fuT8r7mh0p`$dY;r#X1_Z2DI=gvu-l5FS7DNM(44Qxd%^Hm0;Tp=> ztyb0A+)tD%LbHA!q6bAYJFlaS3M{ynMq3?U;4f#4)$uU?-ooFf_=`%k zI_||^F8&(uw+DYe#9#OVN*vnT;BOaP;v&b}v@B8sxQ9#zl=&Bgic?#`c74%MqLe+~ zpra%T3m-pqc=<$7wlkX@#lU0o->RCO^ zW4{Q#EQH1&iyv=Jsa+UV-n7tU%xHusaUwBnxaKK$wF*AczXeMOaY(-hFJ5r!qe<#n zoY)h3AMCd7!rBEO&t2Arf8X`3BhXavJ_w!*yAP?Se$?XdpoNVA zmK4yee)Gcn>OKA%tNpL4H*qUhzDuqch*> zM}$3u5M{QS(mV_0f*KhhA-kVlrXCLTo8X;7sQDpcxR2Ur)qvu8m(NvsmUaCo=xSFT zeB~9OY+%4f#r>|cMe*zb*NpgMo?hapscp`pi~BhD>^#k}QnW)Yx|n)0^@xAYC}H;i z{{%!P$iGG{z;c58O9b}m7;r#%{AqgAG2p-^2Z@?6Me2mWNsv63hLPan9yi23bR^hG zNDy3Kjs!0TcOn&vmBuXY$6f6vP|wkxXQx_JZ)#DBb^+}b z`Ip3Z$n{pmgXQ`Rwn*G%U?l+Usl{-z*DSAn+2A+FxefsB1qkiEOwcG-y=+i&IogYs z-A@DUJp;72ORm}lw5Ph?g^obTy))#gm#gXxTm98dI_3*)arKZIg~2P$!sP;F4%^mt zsja5^KyZo;h~g@A$AAG%^+167-M+iG+!xw@)Qa4)CKJ4-ovq9*C6)m0`~KCk=_WfUta|Kea^Ap z=jdlQ$9~-gFw`-=S)MOB_WN=%$9`WD_Uk6>_jwrm^$L&u8vP4nz#ZT{a}3z=H4Mne z$g<$8A|&QvfuQ3Z;<$#(I3zswD*%I9_5p}1=P}F^G$Wva0`H1y(Fe{`sm-aa)gKd( z`RBwbW!R;#LpBTY5)N3cf=osb_UM4sB|JWt-gLm~+H@yvt(`FR6wIR3s{3A5M;QeE@(wMF9D(4v_B}lvUw<_<w_?tj+a3^l0nFkjfdlGHK-2g-$g&+X2Q3u4X2q5kvK&%=D zh@aW|h67?%1Q7LY`2RK_=6(wxb`5UBFMlf#@@@EYoAmPE0)TW;--byEi>@PvO+WFX z0Rr%kX;h1zSKV(wOA%I^#EfT67|pHUC43YWCLP@`mN(soy=Q1Qx-F{lHj5#+fiBKM zW4D+p#;#H&7WmXr{pkRffR4;CsU(Y_0xZiQ*3;RxwgVKB>9h^x5>^W#h(O5mE`%M? z5UCv#aZ}HS)fX^NhAlIYB%JF3Ms$!yxjG0ZFk1k^7X`9aKBWGP}WcNG)P&SKw2UKRT%f{BvT_EWdrUT68e**%T-< zxI1h;{_H4MFXvt-fsYPJr$%t8dx=YZ>^A779utiVRClvKF+(YO7v@jRuGS641t!mX zg!o!)hx~JH1=3fgcNIbmNv3XZ0HR%}$JSMATZj{cek$v1bZa;a+=*pWw=g7YQQ32= z60m@@MP64H{PCDF?sS#aZ}=R?3VNCsmWK=jrW@M58r)_bu3c_wgmD9m@DqdjjNJ)D z?RZ@olI2dUtZvGAYQvwf-7AiF2;0!M4~0D=B;N-PdC$jt52V!QM>T@7$ia+m?;(uP z-QW<7Io%Cb*v4-*cQ=^nY3*)+D^`q27*!Q;dh`*Vn{tyyw3oP zB&GrhV?m4KTt`G31jNR~leKBh9*+zL%@S`g11=5|J!yic0HQ%auSVM%wJ6(xl~k@7 zrVipsI2L!F-3J_^We=KefUNi*sQm5&Rx!%f(0#y6sZdt;0oZQhg?Aq?hI8(x7W5q8 zZH%%tsfYIQCLR%|xQ?P>htV+Xv+;)2dc$(`hNa*vhMG*PQrlME3ql$#6UXsqlo;n~ zlZ1F0#0I%Jry)LvLSZTqwsK3JJ5_b9TrIoiJjREp!f}s2bcZl>G?a%hlu*`{4@JS_ zGd+zoq|w!fsExvI=nLPc0SG=2O?i>*mv-k%^$GwbP&)HKDjUMc2U3sHMs25q;&0GJs71%%WRATU81mEu zz35138z<&dT(7LncCd2Up z?iDcrxGOYSp;UKC_zg+>bV1PARN+|pDh&z7_=uHj;84i?Dj!IMqV$15$oMJ^B8KP) z&4Jqd2LgxG!{QAX(-eG2#xn;`yX!F8eK<*pL;;c>m51-2|ErK1WyPOY!FBxNCQPswU3(RI}(8`HIUjsz?6c|n2sDg>~MZG zIy@b5c%o=5y_2a&M(rlxQzuCmy8wA!Pv3a4w$USoaW# z3j6>lcThUzc_fk{FH()?kjMZva+t`#1SW-(-7}bseFfgwe=VI-$j+gmBVVx zTysRDOum!^87Hoa0zrzUIiQA;l;vh+xs{B9{L~GQ!Fj06L8l}}H~ww@>{z~IPNW^v zA+LpF_$%rurK&fwbxOUa7TPh7s(m;=@g05aPw=XmJ%WqVb5O z31S>}NFCyLR5&9+k&t@EEpgm%&4AC4?%c{r8H(?xD4 z)P7To`Z;eBwed7I_zzJAKi@%2)v7qqV`1NHzx^g0%v^_1;1MdYS8rG^q>#llf1wd{ z{c*JEOWN+cbJY(>G`Sl-b&9S+8Ni|BTSFc@h9m@~8mI!(DCS#*$4Oxmnk~z%aMhJ> zR;|_UYh55_)GyV`po{|N9f8jrwv&N#D8Q^(UH#%2WwTY?Z0%_>c!9n%;5tN2LMEbA zVekJqbs?nF69b@{4q?9X%*djr7mq{Y8WtlVC>;ku>ELzofM_yW4l@T<^)k!CdsB2X z&gigZQFZ|MpFTn~8ba8L+e+p*V0(|%*x@^32bKhxzk_7v|6=c5;G?Rp_TiHYFldyc zMvE5p009Do5H4!uCLx&+ARz+@Hwl+XW|9m{X2!WdxQCksLMkdMDs8EvwJop37HnFn zf~JZVEmf+hsHm~dk<_A6i%RAHJbRxr=Om)_?c48rf4}el4Xo_7_g-u5``UZ2z0WyE zz!0B;M|b7h+YMoDpn9e=D2QWi>*+UoWPIE$D>dU;d@@SL;qrIttD`bzRwY9A$U)}#IE?vL1JVSlUkN3_1$AxL!YKo3}Q(yn$lB-_rkT;@W%Dp7nKuPMyw1!D#Kq>PNb9IA5V&nQS+-68QlrSLGzR{oPgjPGkAlj zr}0XN#oHi_XW8%=(wwx$x-*ScXU-m<{VYDsFmu-TQZvpT7p*j93RV*yd^!z3T)#&L zy=5Ri&4!D-czzgPaUR7JDzZACaUSFd7CrkA zwA@DL;rQV))KEhMf?+XjavpLa_H54CX-Dw+Jy;~gH>$pqXcjzFzA?q9wG;Tpl_3~Q zeDfiMDP?$k0bf6GVA_jsNn!OnMD6fql=6iC!~)D?PP};u8W(^0vIcw> zL{ynTMXmkzLQ!i7SX-YVzJ`Ify`;s@U=_eS+wxzN^Ng#OH5vag8hmX_4}4^a9jB^C z<3jE1ainHtk8cHVG>%sr7qi1PzIkFGo|D7_Y>(jPFzzHyZhU&-{`3^*nd^&ES9BU# z|c8+eTb6Ha_Od>ePu$KfmcQ9Lg}a^k#3$H)=~)alq%Oz9uv&1{Kx2~Ce*PP&+5 zq~OQPcDvF)Id$U(%7e7{X&k}Gw9rmPsd!0hH@sQ99#4FJGlsO-&IwghuE0&G8e)Df|IsZMbwy#MJ z%TD9**je+a4&IwH1+PFkIqdoP-3p%3e*-0IENO#x6TMj3oP8##{;WgQw{}L1&>D>& zJ=2*%@zn@2HTqsC5L2T|GTCF%3!>wjT#g33C;JAWZeXO0rmsEVm@+k2sa;P z%lNc2_IaOnap2i>Ja?ktc?$TFqOEvA0FdM;t~QPp@8D)GI6(3F_t8`H^N&Zb9$iuj zr~7Dr#VR%+{zxgt(~d3ZREnODg;RV71DZv^%Jbv5!FP58ee9dKVA_2$R*eJmP{0*< zc*C)JRcZqwSK%402wv3E7{Lf?jaQJXfn2<2JTjIZt;85x*=gkB)a9MxnMkJb>Bdq= zTW2{|%0Gr)QH%1(_`~+qh;?G78q{eSKUrOOyjN0M@As8z^Z(Lkp7Fob^ zgh=zm-R8B}%OQ+Oc8WiN85i>62gb^UV?v5@gcP|@b+Y|OQyV9s3WqkPU6}G*$^lcu;3>$qw2`M{=f(GfIUdBH4Ne#*PhH<- zWhq{Ye|ox5*gYD@rZskN3ZcC zY7l-r274rkUE7k5*_R|Ig4m+Q|AMLzEwK?I*6v_S<0-myWN!7!)CPFi^Gn(D(VgdF zb8sB9@9~j^X_4-jWg5%7r;dDXW!}i*?v7O>@tAL8@nODWL75SM1hs{`M|>&%LuIb$WaN zDqt3_mZ#MoXWI-JjXn<}J{Bk{XPxJ|t>cF}a;G@Dtt$nBbpgy=Y5!mm@LbX;2BC0x zol1RbQ*=lg9)`r%GRv@4%fl>vc5(Ok7dRl3@6`GjJb10!2Z?~U5zsikJ3bv-BDA0@ z{t;@8&(P_AU=&_4hP6zn`?{;6Me$!H*nTGE+?NQr8v$n*8^qJ&B}uIMw6&|!Q@gES zLqYr=-SV~1IA)yKe*KK@vD|pI!5eiWL$gdzIfRf(rW*H%%-{*>Gl~#+;`(^DN!lNL zJxxy!mh%$&kWRNxyQD5qW@3b+3$~u<6u%q|Y_vVv`^1Ilo1(|G5WCFDRN?+Ga5N#v&XWbmn+cnvn8$r&o<@#N)lGDcHtNIRy)O=Z2+t zVa%YWStmbD85`?^3}8S&5*NaWTsY!CLt`N=zHqXo2fl*LB=$oaokl9*AKPC9HXIuX zoVj;z%uk&@1A18*-GE$E6HTBdnt+Y|X}k?;dFsf6m~MZAwnMc&L0xeDm~QKNr-mBg zF)D*@>-%$v7N+A}GZ#y}aK6wB-PY3vv36w-rQ7<>z~UQFpKF_`WRz~}-i3_#B7`&w z1&dX4yq3NODp@WNPiT(D_UWlxd)hUn!CjlSsF9 z8zC`%K7}`nsX_sY-i0IO-NN66>IyHfs({Ji>XldWHG#z`skIIG)6qplywPb?Rx30lE9f9R)`NS81#8Ugz2#7--xlJ>xtimTtvE+t=R%qFz+o zm%I1ts%{M8Ud2Z(ao*N6{v@Wh z>mA*0*@WPcrKh^xvKol-5=6{{@%8)hMeah*;7v1A@d6Eg-(_X*vx|B(;&Ylf8^-$* zcA}5UDg27FC2eb;O1<9Mw(5f%C9u`@~ z^U!Cn7Tv1bn(Yi()dP1s*6{&T=wY0(pyi|vj%Q-W67S7FSK*H_abE&-?TQRs>@X(p z>3Ft3mPWmj5r6e>%w6{dXE7}C3|m@!jwrN>iip=hHb%(WWogQyzRY2_^=C1YnS=kd z@wqr~O^^RbC>$;RU;%r$=yq7Utih7R+T&3(!7$VI`IoT&uv^$oHrVjQeS%r851e?d zrW|jNv;2>Vc~)z@Xyhx=D^`Er7upMNC{laB4CC5)pN`d%x~;z*6@rJ5tMN=6c5t}O z0smU$I<{iLSv09A-72A^)DsKV) zoYJFlDn8pAy|UY*u?(s%s9PyaMY-{5TUa_yTrI;F~V2u%o1w z@dGi^s)Gq}8deKvC75#Jul^d3&doS`c;4K`H|8L0TH^_v9$-ksI{gNELzxo)H7M|! zpl6@Nqi)=xARS)RiNQFHeR7EdUkTPPI`kQa2+#t(Ci!!Ty7UU7{ zzhqP`qn<=mQ*58!bcLDx_Qr|ZKynL6PzQ|@Ps6i@^jk@P8%33z)ZcotLq_J2WIsuQ z21&`8f3(lgD3Y|1q}U)CK$6%=EXDP)V@|iHzL3<~)u6tL)b^5n@)4ry8I^*lrr1$^ zf1Zu|2y%RwBs)oRyiMk~m}y~{?@!e~%QXv&^05~0BlS^I{}R-AW;y=B-@oK`EOt`Q z`=~=PVkAz}K)fErO|iIsTlyDP23sL-DoJulQpwa|dU@KR4_v2R)XVf7^RU4Ta(vf=@Nlud_pCsr`gEX{X z?BwdFQ!$!!#m>O?NhU*9FECte$b1LOfJBWkM{oTNBr{3!w-4BaZSfDUfEIo#LBzcM zmPG4F^qe5-9#1~ScE)lgej4M=MoyWHByT49y&!LDYPb#Nkh3p;1~m86FVE@^e8;G~ zH9g>M+|(U^!B!5o#LyW}8Eup?L&(_i2xL4486snAw!+)EX$$^>@w;}$3(45MHyE!H zjLl?RV=_WZY+5e4-un<~Pvk4vUI*4(K$a7DaZ*#$%x93vQjy>Iv45V`3ry}cE$}vO z+K<0r+X=Qre($1;ddm0-W#C?0_%gGL9BG_*81zw+>?FxLkl;y6eathq);I)`DIjUw zbO?3zU-x54zFotU*zEr?nD6(k-@Vn2w*Fih32Uu~-zcB*ShF8NjXB5KHXqTlEddIk`5;+9?-L- zFqMZGwV6@Ph-!+Z=^O0aOlUnxnn`j8Nt%vg3e~T=$LzsJ;BDM=7=J-K3$%%@R7}QJ zGFI4=WsZh0s<dPpnLqB8hE$kAX;Bch*FiBECLUlb73c}XjBzl2F zXGrwsUy$v+%%Prg5T+0;sLpRkzv+<7{k>$#$pp*K!9u>)Rk?jh3MNxGG!vsXkl;~fJKzXa!YVx-!y-X?5Ylb{sjT>G$aIoSPQi3U zzm!a|?fM0RdAloqZH~RWZ3VlMVE;4@_N+l*?<}&_hL;y~TbIUlwYTj{XdV6O<)3xv ztWT0>CV5_bS9Xm1K+`UNKLUx&-yI}gN8$$z;+UQIFme-45Z97;H;L;(%%QmWl6KQB zM|(brj*+MgM6Ai&-JhSWz43IixP2_o(ds!3Fk1ENJFLa{Tq+Oi?q zpCloYlnD~-eNy$FSF&;(`scTUnoHJP{Q`Sd$ao$ZcaiZ5GVZNM7o+BDU1FuMDT+YQ zzWJV6)+4~0kCLnPILmri|HTDn?eA=yxC6wGkR){oNDh$1*{XLF)p1N8VBbj`1?kNs z%_Zrbg0xMf&W1QU*0v7eu$WC!KS>uFQh$StlJrPN(j1cRAn90;vete&4AR(HQgzoU z6pve#bXWZRy;KFb`hFnQfu*r_F-qb**(rmbpL3neRr7HA9=(+n3150w_#Pe(aUjfu z#}&WvN2Zj`jJzbyeOH@)SDINbScg#^-rb69bsvgs{q!x=OUZtH`#@VE_km;)NeW1E zGf1d!u5P6?v|x8Vo#+b3+GmFAn~xDaslV_lTyw%;qh3P+8z{iZH1=k2VlM51wb)+l zqp(T^D#zL}OxBH?j^Z!azI@j<);@x#c^_pYF%x22=ZgRE^Dj_WTm+@-2NqjhMC|b% zC(B8)yznNI?Qs@q9qr6yRie)ew1Vi90<9(bYk{(h>AM74O!UV zW_ks~kltLT*W`eeLw|n@`orEcFp}wWgt(JLrwa5a(eVP^O>~q%TZs+%r0SFHqN$p%C6VJA5EX)`sVVdkNdI^X z>ZPdxW-h%&ps1&_`fq^BV)pkEkPtsueiRJMB#(LW1x6w&7d>LU7tKx>Ka5ona?PX*dQ^oIi7O!Ri5>s6w67n%)q z4DZ=M-^E|#c$_`Q*D%KinPVLMAs44a{}zLchd4K?mLG28eEfWVgr&n_LkYbUj)`X z{5mkd^BN1&rtjC0eY{kTAHO^F+CQKs=CrMTiW^kDGnJve^KT`0h}=5`w?khexUotB z_xB|?UX?1i558~XX8)c}?p@@r1~=^OdcW!DAF<7PHlC(va&C6TQ@*q>@795-XCmw0 zA$y$c{m33ezYeonck6!>?iT%hx)6JKnr(P*X8GStlpk1gRxX6R^D4`a30Ku$9&a1u z%;_#t%_P-6QgIcAZzImaF%^_3)OotT97%DGzVk*KD|^dLWZg>E)nLUS{sPT--ezQM z?^ZOI-jKxcwSj0%pe;lf2-Ht>ojqUXOD8=BQN#(=jB?Dp+!p ztb+Nw3~98_vI+uZ^^kQXSUJg0CaKwxI8{ypiPX1wB;G>eDS|jn?+IeI>gB@SqF+Q8 zt@?RchgR*J5OU@igdCxeG-j5q>d^1lB=WcVKzE!<>EAPbnOqSpF@3q%9_R~AUlGpX z^*N?*W;%SOrmwa;e0lUa9i3o&$J)XBsX41U^o1c?5m^hh%+uHr$W#3*Rs~-AiB*BQ zWI-P)O*v!L4p|40bvao_lhv#^DvXOoNg34(QHIIk=Ns9*c6@=RZ4DBodemPPs0e+* z3VjNwZ2Qe1YTUE|e8nN*)|90L;deT z)8Mn((2n>%r=wGg@V<8s>$b$P`as&Hpe?@>$#Kb(roRv{3T<}LKfHz#9%Kn$|FhLN z^&eS{b1zxA2;Xn(b!?n1WKA6f)*WDF?+%d^k9AwS%|qC29@N)7L2+j5wSc!Ayt3O* zq?BArxzUg^z@EoLAnunSzLLZq5)ZQF_PLW*ZvR>*bKB(VklS}&1?vv7etZN4W$mZx z%f2V5S06}c?bn$;v2vbg`i8Uir*V7HA-~)Q`=m|`d7(XOjZr7P0n?CfTU(MbGrL0 zR-Lk%-v!oOPvTErVq+cFpYl_?Y||eT?jHSDaOHSdj`eHfrh5E^h@XKmv48ymrR<}W z|DqI3=wFyz3DJzrouN{Lce-uszRh3Wbh6V>$fCYq%$HPKu>XrcvruP<2;G(x%l zo!=#Nc#*GRivNMqho_3maiHT?o3n=*~4NW&D&Y<_VBf=^QL`4B9+ zU8=ry4U%WY2{m`K=@SF2-t-AIx4`rXHCJK!gqoXd`h=PrYx;zm8%iHeLIbtJ<>6wL ziH_1|5=GrgC72txD?xU~LT0)?51F3+#}1uwAfpa5YGlVKl~I}F5T!8+nr7yJ)55;! zf)26`a3=BYOCYWw@h2}(bH(*MWQx0@iov$62zN!zB;7*NgM##=ei`#`)-t8tL6UtW zc|eft(?6-9w8Q#^32FP}vDE^So+Rl~kaCChOK1k3C!UNyl)!$Nz_tpkU26R(Vt778 zTxW;~ew8ShMDs~>F|&l(_?>EIX}g|^-CWbgn6^#m`C`o)wczprUEw^!zzno|p zLnT@yP_Zr_El`yN6~89!HlqDR=pLdy1bUL_MMT%P0d>Wf-hk27v{!_G=1oZc5U42Q znyttdPEGL_C4KKtwn^+LJk3P~C~W+Yt+&yh|2szQVAS*WC^q?hj5^JzUm^-uarK|P zVcXX22FWUtWH>=`3rW^<9@STaiXEeznT+kxi_IMJc(zE+v4voiN^}%O%%_NAk;+j$ z&z{Ooq;fe)Hj|{kAc^Z&*-5xI{`4?Nnn}_bB#Aa>F#Bc+=_Eelmcz6SCw z7JSY6Ivf4OJs>V1$u5$V3z8PyEky6oX9>4ipCa6?`UK(b((~ZTBsVus+yD_t6mgm& zE~1FNF4q2cNxe6Ns4CDLqMZ`FXah}V_sKsZyPFQ;jt*q)g{OJ=c*y$wb1dn0{l$-s zWaa@|6%z1&ymcZ0EMZv)Zq3p7e}tw84!trutk(K?{A_ol(y zxXFRP$W1?cB3CexT})&E65)wqB}TqY+tJGQ_ZL7kwg^O>n3MI}C>`JWFr;r4(zi(I z&w@5lgneZ6lkw2AV1$~yqKf_Yn0^g(tJ%a8Y4pC8q&rCZV?o-c|EB8iJ6mkN?Y`gtIs z&3-oWL}j?Bzb*Te`r`9o*-Vyq4zi@j^;hgxXifybAW1Vxo*)TM;B)L!nDAzjw31}I zkaASN6;hh;jq_MekK_~}KHdzYDGDb*m)`unN zjXPN9lO#lv?+TKGy2=c|wChNaqN+K@jvoT)PLiH{h9%ywzju^*J+A)>hY3y2-Fmj$ zY(V1-+M(L*>QgN*VpYLz{TYN(u1`xxah z1kXZVB=?@iiPWY;ND?PWo*-$~uVr?bP2oPI_f4>17^lf${KX%@l~D|?^99#2U9nM3 zq>?{M5*JD0PqSH%=(D(yFy{A7SXHnUeo3n3q1jl31o{wAe3AJc&dW{RnWZtG!o(f*d~b`$Q@4f0=m^1>Oeq9Hm@9w#{T)3N~49#@H`Kl$=?d zBsxW+X?7y^lmU#|G8s`L5LG*OA+9Q?Vf8%gsoHhK6^TDc{1n;_;g1lHOMD;kV-kOc z_+g2^NW4YjZxC;mc%1kyiGMO8hI}>{6ga8 z62F{yk;F5IkCOOc;yDr@K|Dj^PU77q?joKh@!7-`iB}Upg{2|t;U?m7i7zL9Oyb`o zepuqS5pR+B4~REQ{2}7IB>pSnJ0$)%@vRbnmiPvVA0fV6;%^ZTN&Exi9*O^*_)Li_ zLEyy_KcDzmiC;#1xWs!B&y;u;@g5Stj<_oEal}(4UPAmdmVYSwOyX@4uOfb2;sN4E zB))|BL5Z&;zE9$}5Z^8Fdx-Cp_yfeZNqjf)%@Ti%c!R{BCLWdepNQ8={21{HiN82#j@aq};_;(KT(L3n{H z{s2rp)8iGAoH5GWr=IDQ@%^r9_n+fsmd|u5uuzYMuCvgc7TRK=trnVkOF~$Ng%((- z$3oXx=uQi5vCvivP2FP2wa@|!^;qaS3*Bj7FuAT9t&M(p*t ztoi?c{~xb`4`y{$=FaY_xBw#nSpW^70u;apH+EGH16lx&0(Jp@2)G##08{`90V4pJ zfF6J}z-h=m3V06iC}16AZ3El~co^_F;2_{Q;4~n)qN{Qt;3_~CU=$#LaQ>Qs*8?^H zwgX-S%mwgwcwSfKw}6KL_W;6x`GARl5rAyKRe*FrXTa&XU6nS#alk>q2MD_l?)L#} z080UL0mXo^fZ>1)fC~6{PFLk+z>|Q70owsL1N?vrKrtY7eplsUz&L;gxEA07%m;)4 z>i}B;4+0(qJPmjea2)V*Ir0Q}6p&U18n{~kYXD(@2QVEl5s(YW1gL;hpgj&a3}_}F z;5NW=Kp0R9Z~=w`t^n*tSw2L1{B1+qYyd0=gaC5^<$xkU7T`iaGT_shU6pqLF93cC zxDW7sz;eI>z>R=nz$xS>c^dKs=mi)K7=!R^z*PVhaApSD0B{s=5b!AAXMk;h4S?kU zKVT-H5HJFe1<(NLfX;x=r=#rvuK^AL9tG?G+y>YLSPJk1ZUhtoh68#5R6r`=W8~`{ zz!5+TU=QFyz*fKpKp1c%pa{U9hPJ&B@Fn_P8z39F`CExsMr;Dy3AhjNFyOa(hDZFODLrOUdgcRtib{r&MSiTE9zP)BcDev|Jzy~Cx%`M~FNz|pe~<>-43 zB}eJ1UUE$rb$?PSVv;LmNs~67kYiJ+#ujHM4Lel5t8+;~z!@1-i#(E(0{;n#Y zy2tgo#1HQ-Q25}z8IT_gJL`Q>S2$SZjYJfsPKhX0N>B+aUi`~eJc=Lx@ZCQA8-dt5 z{Egrre;(ssmZB*o#y?GjF=UDHPZ2SLMfhM5MqU>}`O7oh0;E<2s8cHOH!R{NBOi-8 zgq4CSig1&v4Dlg^*g5l*m{J3XAe_I6!2L+s!~>w_FAtny#V5*FqPT%qDYXbMM0_QD zF%f3+xs`w|MCMmfWF8eo<_j+n5&5BP=D|!`y69Rcty|8CvA zopP90@}rLwji{>|!Cr*EfnSzZf}ciY34TgR$zYFXFcAD)X#PAvfw#(ASLqcEJ~_B3 zftOZAgA6Xis51leVl}Y{GBz>h7cwTs0-_=FLSY~KXo)*qCECwh8IHNblExhnDAG|N zUx8f8R3M9T00HnVQ6Pi-N};z>ndlBEW$tJ!>_G&6g<+q-%4=ich!Hl!>j`)bPkBsY zCBcA*EsGhhJ4#*!ddg+#V zqto4f@Btrh!}F-F1Tp?3C8wlz>fFWA^}O@bF1WCpdeOy~q+fd3ce-DG#dmvLdDYcg z&tAPV`tbA}8ZHvF1vugkrD#K=*j$J{VBZ(M$Xvv7RTgo%@iOD31P zrc5m>pEiBQ%vm?iu9!1--h6jumB(9MQ|nu>&|en_hHeT+qOnDb>z6EDwtU6PRbr$B z&|`cUyiCPc#cq}sUbD$ z4h=B@{9S^)GgZcg@Q)HDhfj>ZY{X0urIb?Z5K7Ib3Ce}Yzs!3S+JdF0W{*IkU(f`V zYJ^c9^}Ja!>L9D028nvAL)z4p)GwNnsSHM_AJY26R}Faq_*rI_k|FE?tWTEct2Gr6 zd8Ce&`kdvHJ;vfJ5P71;WWKT!{m5+Zp^5emfR`oqf{wLSgR*K!Ap~B|D$I|R?uRQ& z%TUUdF?FCcbKkLF4N0VP?tVon?c1BO&HB#AI4_5v?ZUd3F|vkPSIl4b|0DgPV>xmX z=^MujX7N7uPzXrj-t-)a`RwGHj*UHfmO$C1P_`tPK7O(MMz`lM|8MUWMSOs*~bsI{+-9CIvMHD=b=@Pxc? zUtjZ(bFK#Jk!}=YmNjJh*b~iGv{EzMXNYorBE569cMz@0_L7>9<2fj_1GS_VI+0q+ zDLm<^i!0;G$y*%i<#2bvy#j6y-0#BO|9yvwOXNxj?o|wjdo|qJCWorQRp9o7 zqc%F!dblSyIaDqhkHB3Dw;ApkxVz!fHoFCGi5MH4A30{KMVY4~jOCVEAzvAYe;PC; zdp3KpTv-(ZowoUsK zoZypdx1K__tDUqFkf)%pawo*~LVt=-G6ONcA1FQ)+L`ZJQk9g>O6O!X)#-G0;_sRq z?Dt5h<+^5eaVXd2SNs~D`*^}lfRE;n zyYB)()2vTUKY4ZFfh5CSjr2tNoxp^**oq(CN50=MS15Pd@Fw7_Xa2r#!*8+STWmO9 zp_ZV(&4%A@!}laxG<$70Z4exzkjL+=C|Z87F68${y;^DI0&i7RE2b$X815(H{O(9Z zEAn~6+}$nF3cQi3urFjpE7~}B#H-~CqP%d}y#!45FpFGsN3~2vD_;`wb`Ub3rXRl+ ziNgLi!@;pld?mA@29reOSqj|iERI8B{R*y2@r11rOQJ>rITj~vKM(liVt(onA znI#+TH)gzJec1A3s|n=mEA@8HDpTf%{BBqPya5)EePH$+t;!#a#KK-#zK-#>*!jV_ zfKNly`6Ip>w!0~T{U+dDJbMoEA=`FQb<|zyXQNozNF>vq25mmIynF)d)>)*?k9ne6 z*b8Goz!yLw^S@F%2{DST4$b5 zVD_zV%7jUC&J3{ZiT-)cA}I4CsCRc*Ryk_M);W!S>8*Ch{LypQxFugS*}3>-=B@0p zT|>)wDd0`?KhgIPrOcZb3t&Xn1YrA_ zH!sZ5>x20Tcqkgab~s$GyV6I0l|Rg^3Z80rBq}}g=0$6LtY<{bn-__C5;P$tcT7x)P~~@^$6k)12!Oj9pEVNV}Rp;RzMuk253Os zazH&G3J3wtApA7I54;xO0n7(f0A>Qp0WLr>pa?JukORmB^Z=v+PTzxc04;!>fOP;5 zpa7r&QUS;BMtK3-0LuY>KrLWCzy-(xWB|GY9DufM4)qXVCtx|C9FPe}1H|t_T7Yc; zKfncG{f&aF0nz|%ccM-JY={5be;QVc?f+$B?I{1X4?nlB2rJ2N`nOK`>c95%s}<{C zlJf2T*(Iz|tbfVaXMCG~CcpN7d-J3GUv1ag|F?TU((1&&q;L5%TafOWBz2mW16Pb}p;etX;SM=I?FT zxT$e-)Aw)La_eokZ@uHrySCkZ&%N7!@WUVN`0;)B?|k6FpFH%_pZ$E-e?9z*-H-h8 zS9|t8`s?Q3{PwYZzkB?N{Rf_Ws^#}jKXdTe=l*c$`4|3p_)jmsbmY%3zjE}|*IqyN z#+z>)fBT(xTi^T3`*Hn)6K#L}@NXwS`uLMmfB*C!r$77ri!=Ykm8k#e0m;`NfPAY1 zlK<`U|8J-NKd%3ObwKs?@#28$f4lrRxHHbzXZQl1;NmiFG;t1y@M#fmSZ;bJ1h8wX z6A?2oW)N45g7}fKAJ6*w6qj z1?HLB+FFOBOMNJ`I23AUm+=nF$;kmtKF;VS1E%4uBLn^+y{Amhn@o4Yht?pVwm;1G8#j@s}{+{-Y-dkXCVg97;QE9}+5FN3Z4ln(J1cJS9jwtA_eW{yf$ z<@RP&`4}x43~K&hphi)~CU;fe9i|Ao;RO(Wq;psGx!GO*XQhY{r4pGWxyq$CaJp+HgK$>-uqdS`g6cv0P_*{Cg>RU{m+xscLC`L`y65UUnHp| zfZGB7RD7rvyaV$TbrRqvz)XY<{#%OL!>On%M=9!Pz(T+b`0p%G)I)`e+8I!^Kv5s` zDY*Bfs3m|802@HJp-xe6Mcn?$iuyd@5`^`dsi*~zdl%&YcB-PDU#6&MQo5?cMq1_D z1HbM{66LKm@JHq=ss^0({rX}>J%YBl3+`#atffc`{@(&;+~jG+N?B=->*J9~#SMxgx3N~o^92@Ro9KZ7irZT)6pX->1O3q4rK_5= z%Br_>^+n3|gYMYPikj0aNeuw{_fAp|Uzwz~0O-C1An&p7De7ID6!o>=C94l??A)%u z(LeD5N%zjdWOZ|QiJNJLAR_{Jp+V-S0l0QmlKSY>B=wr1N$RBBB=z};NowaQl5f%HOpU@Sl*tm&WZt`m1Y zOn;%9R=6cfu><$IjwGoU9Zyn+0hA8@9K&9NfE|FX0M=&_ z!ZQHNvCo|e=<%_|x9cGGhJft=((d>S`(;1_AOx5XZ~;aE7@zwAT!Vl6Y0v^108v0K zz?605T`P?Ygp;=bZu}(n)qsNlhB2-Opy7`eeL);Ff5*NRkOuq=%GL(h2S0gO-smBu z2cX|9-#Wxs0L=0g10M?*4mcOz(Nk8q8BaGA;jNz_eE?;d@|bRmQT8ox>jCotMSvUt zdCj~iv@0O2^{@yL7IT00LJZyy9=<*@E>{)@&G2E-OWXK55VbGqyyLuXaJZrnZQ#4$I$2O z{n_k;I}yGaP;c}}7hJQxatu6*dgu<^0XX@Nl-&lK&{04OU=Ls?U^9T}(oSLr#?jBX zT;MqXj>k;6X5V%IKl2va5^w}STK1R2$B=IT{SUo~u?W}z@B>_c;Q+>Mc>`qt%m09=6KfF1yafS*}z)3x{4wpU?a0vrJx1dx6M+*cuZ{lO7S%-E#WY+1PgYEkvVZPz_E1*um?cC(C<;dfMP%{Km(`%1#k-WK$=9I1E(z3Pb%QdQ!>64bzi(6 z{TnXZAs6@_xEkCv0A&<_FBgyr=nhB&CFRGiWY0aC$E>aMG*+KHQ+;Te^tTyV}5+AI+d)e(;!ta*aWsZs7E;1wF$_ zzXo_0xcprT8hFL;G6N^QiIe_nBb;Sy05R#A79SP55iV&MKFh#ghj4aghBKe}2F`SO zm!ILxPo9Cl0eXlMzwZDc&OCGn!hIZnmm4_4iC+tZa;^k^oq=BkJlDXTz>5)2nw|#E zJof^QErrPcT?S5?-oOjs5`O^rGy~5taPsy6ZvSn?8kPI6=kOx4V*sw7Tj91D{=RQn zYjEvkiaH(P)j_|9GSa(#J?~%NPEyHx7Vg4#uucc>&wx)Wb50#LRIH`TmPBx^y2Q&9 zsR-raUa}7h>B4ZZ&af`D3!945Z##`E2z5k0XCPKrAdVoH7$PEEs~b3t8hLh_0`DRp z9yG{P3MQ1fit}bE1w#vlWET{(ss)~p!}qAyT-76N#?%SrPDxQPBaAc9_7uFoGzhm* zSO`-A@>W$9?g)8tw}v-CefZGpLflrV11)c@-Gn}pt_rpIJ?%RNOd&zvg5BD_S{)}Yxtv<a#^}Jj zWc9pp$?ABxMR2DADgg5V-U8$c@Mpk4C-MvM0_p)P0gnJKD@3^gSAhS|6O&aBWO`>L ztNDNm!1!L5c6J4CEWFKmQR6>H&hK*LhqIbG0ePUpxD9^2C^NH5vxHx1hr5Y134Ir;A%uojQ0R= z*9ZsP5%K(#%N@m~n1E&AKw2d}M8deiHG;D)6vZVPdCLR-34Xt~23Hx(kjc1CriBb4 zzCgt1@oE*LDsaM%xnN0^--okrBwXzcdjnNo=-Pk>7e~T%J{+{$!^>gW!!?v8T193> ze+cx2Bg#2tBbu_O1z>-zs)Z2gPw;1&+<4yS9C_oN0E@T34bQaU6{vNQ*C5@gUXO6| zV^Jj^cZwM1g25NX!80+u2m|{QT-=7r`YGZk?MzP8Yb$JOCm+Y1$0w4p_LsVV z^|}$ZG}h~&XOq<@o|EA>?N3(k2D}W213m_@UI!jXR=52=S+&>e(3WKN`adVDw5J6g zfZhVIUXMNo{j?8q0M7wvPx~(NuomG@03QFZWVPja=-C&N)juJA67uE&^g!9(dI~xY zX&pjeBHr?3vbrDP(?7B1sI+cf)svq=Ck@cVv`W`iq7C4h`V8Vez9>a42-YvD@dmVo z-X)8JVUJix;3}WE%oPcFt8g7nGb5b!QOt!HS{Tpb>Krr$847%1^l_YVz%$ibgW1%J zQHpWyn%0q2abKIekS$al3xGxPyTdgxCP*G!;0vPfqW>;x-xTogRM2xb&!3iCoVsO9hv zF1Cp)dyyr9sJmVh*PD58J#Vnk=8lo4WT@5K!`IWXmz-p<{RXPX2BIT zk*f&vD(cyuRY6BG=o{uUD4qf~q(#gOasI=+giD$f024lz#}RFDEk;L7%zLbtyhxoU z>q2v$iyZwSxHzJ@JuD(5M#Jue{K_SoS;cN`CjYPdhRK6+T8)SW1llp|&C&wFsI~x4ph7We z9Xrlf(>3{cFI@C5+!wD?cB)us=cTAy47UI-_ka`fQ`9QJV!(@l0|hB+E?|T+MXfGO zQ3p**5&Jk^U#6}rNL+)CD0xwA<0@lOMz|vZF7Z%STph(AT$0evqIX~^1v64LZc~HS z753GAGX>;*?X#blOTYHHQP@%v51C>fMt-vK#}jrhX5P3Gqw9B9da1-j-IFth1gBV`Z3JMdrvp$3#kG;1MS0?A2gx?kR4zla{1Rd&t)xvr-!|L2s zVczOD{q{M=471O3P}KpjD?FFSQJoU3#&aCOni^{F-dL3OHkHaC+5ZxLrs)e*`C}eY zw%*u&C*lUl@sI-=Q72eZC-RRlOcM$QyGU2g31Kl8B1$nQj>W!cE&aW*Fy~@CBG!u z7^k=wd6j8cw_(Pp7Hf1{<>vc+AyfDJ(18nWbGyqQtHHdg6#D#PRnV(fFUZ2P8PO#e zel^+5s4tM+u9lD<)`l_Oi%=2>%2(-ji+WqGEyw@98vgawMrtERYMEMpZJD+LG`?yL zQ(CoF?StmVJgkXIK^Qb2>s|9;RtjRm@J8HKniq$*Y$rSufI5PTkG~snXEvUFPCO zODs98_(YHbjc&CG>_YAQ&>}8e!v7|jR(yMz!;m-1f=J;~A&v9oJEc@`_1^YPWT5q@-j}ahTE-p9?~h zkrx*`&%c^4GZDmiS4|(Sdw^jwvNgNX*-J!_9!p z^@4MIidqh+1v~}#)elqD{y#`jvwoDKcHfbr*6ft)g*tDvmQTc0@d+v9)#I(in=df; z2CKwg3Tw;&w3!%3z_|@lDq-VrV?S*URE}p8=a}Z|-XFo!zG7Wp<*xH**STwaRf2b1 zu#_iJ_3-q(VddyiW5&*1-gn@j0fRH35NFR>wqj(~i0s}<|2aVV_2TwN>4~>f3>b(v zQ;ZO=qnNuK4_b(L#8EnFrh1`J7GXCsgF8(vQ>ZxV0u~RE8nNUu?aixWt6JSzkuF?sU%bioTvZB1HPOK4~lP0^$%01qNfe>d5!*9uk zjFLPTY$Ewi7bK2zj-P;JaQ~?c+_2NlbmmVhcPbMKVWTT|mQ1)2I1?z$%O}A^BuBd9 z(oz@QlG1`{xLT!5b>^2&EkHS4uHp&#c_Q=q#d&3Apeb;c=S?Waoh%fDJcXsD5J-0_ zZd~DPVruC$3M+Ev6)+sTP9CKQcU<07r4($XE?FN_ra7lk$W*7RbSm;+R^)WDV#@Qz zDdnZ5#iXA;!O82C$_!jTECuGoEyQV)%b5jbMv=?}#s=GnV}x!1PXmfY57#UOa>)YQ zTo^Zx#4-f-I?Kl3ES7bJxqE6UWTG6-y!;}C;jA~LM~AMN9C4GJxXGea)wvgXNo(3l zY@KGDtq0}VaF1`1Pg-3$wpjwqiNczKxlr!<&~L_-vb=#X_6T7-!!&!@=&TVVd-j>z zcfj%+R*D4+|747<=sRjmZ?0I(u^kF!i(P59CkUN@O+zf^gEqnXvUhJ~@ZiD9-~j^w zJ*BRz!YbHnY)s6(K4|U1m_KkJC_LD`C2YiEUyk)$m@oaJC0i^KA`!0SK&fGq z&lRSyRf)}YI}#D4W#(jwDCCDvxrx~}81OIAs&RlOVvOf8wcfNnAT`aHOo?)ar1GF~ zEOSVI&LR8>+l9^gL34m$?U&I{t4bJUpoDDOIE|}dK~)tB8Ri8k&XgytA7Y_{f<(36 zzUslfxu(TmZUUIUny`0?7L4&}Jyd|O5}+2i-{sV>$eV5J511vY7Pen>pCi3k$OBc| zzIMg(UpBEcjr0~FTu0!IN%k}(cgIAG`mtMcYJD}ec*3qWN{b1WD%c3)N#a2_#ez|^ zA69b+7j_+Eu0ns7B$5Kl1VNFg`)`t6i>3BgBwKPB-BGHsHbBdKb=COI>&A1Kr^I|? zE-+AMmWiT+or!(^KeCz}Jop<8O@jyjcPvdt9e<;(kA-4Oo~!htkYcH2EHFn8!N8FL zs9z&6+h(sjr!BCZZP85c>ua@Rf?r9`WW^XL|4-S=Q18?UiL}f#{_bxtkP6t+;0yYGAZdWYk5bg-pQNb8T~mcku_TCTK$--VKp;OHgu%TsVK?NsmDXc(hLsE7U>Ng` zdAtKY*w4s^ymQ@TV^@msJ_Uqe87?cD6MSiiQ%wZ*1{DlHr=kGdstD%-tVP2xg?qz; zgiWuSW{rq9<_QjhmBl>n`C1yRg1Bh-YJ7fK8Q1STXP~XAqew&#v&X|f)b2OvP4Noi zhuGtdxgZkBj#S|f_E2~(9d;;RT?m!M9TncM>Gk+{&IkgV}c&ZQp;{*BQn>(i4h(zDrvIRFbT>8d)%r>Z%I+iLXr2@_J)D!^jEi-2EEOjUCM zS(8%L>x)y>73H$eS7ICnV8jb}s+7#pSxRi0yg!KmbBJQBR$+k#+Z6Z6d^!v1;{7o( z+IYDe#Z4xR^GdOm7WQMrOSuC%q}iv*Oo?}Z3>@X8nJi)_>z*8U{>LLtQ1{iKn!$qqFanV5Bn~@`tb~PBc zu>GK(rNNhcu;GTW!4c=Us9if7>)m8c;0C*B6AUZ5LKIx|GoIXwFjE~c-kt>g!fXv! zoE|a{CZibuKUIrTecg4|TrgbAj0G@IJpHY(Vdn@NYMUouV8__S#Yvn)L7Pzintwv*+TBABT7xoHypR9FlI54VB!Z0&JFQSGanb<;Kxgcc;P|LTO!|Hyv0OW zHVEsK6#%%{?JV@77Rtt#6pJ~jpuE7|(5@nv-K)5kzz%75rU zKVG9tPuvnRPVBz;Hz|6$)l09hNh@PfWeluwyUoPW4?b0;E5|>(-kd4-6tWlJ)y-NlKa>(>b7~w8 zHxo+^siz|Sv$P3=OL0;e5tp?!oN)PYV!)Lv*5tx)k)>sdHyiZ_749z9+9puY$a5uY zPR$-PP}X-yRyggfUS~+yZU+n=G%&OO=w&Nb&Ym-J)R?U7xqU{^INz&Zg;EoYin>4D0{4RspEtSJu}vS95AR%K~Imu6vWm4)Z3IiDu(6M4Hml}TP0$~f^tL-B9K3pwXV(nyRc3x1cFOZgtROgXJGSH4AN=LYG;9|dqhh%WMVxf6Y0Ih@T4$#k4Q67gYCD0v(eD^q9S5ThkCJrM< z2QblcEohu;j;5x;W5MVtwlL8rZGO<8t&x780|Ypbaz8aOG2H(KfH( ztiYL9&hvosBIc!hmdk0LcNCZ60do9A-C^zn>C;P@&tmT-8NaQB2F~nZlER;5^gMVlT z{}8l+v39jol$qD*_WUq?oHv@UToidMaW8-k+)T`vGmwpJTDG%g&N!lxE!;Pe_fYDV z$b8~z2HuUv^Su$HM-HkO+_z6g&w-=HET4NrR`vkgdJyxHxg!nu>cUv4h%jL?jbs}^ zSkH~%tSp}}xchO_wn7oA@27aZdu`BC| z#Tl(L(hm>HWy}?(J08kdlow-F9+HwKR%w#qT&TwD#7Hm#1U*%|MI#lx$uHuhJw-%F zen}(B#fbnthYce9tR$>k{Z)0$o(Q8`hP5MUaEvL|4b?c2B@zsAB*}eO7;m40o=zNA zO`tyM5az9_6}lY?0k`t8X7S=J%;9h_?DsAb`_6g{TgbyiE9ClvZV!#_Ov8`AVCOa% z`wMx=6ct*nA#MU!OCvO_6$dE;VT(f$>{zs9QI8H#ZqT47vo!1-moDYy_qs@pI9P%! z3_@_LqSygR{e;|wBE~AjI9SORGl}T8NCVQ4m+I?tur%d5JBqG0f?>EjubnF81GZSQOp>;;X#Cq zFer;ficDK_m;$)s#2t6R+trYf&4nv+Eb1OI7t6e0EglsOS_Kys6AabLb9QV8MZ05d ziCM;6tI3u_i)G_-QjE(vE>B5WVJMaguUvOjP?;m0Wu{Wcx_+54K7lIBxSU{^e81!p z!>cUw@(dlPq=>_0z$;}6+Z>J(LQfJc1)N8jEH%RuxdQG-Za8u9mBEZ7J+J)|hmlG2 zYO&IWpX+0WW7RJD{$f7<1wV!|*TzZ!vxmgk|EP$?o+V)+Bp+25We8rwgA2A?ljCb6 zX1#^PN-{fwx{PMq&y=uk9q4s}zuiI={@xkZ2Q|cJG{(-JGk4hv%rzOX3E`43XnfVO zvZJt!1S|PwTZ~WC6oxm(Dd#}(>S5GhB$SwV!6$QrzMDAt$9ONtIeLELsNeMS6(u;Y zFUDDS{v<1wZLyfMHH<3Qufd8v8ZZL=3pXqvziJ`38y(LZ`GQoc8`{@hL62O>eZ_R| zf@#M%UP4}l4o6x1*&%K{#qXQs8fkx{RGUmAr_`^w=xjS1WnN9Aq?u_NMl4=)vN5U7 zZI=|KF$?|QI4H2vu?&;FGO%*)JHOw+tn9%ReMXF4+4BbU3alIWc@^9>;I~!qX%&1~ z1$`awtgXfxS;N~~aji9Bm->dgfw)sx(f&>$FBGE8H-U*2k1K|K==RQ-$L$qeakdY) z=UiZ;GsY?vvopr>w#}T8Sj&#)dX{@qu4;+nHUd!SPYieTnJT$A8C@#}Ae)(V8R=cs z3t#M{s)pMF8!XQoo=4a*z)8TQmpZ9yj&xEVf%^sAPhaVz?*F`#IB#$j4=$k`v9`ew zhMM$XY17^h`$oHX-bb|dU*>cw^uH~9g8hCoZRZi}j9~PX=NrH$;0S_D@}*mh%`Y2| zzj-0pPhgDUTvlut?(KU>cV%?|FWg;})32B8V~GPOj-D$|NN`)kAOp{Rc|eCXGN4{0Bc zDLWcm=ndeV)CzE8MS;8_?IQEw9!+oGAY)aUjV(sql57l#K#kYrGS&gYij<8J1MTUL zWLNqEFvhZO+Qmy_XCyoJHQ|`}&Pk6MA)IaON;}G2XlzP`!V;SeQ(v|{*I0X?ewmM| zkVL8s<5|Cc{bYYJ*15D(@xHj}mSUS5)?8B0*{sUgyL+|4T7jJ4U}X|2JF&n2KkR)C zTou*Y@9-gFQSHh~jT8-2i*&yB-m~|f{lSL{iiv`Wh6)M_iGYBLN`+}fCo3x|Dl1Jh zDlIB1PnuGpQE5?GnORX$Sz2*AR+N_a|IDm`VY79g_uluO``+L0EPfBqto3}XXFY4p z`kFnny4q;hbRBOs(^!dh7x2PKrAwxwSHSi$HyZ;XrU-hUqw&zDHufBfFvUh)U@pPY zNQ4J(S|PN@OW+$aEPEEsr>?qmFn%O->8PRjHQyyOE4dNZ%%H9o-winJ48mAoYtOc_ zu-!X%aZcWB=ybDr2G;NS^w0uTR)p%{u3CH|h)>Mf#-F zOYu8*cntSfDjw+o2YP-6zL@UA6#c?%h?eURT&9fa_FOwqjT-R{L?g2`i zjpl_tllfRyb#|bb!_SQwqTeUPgN<|?$c8Vi7a6+2CoA#S2V}#B@r-rGvHsPd? zrt6OthFv@i7lnn|uZr;7;T&zxm0kuj+0io(^2=!L&8;$Q+QLG5r!OXlei4SB;m^U| zK=)rp!B1M-G)krMkJLFeCqo~bOK89K!BiYuw*|P_=xN_P>Z|nMWnqRwKdj0v#(P}D ziAL}6&+9@^7-se0bfBzVya1$%NXAk^CNNPc-~2COfrNp)&hE*E)ejVx3-oXdezL4 z*eamyXRF{KS&W7@e6xyqL8Ri7=4~8!U9K zv6Zv+Gx~vyyv*{L$;G%U3-otFjIFXh6fGtbye@X6K4NqKvH{8kA&UwCDUr=|&^>tBKyhxjCb;b4lmae$5k8SJ`&RN!7 zzuwNe`1LtNS6p9->FpJH8#i^=)*!ntiH0^X(&!A0v6Is2#jBCp4_vzRbmlM;qlvyw z%Uh!HjKSIhdtKVgs5pLw9+qhL!lEMF8RgpYh$}BB*A|TiA0AR@zxC99bb$iuI`lm# zT4Nggh6bzywf!1w%xTzoM;AYz#6gny?#H6pop%FWo1$FexbeoLFT7t{g4-Pr2M{uf z(Rl+yrG_D-E#`E2eO)(CA38aDLO?PV3~P^)(3Ulf^tr_ag={*_(R8CQM|%y8E5ipM zG4;f|Jr(#p5x%*aovrPc(2fc1n*b5!2xC75fngR0qI3Z6o53aeqkN>{8vDlZ4hk@I zF!WcHi}bjM_!nayglA{kb2y53n{Q*gVZQ#m+pZx2QfwbHgQz5ttsXcJU zy^FaEIgT(jN<1*5#V!>O&tJeiPv2F;yaDeIYmfD@@1&2X#G}tim!dDiDi3ioh0@XU zY8Vw`GzWUl+Nqwdjr}@Y8_QhcF=wSct2MF%&B#uBX3MhFuaWK5c$1g%COiv2bm_d- zx9Dk4oQkgdZYsT-03R9e8)ypK3EJ=(LoTF&vIGwV z@U)UPKrE{uCb&lzsHm>1aYjP-{$ff!V9So5Q z7FxafMWzp!fQ7z3{lYjOnP^qi-Lo*wr(alr*Cen+9H&%F>G7R$E}G&9aXt-c|CS|j zzG#dX&0TU_BdHs9EvvE9-dHlvu^uHbWl0KFe=-v$t zlhc#ZtG^!q=dy2mjd`l}vkM}xi<%pP^h9SC-I`@tSC?U?h^s8T{W~AMQC1n=IM0)K znJ(xB&cd85EQzx4vA9(2-JFu#+5VOxza)Hb*+?e+8Hi^YX`mal69{ze1DItfjeDSv zB?{l<)vnpUzAO7!)){(`77D0Gd^?~W-(Ds*;-Ne#nDv|Gh$e&Yh)Gu%(vBk@1wCec z#7Fs1FzYkR5-kIKDzky&q%RfmEI)n37f7F3mgLL9x7wtS%Cr{ojVz7m#7Dtwmsy5r zZTI6_BPKnRcN^ld@U7u9@-^{NFzYh=pYo43$&lVaem3Vt`l6vb!&HwXlZ$vEOCvh* zQ84FimLZx7zO^PjRF2JvZv~`=={krfkWFSe(v=0iLw>qC5D$l*;rO<+!4pWAS&sNB zpi5@?Q=DXy5I1ZhI;B%Em(MIiv|8|0n)FclRwG^uXl3cd6UZjB9O>E$zGjmylG$(4 zLv-S!V7AFDL$rP1voL>9ob<#XZup4klup5{$B>ECN!(HJRWUu`0n%7fH$KXXc-KI# z18@+~2-pZ9{+hKqraa7fufw;_H!~W^n`wtYt7J6NVbEx^FcUPglkQsz2F-_S!*)ui z5Ct8>@eOo6ruRb%;z@uK=rMQ#)sbT~i>Le3PC)b>ah$Sq4$9 z&Z&OsngZ#mM|>+wGui~v%=KrMAsV$0Y72Btf%J4x9N!10IME4HFzYeP5UmM(Jd>d~ zwH+VgX#n$mOMK)%3TAy~S)#Rpugav4WY!?Q7SP7hi6@ZH&2pscIQaIMbdk(KlOCcI z9|f~bW*MUOdl26e#CIg=ngZDri#QLcVClpY$R@KK$*SPXHt8an5|bXH6CVY$O=cOQ zWrDBHq=#(Uig**CgQXKsAe+o`L~l3Al$<30R;H8krce#O;rLFT9@FbxK|C2?wt@Hp z)w@}ibZi7)g-IXDR3lykh{Jai4W2;dG0PEOGjuhXbWxk!hj<$x7rKo31Mvm2%`8j$ zTEW*B-#?^l3M3PYI1kv&Y$KjPwwdKf_Bi;m{dAQeUTM-rJb`qX4?eDUco+ah0VJT_fP1*&eeD(YJ!H&`(b#;;UF1(F5r*%Mg7Z_!|85G$Fo+ zr4c=l9vd!K}wDLo^@wT1|SWjO`T1xB1ND74Zcsqgj^pWrL50 zEL~I3#y`Z<{PYoDAbn<8lCJ_^l}VpA|3iEuz`q`dm-3@vF0)ylXluc@&!m&=XhXam zV6=VW2~-beIns3$d@=YoAzc$c<mdQSrPIAOc!ECEp zmzKXthV%xq$($GITLnG^a&%3B@=r!Q17MVocmnA%%aQCl@U@t9QQ97))tb^se;wk7 z01Ygij&ADNz2y5tji*`G_ZwF0&lThObBe zXVOJ!aY(B$rIG$>#G3&%ES=39y07m(UCy*|)9LXx+OT&ICT^k`AY5h!Tq<=W# z`2d-vlbpeCE}vN!<)3YmA-#cYGUr7)tH4*w@}W58Ux#=Dz}UkhoWI4zQU3Ge|RbUNxD;J7N1yAv=rE0UWHxCZb9-~&Jh;Nlt33%CWa z1MtX9v<<*vz?rimxg;N1G44Mr)0eOIG zz&5~VfRH)xC15h(dcYPyD)P&gbN(dXeqC>i;rkP&Yk$6HS9J01FkPGZdT;1$xfnot4W0h}s(!RP-QV8Jo4eD^ z`nT=rZFw7D*6;6+(fhm8{oBiVt=;MV`Pcv2o$fFH<8R&R{`pt@uG7iJBwQPQ@YiGM zrJp@z(EaVWHKIG+Uw&@yQ`0Ml>GZxU^|2MrR=Yo=VAuK)I&Ce(Tch>$U^DP)fO?TG zBL|TE(NFd$lMRQASvDhptm{%eUwZyU{xREh$xs}QO@TcZG1I=c;ban!VvvVnTi!sO zKND%hJJYS}E&!&nyc~E)ue z-{8H(qx+2FTZ8bXn0VWQ@D_rX@+xOC~0Ps6XDg%Y5_KEIvzwuV!UJ{A9HHITxsIX z3c^d}3FN~`G2uOYSPNZ-z16rTTk8Du8$P_(WJ9YT59LY0;C&gq6yL>UsP3Z%pSp~P zP5OO7c+d8Awb{ZTyktipf5hNy4WdyXyS1`Im*J0ETvOUsKmA4-C!1_&_v0a*6b#-) z;HCIAOosdsJ>=B>*ksb57KHZ=6K`b@-XFnB{^&5-QWr$#qIli@;lPG}4hE6QVZ7u6 z%f+WI>-{EPH3;us@RI%eO}69*kvTh|tG%oZ!YiA2n}hJ?ns|=};idW~y9tv|C>YqM z#q@t;-VC81PIZQN-w4shL25HJu91u{w#%PJS{l-*ZfMUl2G_)&ZQ?^zlO-D-G1*Zc8Mo)iq;i%q--gYc4^VK1#1jd|bS z-o+VmL}cL!#EomphkVg*SeN~gxTbUk*x(~<*hJSxK0b=DaPK?a^%8%TNpA_$yXGW% z?=+RQ*^kG_!?59b6YtR=ya&Kb@?SF1dwVjYm%?= z%g?A+BcCB-0_#t@OxI8RRF8z)n11Sy_b~lOPobY|A-T9qPwgMDXkp$-Z24kDPg_c$ zlk}4rEdnxf{_=D13J&9koU(&M;RI_|&jLc{G)Se=rKz`|Uv96bFp!^A1nO^cs3)9>F zU)1Xv+*7X-*X5VtxTd_4fq^;$rIDQ%j@A2$P694`rpTO&!Zmr~H`;71(@*WBis`RA ziGB~$KL*(7i(377jqD7Y%9zY@hF3CK%CGO`-OJ%G`z+%nU1>phzcKMv2H`z7xoh03 z3&QI&@$L)4n+IMh!vZElKITTAx{MDonN21cIfx9Y4b(2LY3n)eRX~?fSNXUmUsn6+ zH|pv*v!!>6eqWsfZ1f?GellbO1w(c`cqyLFWT@=NgUAp+g{3UNYk>om>**zWxkx9q z8?8Nz(#u8nF^_9X%LWGO42Es%nQf0V{0zg}fT?_>qt;K>P-5sf#AMo;4B2uphz#in zRG#?sp7j*Nch!>x*OV_0OgfBU*pe`=tNrHt@%Z!RftPG30VeqhCQE*-2_pNDDW8@g zy!%YN$Aj?x241rB1d}0O4i~zYmFN_VG7lNA%UlXna(NV^9T+3ugesd6+7nw|xNv1W3%=b*@7htlLo1oiz zIxzY2d|Ikk?>QgiWc~go`wl@rf zCcXLpMZH%K>Z!Nhq<0hVnlWMCL`tOXY~Mow|$%nf`A~`cs3*^hwigIvd!ihpHel zP9~FJl4%GclgDIAOfrXp$lM2Bs`vE_Kh9*SzM}1?_Qi+b1snGnF!}DVNj5WxY~M+` zY&0;*jsPa#P`))mWG6G(=?u>{$+iTMy@Scz2Tb{{XZUfZgW6}55~SRWm*mre@E!** z*tkBEbwBq7Hp*EUMAi;ol1%`nye0rsd(H$VKg|Iqdy9bSep(7l{q!nex}R)e#&IBluxen)P5m3k|FG)e=K}GG(i6kU1SrLV;!!^H;sP!DUI~q z!)#g)Olg~0{6%20>s4UVMP={s(}5%{kQ@clcZ|tLOwsk74NP`K1CzdCz~oO6m~^^< z$)Cx<)E?7;sXgWZlTV9*sXbl;OzrU&U}}%|1JlQH9%u0vfyqvCaI)*vzWfxtVB@|A zCYyg@vSiazWS4Id9zPo3XP#!G(63c`B}(_afrwryatWLxzqWI@*aznjUw z3rzWa4ov?40hn|g11A6XnX3E$0$}q0P+;=E1We^3-#4EkKeBBGc)`Y94NUPxOqTMI z-KX|RE#oB{OM>w3V)^W4`4FZueZX{3dDaHeaeAg+F3PX<6ucm7ejEvYy0!t6Ogu2< zc?B?)FN@*1z|@Y*fXR<5fVF-VnA-8ZEdB^Ewc}@isU7bGCO=afws=nMt2Xe0jr$3h zZ21G2Z0R*kx5WZXy2y^TL3G)`3pOqum~>49CS5atsa*4c$)8JsN#9MtRIa;$sa)$= z{7GQSlge}`NS}65=7Ty-~}7^EHLSMnaPr#=&{{>L3|X9a{iO? zQam#V?}!}Mc7TcB3rseT1E##D02?;13Ze__TDT1|M&0{kALAi3U9_(#a08 zfp7=%Bs&PGFQK%^WW9Z8egvI(`ymaeGY}u;{T#EO;<Y zyNUN;5Z>rHx=pdb#(fz%?$l)-%Xp~_Y7pLKCf@uYybm&49yQrg6GWz&$+Q5IJ^Ps~ z`LsER>@mhma^d4oU1qR!_NhLKuwehZ=bX$3U4}1tT$BDZKmC+;s{8X`fHADrq_>*s ztviX{jNGn!qt%bcu-&j>33$nt>lnU?$&wGFQcvxdEv9^ugYdSPc*}$E{>p6mi^))b zur7$q;5@w?alnTE_XUy3V=^TSFK75hhVKBTzHcos^?8p0(>$ty(RVVu2bl7tIaK6? zQ~RvHN0t{rG6aiI)P^FZrzzx{ZA5aZTy1e)&wIw&_3=#sHs0x=_b^EZ z-7kb`j{Ku5(y}^@R(pE*CZiA6SQW|bnbei`#57!AkF<$hX&G6#249Iu_DiH~MB35G zU3>{M`f$TnQmyw4-$U=rtNL(h04E?05CgCPIKcPQ`*1CQCcq1T&47mhHv)a)3Jl zm4H$}J|GPs0|o%wng-~IhEG^GgNn#Bj6m*pkm9GL2N#lL}*G`QbJ-n^yCtWPJ|jA3Yj!~3N=0#M+(z- z_J72e%wbE9eAKX1oT|ji5YKVvkt7bSz)8Ky_yBid9@6T1lnmw8KAF3edzVYX37O?R z3b29nTuI+-FD@Eg5zmEFJhd1l&r2zqTMVtGRIbD{igB-o>gSfF({T;l4i*FZe2%+| zBs1`Vc+H)d`7&xezHvT>JG+YS+?{K>q&y*tYK*woeDP>o}|G9LS8y$Pay~H@E z2C>r?mYO&rrzBlF*l;RN%osiSiqWZ(I5L;cwKx<)K1y6viVyY2a~n}&It^**1RToB zUBo5gW7<=3Y*6tM&EZ_1P-tQa_;4@I$hekDs(-u~NA8st%t3wRhE9gx@P*w(d>b0y z+{M%0P@M%|y~Wu>sH-yFQDIzs?$wLR%5{~K@rhol;Xk=C#70qWK9`777RvL|ic1!i zXjXk5nx0?0M3+GO)jX}4kK_LEd@>YYp*JiR(|40LJ(^lvG!Oi}!lo3_!PayJpLW(U(sqQT6ycnx0-SZL7lM1O z%PJ=KJb3U~XU5RPC6(qZ8G~e9iEzrC;v%gj&13fH3Hm`P_&T-5Tf7M0 zbWSWpQ_3iy)1A)bv@Z^);V4Ob3w#OkFUp;Oy9Mn77WO3>aO2CuT7J0{*FQAarGRZ)pL>-SeW53EpA#r+zZL8rBLRT!5FpPD>Gj>I=z zk&Et0O{`ker`033$*3ir&W*(>(qw8zarzuIX?!>OAny2FR<$QnzBq7Pv(No26+bCyUgsUdYr<7>74~|FXQc(ZJ z=uHe?U z=n;5|#~4O^68am;Lu-#4HG8Pp7t#^U+|{9zG2-QFw4qwB4I1n5;<@q6hBP$JamIBH zPN*m?Vix^MIbMOIkkG&CeNlfy3rt1h9$k?}J!(96VZijM+@D=Gqt<@lMi;`?vOG>P zm31mN3pI?RP;r7n9yiKpk@(Iz&Xz;HB@~n|$SFaIdr;8XXuU)sqzx~9gH}u9pAo-~ ze3CF9BWNCXt$wW+1z*ok)OzVLI7t>K6c&_1OFTw13_5u@yCDIG%5iUz{YiO?ab64h zjWW&`KxQguWvNLi3C1*nyApR=;nI0H-sdZ35m~#*s3B&9EtJj$%qZr#i@JMI^Q$Dr za{~jWPvy?#;1|tCXXpfcM?a&OMxlw!67uI{G=U*Fk75D70-i?^4yWd7B{n?z67_mT zI28rc1JoP+Z(a7;ltmrrqH z2xV!uPM%Kb&Jn%5r)Ji3<`CtI;_`yIOH(F{#+@`_0<&gX$mG1mI7ABL&b%a?6^LJA zgiNIQi!qtwQYen@sVikQPLl27p9&3nuilkbT$so7e~%uTIyTMu=m*|J&6(p%sV?+M z0p0cSWf(y6wC;NswG)ib^nLsc?YQ8ST=dUcs($7s)pI=87@mQ1LvTk|T`?!GL~}e2ae-0Xqv5EKlan#CO3ItPXx_ZMQk;cW27|azvO5(= zMvkV#E%AHd(B!lV6(n{-pO?G!4wlO(~j#vlq!k%(k@tOizc~jdVL{ zoH%*{&9`@jXB3v{rgE>-HAt96;?UD(ioq>tk zbMY0z2NeD|x9uO8xya?^2oqt5tGs#mRr;OIGSj-DG1JXusi zcNy;Bp84Uv%F)&^ql*?7lol6}YxFy&Y$|tv^aUbtd$k(S?`@8ITZ^$dG51Q()`h0o zFMM)&;gq5!m?m@YY5bG(bjNzl>kpK_K(`yGdd;H~ERZsnJVNC%ZWHc)Ee{;3gc3JV<6L*BCY#t0k>kxZ90B7FkT?ChOxUtE8zRV{qz0J~1XN znmZTcpSJMx`xkX_sdgqrLQWrTzbOQC0tImu-~)Wx7RpTo##2(`fCO4wAflh0Fe^zL z5R4N!{Bro86ZPGo?{AIt#$Q>E3Yt}b#^v*M8c2JF=5WO~zHQI+--+4dza!w2lqU&# z?l>j)B;ns--T(bO^pj%efOamm8cGMpQ^q++RdJ`;Y)lt9OUj!jM(H(omt zbP|pPoq{t#r%nIAZ`;2shm$k_BU!tf?(u)cUwV>{;phKF{&>d!0{Gu~ zr0tOb+}DpBdgQ8;>%VrrCNZfO$4xpg^FRzY>%i3q#Gd@`@Bggzca9UT)h(mv4~gJv zygAac9k3P90H_CS2Gjx80crtj0IL8MfD%A1ARCYc$OL2n(g3M|WIz(Y2T%bDKnBDC zVgUUB769=_0yscNb)@A8pbfAeum{i#XaZ~nYy{K-`rsiKjdv8*AYKiq0#pD>0QrDy zKpMaY-~rKqNI=I;&<{8W*az4HXaZ~pGypaOHUicHY5=PNs{rMIY(NGe89@9hfCt0? zq5#KljI;vopGy&=X)qrvU*=yKM*Z-X%cTxA}Q2(cKveVyIOJ!Fcbq}HJ8&JND z@Hg^qS*!!yNA$dj!sc~oGc~9i0O>j(K;tz5nze>em0Ujnnk`4a-J<7}G;5*XankcD zdXhw#(g@QtOQO;5z6=`aC0W8}0Z2bNo6_hvU*|BO^uYj1w*n|0&*F3sP#n`cO=dDn zPiGhtLrwoQV9FcYw3?m;z%hUl0DWT{%MZ;~DhJt91t6POFnm2Qm1QM>=&Jx^&mDjf zfQMLoJuum`5kUDp1|Yr{0aT{90Yv`@K=gia3i*eC{L&Y&_3lW^MZgWf1Ayy+F9faw z9t6A&_*~#x;K9IafX@W32By5KfXSZ~z~s*oV5+Bl;DNxoz~tL(;27X6V9GxOm~2V~ zJ`Xqvn0%uG_Xn1NsSI(zRQIvKP-~pIDrc^=crNDjW!AwCgHtxoFpmYVjL!fEUj3k^u;$sER7?{~&}gSpyrY zjJSbMmVPq&f0f_RV_-x6e*zx%OK;1+0wZB8K_vR1+^2)Xbu2`IKOg)j1M1VLFM9%g z75RtqF#D$KO->b#CUdX8~jbx-a2#&yj09sTv|@SSg5c$-Yu>wnnu_Jyy$ ze}ylm{h{YeF00$J>%jtF%ZxvVem&r}iTw|+^ew#Sqq`H&>~-siryuhDzH?pD4=c{O zeZ}>E_w7_a*!0ecltC4*zV9pE-Mad_syD{IbXQ&c_8aC;8Roe4x02S%gzcZ+_Sx?b z9y@&P6O$6xf3x_jJwJ~awQ9vBNy9A{Jkjx#<*QvyekM&PSSOd|FkM`o;tI#{4aGa(2_u zMJO+~chBBEdN}4?=sxYE4JGui!#h3K_4&kG?=3oK37BWyxD)Qy#48j znrqH(yZp0<-+r$-{L@YQPc!d{;XK}gIkRxUcyXz(tUT98jjbC!uV`L*es=~l9Zw)< z70;c8=Opv;36BKQxz6gSe)6>tPbnt_cp8lV3aIGG;ON7KT82N*UR zwit5e#{;MIfN_5rOcej`3Z(0Q=RTnOmE=?gv>rVboa+9fwRIpc z?$iG+>~90dA{fjvghGeD2NB+N4Ka-C;8qu1}$>EzQfVwZdaqc<_S8}x-rm}Qx&^VBkWc%v>q z1au>$CWTqbL8mq6*4K188M=33m}O|XE}zZhqnmX46wr5PgjtSG)9D$E-p=UMZ#id% zS?%+l{3ogT&HqndSk0_a9?KNx0dsn^Tj{FY8nG>E{WMDfnn9<%=pxbtYS+>2R z>);tZ?Hyg7_Wd#f&@&l54fJ`hhgqI_OP7yk^7|P*3-pS2!YnVn&-}yae2cDsF6eVU z472?5g-#D=^m<08{qWD)bQ&(Xj;HnVH8Q&1?1_T!!L)~2T0y7w#qHPiUrg65Of%8L z8J+h3ua4{b9#IR^U&H9*K;O%UTb#1a)5z!t8J)JF8g1bgZ=z0L%jiuX>-lRxNMZS> zjtjR`8uopn(+fcR8Q+esEYRi4nf!J}r)~F}7KB?KF45_QjDCdCX%C0!yBBt+A7ymf z`>87rw^UuL)6(oY9AWrqgB6 zkJW^Cwy!8g-_Gcsx{uM5Kp*gTorX&-(EYKB(P`}1@JAQD7V^}7_J67CC*B(Z z(D^TP`e@K!G0_{Cd>fNb1^pw?e>$P(QOWE}`bw8~fSwT2tFwPbRO_Eo8T~xOxAf{| z`J<1{Q^Mp+7=1YCBcgg)a?jG~*^Iu2(djwWvuF3Rv=7wjDx+7n>G@9u{m;R@EPICO z^cY4j{932a2E95?r{Piy2KpzUk7D$GjJ}=GMbIzz z^s)>}(B;D!ef2kb{&Ar1OX|x1=oY>Gv@m)e=$5oz7I&)7v!Btkzt!bOf&S7}y)6I8 z(&_scy^7K8pnsL!%hHjn(;FDQjnV13=H&cdmXrlLeKn)6KBVi<2K~bFUY6v=I(-$R zA7u2)K(AZb%W`YAPA_5f6F|T9Hl2n`E|<}xzt`#X+_0gxi=M&g)kkzXHJsBP z=w&$oAo*-YU&HA1gQCwK?2>4|@3}&=>6PW%>9G zou0(#u|Mi`TH6?5*ZaLJD(G~7SG4Q&$+-S!NQ9*(Tpu50Cf~^D!$AKeBEqsJN~c>G zea$~~`B|WsMn_oAyg;WP->kRKBaEI2dOhfe2kG=SMz{Q|%hPl8HwQ;p=8n+mdl)^I z(JuwP-=z_j4WdqOVDv^t4+VXbHNtYjqtojcz3HF2{wqO0m=IwZHb$qfVf21Sb^2J) zA5V_3T$QHNs~J6-(dqf~l<5(c{UtiR3Uu;m6Qd8t^&g8PEZdgrbVRlK+r#L|h(EES zi&nw(A7}I&(D$#5=o~-t8J+({w{IrsAF{a%F1bub&tP;H(jL4k!cq+&x{uK}Gx`-s zTYq;~{yd{MFnVtiV&Q_d5tb;>wf_G%J^vY?-SJ$6sDUqbr~{f<8Z5m(OPMtN+yX`#^67O}JF2`xw3MFP+YVzBjJ7<=l}vU19Vl(9Qep zvvYE1;RV0qIcziDOv^KVDj$GG?bC2l6WXW$EP!sLm@j37d5%;0rQ#7HTwrI)e1q<+cS&w{@mKNnKD44@u@J#_v0C~KbnNVDjNfdK_ z>5EF|=FG`U5|et$FdAOn=}Dtkb`o>o8~yQDH=W(>=_#A4+oBNy*wQ1N@}fjDuhyot zm-#d+ddPIqHBvWOynRwa?+zH=H0$mBv3`KMK^+*)yPH0wYcHCRBmM2{YJ2qlc28Tn z=u?+H0_f0m2e`)q*$=jp z+s<^*Z{OmQVI*Yd??`; zojibQS;nt6LbMtv*Z7K%YoW;_J#D1ldB;K~75wuwZt`Xcw^S?PJiHZ5R`g7Z;RMu# z18)&u&WXrh!2cN3$5Q-1nb+|CJQUVRspSPn!LxIsV`E53Ai0v_oYmgim1$DZ#ze|RFiQQnKZBfPR#^(J{I zdZ&2vybHb8cyIRJ?OpHP;{CgKm-k)or{3?pztGJbgI|*ah45$a{rRE1z`OYrehQz% zFW{H*H}H4x5Au)m&-1VFd-;#~ulaxQfAW2V^Mt{|<$^;PEld(-2nE6-VTEw3aG&s~ z@Qm=X@P_b#@P+V$@Vn4UJX^d-93fi8cyWR_P0SM)ir0uYi+79b#Vz9B#a-gN;-}(w z;xA%|bcWPl8Y&5rTS}3pNIB91X{mIBbcghy^tklA^oq1s`dIo}`iJzV)JHx~9x7iZ zyXCR+E%M#+1M;i#>+;9)=kgzNn6;0!zg4!rWKC9XQdTQ%O1NXPW16GQVRQYRHWkoO zs6gTJIr13CI_J~QkuJ9@!9Bs9?#^=0b{Du8y9atikHeGb8Rwbg8SI_xt@1wQJxIRt z>CYm^@zdd-e10%3($n;@`DL+PJSN_+w7afU=c!fdeUwSI{=2Mu_|1GC@uFgf17+It z?YG*Ww|{LvX5Z|1*OBGC*||dPkNhw5Iw_wjy$w7qyb51lB(4x|6!(b-;H7irW46=n zd+hJopKxq*#JiGR6J1xjX1H=)^IfH`rLHR1O|IKqce~cQHn^T}J>%Ny+UeTu+Uwfq z`o#66>pNGw>o?b5u3l=CdagP^y-fXDeZkx8<<{tSek-I&S5e2YPJc(`W?Q3@>L_zA zP#1chq6cF2dRaN)c455`YW);#^C#!9MC)cQ#t%BdjUna~EmW!LjE%KRGt2N8& zwa;+>)1BkF+q2Efwdg*)S-wYh+8S*uy^njjRz1JCFsEk#{D-)G;WvX(OGE14G%v0to#Y&m7L|Lv} zr>sOfyhXWPxl6fMc|dts*`Pe8JgGdbJg2;I=SjmPMY>D6(OK`_e+WO2 zAL4n*!_|jy`>_d^E$7Pla-m!zm&+A$rCcSilB?y_@*25Du9ery>*S4coxEADmmB1* z@^-mVZjzhjJ#ve@Pu?#dlw0LC`H*}>ZkLbB9rAIRvxZwEtx;BswXe0GHQE|ujkON9 z##wpv6N*)}`m9OTWNWH5&6;7&M0?G)=34Wuh1L>lxwXPtX|1xZvQ}GHqixn$YprXo z>#Q5Cb=J++dTWDqt984z(b{Bfw(haESoc}?TMt@Wt!=n7j#%5RN39*!<5tcVZi}=< z*(|ocwtlu~TZ}E%Hry6x<887{LC@~9CE1c~skSs*hAq>UWy`kZ+VX9Mwh~*pt-@Am ztFo=KRohnE*4S!nwYIgkb+(PRI@@Mjy{*Bv)wUgXQIoCNw#U|D+h^NvJ7{aQwb>5Y zj@a65M{OOp<2KG7ZjZD_*)8_I_I~zgdyGBSKHMH>=k2mxv8#5UJ;|PIPqnAnGwhl6 zEPJ*+7d=#=y~JK_udr9ztL&@n)%Ml)HTD{NEyka9_Ko&B`(}H+y}`cKzTMtvZ?ZR| zS8B2Ev+uVbw71&Z?1$_}?CtiW_73}TJEw#zkxG%LDwIm4N?D~;qc2~h)F`#M8`mitl{#g!Qm-^9 zTb1ofqtc`_D|?g{WuLNNIjFRv*FU5jQQDQGN{4b>;T++PNJo^z;^^z>=ZJR1IAR^c z9dQocAv+X@>hL*|9LbJUN17wUk?F{CWIJ*l`Hn(IiKE<6;iz;}IaWEU9jhH{95s$w z$6Cia$3{n;W3!{)(cswX*zRa_G&!0bdmJr}eUAN(gN{~=HisNX9PN&yjt<9h2j>iT zMmnRM7H3~)KWDTv#u@7z?u>KtPT8qARj1FHPGuxT#%y$+#OPuA- z3TLIW%DKu}?Og3#qs|WJaVO^rcSX9QTozYfS3g&@E5;S;8t#g7@h;h=xKx+Vm4uNb)s^PT zaAmr(T-g{;@?C|l5?8sa!c~b;WtFSiwc54DRpY9~*s{*G(N*W#?5cM)V1(K3YIHTZ znq7NbEf{C^yAHZqU2U#It|J(2j=DNr$6cHnu0~?av8a93ermKDqsFSk)i{+`WmQpC z)u$$@$!e;are>&_YL=R<=BoK>p<1Grs}*V`M$=VlwYpkeqt>Xk>RNT3x>2oDH>>q( zgSu7St~RPoYO}gWZBh5B`_+SLtJQje(Z>QS{rJ+5-@aCf9T%58D?b@y{eyJOt3 z?&0n@H}96+id%L2+)3_acd9$ho#D>JD4gxib?3Va-6igFcZIvsUFBZou6D0>uR%Xp z>t5?#=icb9b8mLnyBpkF-P_%b?k0CL`neYOKKFk2L3gXW&3(vy1T(aw?hf~HH|GiW zM0%n;7EfPKKTotL#uMuq?uqm89@(RKRFBV-?vYXQQXiv)NPcY4B|IZ1*&Jnmo;(J)RcNKF@y7K~Jlv z&2z|e#MACM>gn(t_i)~DZzN`g7H?l~KX0@*25$ij_r`g7%n=pL5`CB_CVNx8Y2FNP zrZ>x*?alS(dkeiK-g0k+w-WQ8Ro-gvYVR6vjkngj*1OKT(Oc);?5+1Uc(;1DdmFt? zm__XIws`k>_hY8i>TUBL@*eTFdyjfMyvM!xBn}sgH5el5R_ z-^kZtZdK1W@LT!qd?Vk)H}iY=7R*8R^9T7>zKuV`AK}~iqkIQ{9Lth$AySAEEJ9zQ zpAap?2(iL&Ax_{0Sx^L3@CivmvXCmI2^m7BkR@abxkA2BD3l20LWNK%R0*quYGJjo zMyL^Lg|)&uVWUtdY!>Q;24SnPU1$`Vgl1un&?4*;_6rAvR-sKeBpeaig`+};a2$)G za4}Mh5-nn1v7Z<%#)z@va4}BgMOjotRrHBTVzQVjrimG1rkEvWV-}Jx7Gfq+E>?(@ zVwJc`tQJ>`Ys4C{R$MEt6E})=;%2d4Y!J7K+r>t)No*GPh%J~U?H3P z=~1ymJT7ulxD+WxNfxQE)K7|*Vx(AUxD+Sxl8n(>m3&f?lq{u6X;OxiDP>97Qm&LQ z6-p&ixl|!lN>$P-sajest&wV^T4}AcPTDBdNt>m5sX^K*ZI>FQCaGE4Beh8Tr2W!C zsa0x|4oOF(cIl|pAsv@EIb8P156jnDf47aq*m9=wHu~s%^s(&@u7y^e_->XwPQF#X zOWuuf{ILAHJk$EV)nnUbJ8X-#-)85P5sn1Mi;j;RBhg!Ka9-dV=DN{!iF=Xf2G6IS zuRWu@@tCi3ts&a__hbHhUKQq{-nIx9_^(z>l%AB{lz7Z1ZndS_=PSL`!)gWYUS!-J zqRll+;n9!9KQMP4Vim2EtXDghIqq=Ga4tX}e41;3%Ry@hE|iN3!MoSOK*5EUG8Zl6 zDb#P;$^5`RUC~K&{g7mtbmqa4YU%gpxea_;&b8~ z;%CV3B54$S{=BpkKHMX{D;XqZb*EzT#P$qvMo;)j((Sm+&5bGXDktBTsYZrQ-GC4y;*z7EhA~qGkOqMaVyD z>$51#uU@x)VV!8Z!Dg{vVgJsa2D|T9Hesah?XWr~VYGc5H5}o*$T`yau`|SVz?Gt2 zt0uT*&sg+~E3n$#hJNlB&pF;v=(P&GH=^(PfozEhLjZ|)G! z&7R5V3Gs10S|V|0@S$RV@lw>_O=3UPmrwdi3YB}y1LdvODYjyir_TPW{d3HH`eHV- z9CP=xFw?jjvxOHN?>kmu#QeV&YZmm|%SNM1NuXu}av#~~-ecMNytW6Bm~h+{g|4{u^#vjA(!V=fWxBH4X~d$;=lMm5oMpZ7uR zC_IW4+!pUM-sim^dk=fLv{0^rssQ^4@%(7)B~0KaVLxFSznI^}FGWuoCY~Xl4=dBr zvz4JoyH$Kt{8c<%x|6V-X{p`KlyIBIj)jHD%VZ;VDGrHgG>+XpBo)EKwVJJx%J_bTsfw9gXn67RL% z8!&?2<-Om#!;24>V*d)ipWuJx$B6@Qe+-c>kuH@+N}^`IP9pxJo0W=w0j5jf9pbN8O|-?6L6;tL!UKDltjDe zLQN%#W5w~}MAX<+^kB2ZIpRF@W5uYwCE{}NI`m~XiMOCPyGy)Rd_a5{z1m~qlj76p z+g=p6i95yD#Mi~Q#COE^#gD|V#UI4q#NMdwAsA(z#h%VzQkZ-edbj~{oGi*Nd5L@z zTI%2B599&XZD^%4Y**W^vu&~O#QK7EOwNW+#wwRNM>}UZ%bYhlcVVV`2Ii@|T<^O6 z;ga18+{@j6!+kRkebo=1KRwGZZ$ZK8^}eB)?}Z+Fnba4%M?YClSfgy`*)Fo>pe?Mica+}qqq*m*0(m@^1-8@+E> z&ELhp&cBWR?+5-uVF>06KMKj>-%uxaNL#RX^`&&7?2s4BXIV#DM_bpU?{2b6w)M7c zw%=_1(F^Xje_;>BDrvRywc>G<;=XHk9&rBbp$D*| z(t(+!h&?Lm6EnTHU~cvt_E$n_`-VPvBRn8%6W$ljL2b@NT|I>Q_yK+3Mc7?Sk@L{f z)2uVCZ)1HLYO~tBw(+(pwmWSP*VzsA18euMpH>{i`jzZ>hmJ+Lwl zdm;;zg~}pjsdA07Lb(m=v5y>K&Usjwyo8bEXJ?)3SJx!W-|thOQYH6z%$!fdjP-Qy z#oo~vn?tz@m^TdbyM>s^-N!$SIownH%ltQ(sr|u+31ygBJtq8J*eSdx92R~P&O=8bXwsM-Bgk8V&=m(;#6H$VN*88lFSwF&V)R)%pt^crwV5NPI?E>3Ctg<=# z1p8}tCym+dq1yO9O}q~+GZ%A_bL5X4pQA4rgw@vr&H-2t39d8L!RjU0O$yWYOCH6H z@-Xg)WMP!t*ESKW^L_Bj%~;Vs>iAPV+s)wwo*1Y;hc6TE6wbzM?x;9HuD4ngoAV9I zGbT*iFWJCPwKWG=pPg_Pp${6N#$(J~fDz$tjJYqXYcbx0X?@Dge7+DWTCLC8uT>({ z^I(}B>!fMw&FTm0eD`QirT1^%&oI~iiQ2a>O!I3Pe-@AZ8Q#l}=V$N*{Br&#`1n!& zMgBGZ1GLU|jE7;Ex1?cqn;=fY{k%Y2hS}q8ahddi6emxVS70|K5%Y_=*1N1@Y~yTK z*e2Vqv`x3ow9U3Hu~jNQR|R^ZS3HZo2Poe(y^Nw%CfzALBfTSkA^$9&gPoPnl+}(6 zj+Y#LoI{*W=LhPQ?nUmK-49}98>{uXVO$o(@8O^3-$%_a5(c3+*#;YmaR0BB_hDvu zzRT{q+I79_3inO!-dHiISRv(NMYP(p!SkZ$9nV*u-_WWCc_r@zZ;p2n`qy<>jX-Hh z7@lI__xr+d?AxrtZpl{LJGQTEy_F}NZ@Ze@pHhEUrQ1Ccd%25+^TkH=L@!$3upY2x z*%sMuwB3vSmEE?_ZO3f=>{k19`w3;I;|s??C$}bytAqGd;VJ90))%nPyuKP7o}tcHcdHj+#hQ(M z&1>Bcxi?__dC>iZJJRF!jQ8Az8JZO%Po|e!7e?FF+z7rDtC3%YzM?Aake10VJV7W@ zLa+y-V80_DdmA;_%h--Fz72a7na+=~fvvwhv&U-dOyed51)e6o*DJQ9-oBO-3-1I zEpiM0D*q8`Jw!NPxC|?=3BpXF81wWyghzzeh3}+4&_6Gd|Aw_fz5I&&p8OSd@_J$C zZj$vA>p!iL=&?oHSnQN7L`^+ld)4)+Yqh({^M&V3tZ7l`mN44p=UOBOcG0f2-EP}! z`w}~0=VHfeoPCi!g!XLIAJj8EgFFSEC(tK_(bhIM3cI6r%;>#BqA*q%FH98DvFm)5 zFbn(H^Mv`ZuuNDYEEld5Rth%>w+IqO#aPtxVP!6Mikcm7J3e;&fceGg&I_C)oL1*p zXSy@bx$vZQYj-8OrnqukWv=U7ceoyOJ?+}&deikDO4H#QrFyX=a+O-7Ua#Jx&c*)2 zo$hb2pD>>G%iF`W`3i^Ca~As07Jef3T}y@c#2c_G+k&;%k9bCMi9Foy#J=7t`*`dn zf2lUOuc!MC&tNO@eNo8@>Ct>Jyw zarH9nq|Cq!cBA_(cZ6r4Cm#1{ho{=R4LbzL6sPsj8t)H&fZ&8*S7O!lK2}N>i3wQg z-iUSVC*n=g672FW$369j?KHcpe4%V{U8Lq=*XL8U(*1zvL+op8@xJEeV#2ldU5K55 z+xTh1{dnH=mry0%BR-8a=P)@#en$QYd)$j{@7W^kiOOP>ClxLIbnJ&M)Sd%{YkU0% z_;@+ny2QHIHpcG5obX-jU~s;0tuH;!4;1v3bJuD)1J9)j!2c?Cdq2U`k7L&JY{P7l zZM1EYZ4TA|D{OR^Jc$+SM;O_|?WbdQE!qn(mX5|OG#4wg7nNm>4;*pMiOv#!F((=ow0(S6K)2E2cZ)=%#9{OF1Fa@o4?*YO_-3VQViY+Eq*_*wZ? z`9t{&tHlVc7teH@<2dF#(>2g_IeOjuTw7ePxIS=w?fL~zjLuVss#Y~ct)afNB%B^? zai8;hg$~hzT?7TY2HDspsFohZKEV6Z^YUElBldrNf2_A>0A@0Y*#FAYo->4V8PG3b z&*vNIgmf03_Ic!VJQKJ^zEgfoenUQhy@BKM8P65ciJGaRju&&rEe<}Zl8Ova+%{m?{;DxaIE<8v00Bz`e zJPG*0ewt!ap2f4ExA7F{L+3YmdX?;YK;`PgwK>FGJdOPu{{VKoUdAl*bH2CGD8FhS z=C}cSvD;nWy3SE0^cQ*98GTDFazE+Dr>XI@9^c5tY_}XcR&~NFcq)5X2$lLs=VJDK zuXLt-J67Zg)&WJ=TkN0Mi;@2zMTpB_?aAWK@=WRg~SqO>ER^(}t8zSMkP z)OVd->Pt&Kqy4u1cDbwfLcaP51{&_Dh3n_&9rW|`^V$9{(tFZJ`|3`5sUPm* zaxnkZ`Vf7%K1v^>U$2j+yH0|cxmCYIze~THpEyW$hDe=nnDZUgYfcHiF8fZ1!~@Hi zJFlRBeeR57hsgmEZ+1PY4L5%Z456QdNX&JOGETXj3H5~Xyz*Bi%(X+?r?s=*v%+Cy z-$YxFhbv8m7tIsDyVCOi`PnsH{Xw-n`#c@BZ7}b#aN5o010bF4))!X$fF76-xG(T! z@JI2pB!tNG?5JGo8tnQ~eT(g7C;#hCRv+tf*ymfUd%;L0^v|8v5$l4$5)e)=^mdWxCI&zTisTfjfs zp>$DtD;m4_9OV&ZhVvU|y?W4dFPMKA-|<8JT4NITeku2U3q1Ze;EnUlez5anKpi>e zL*_(B53HP(05S#aBZ0zvkXiD0xB@gsa2xH&k7tz<3z z`h(y;_TCVAuLVDIDO~Spo>-1;!^NjAzs=ZYeqs#- z7cCX%zad2G$PP|opz=qi*TpEOufZ7FVSn$0qkO}4Z2uqX9^oGC9_zjVPGq8cvU@69 zi=p18KBm5;ex@E)FY@?7M3X#oJ&$p$d3J(O1f&~4+;qVuE@cj~3mxsvtT?pTPu5&0q@%gU4 zI6FqUCh=2$|%yb=q+j<(N`Hcfp2u_UbdBh-d`W657vk3BlOYwSbc}y#k$N|WxZw13qHh8A1eFFO8CI1 zz^9+6@53n`^6c>@>QA%5eQ1JvNz(`}(k}O}wbb`vg>6=y;&~TD@}c(=@8@9B|L}g} z-RJ$@`=j@e_Xw2~s-3NM&@R;6+AUhOKLo|ESl_B2gx~0G7{;rjhsK0T+#>FflUaTz z75A*xliv5JZc{>KZ+RJ4%?qB{-bcLaQH6K21^0w)4?&SU7tQfXHuZ&iJ7)ZN^9mR$ z{>+3>*)zX(S#SU^`EE8oGi^zs5@YJFhg{F$(;1~sR_B1s)~K(kJKzuxs%Lw;p`lxz zp`LM`%h9c;cyH8S2#Bv^OAD2~^nlU{kHCfQWhev}QMEliANf1-jn~4URI-Kbvmyhx z1eXX#6HE~*=ks#2 z{!jh8bf2*hRkW*l4<|pynu1=q#yVZYTO6EyX%kR~d9X`W#&=upp-2Hd$EMGS? z^bEhssgBl%F_G)Uw=55pv*LE&D*RyG(CJ{}Wi7V;WCgk5HEe{PgHG7_n}YM$2KlG&Z~4|CD1A4;N)#wVQ3!^3ZUjp& zfWaxoMe#TK*C9_k91?x;L?nAB;&s@_7XB$th7hf*b{V|v7;UO{4=#i?aGP)AHP{Qr zXb&HCug|Ry2>d-TF!%(&X_)-hU6hB=|Bk?q_dwwr=v;+1chK1j9y7<)!#&CUC>-+# z>V=-Kwee^sHNNw36zN73cQ*_#A%9l{`1S`im!INAHps8MPr(lgM&HjCKLOQhvHwZ5 zs7iQ&AK5EnKq-SkBs19Li}aWEclBMU@8=jjU@;Qe@@_NkVYWUETKm9^18;=MSvX3$ zNtsR$tmY>@!`YP$R8+bHkILUYVcv`3<*tKud6=90HaGb!{2L}NjXPlEHo%9*`9}CY zq>i@fwdU}EO$oC#^K%y}4qPkqJokB)cvdkP)_b<%Njd1b*}IwF<7cmqw<8y<_i(G5 z<4x^b?VMkDGiDt3U3~95?2E>E6f0d5L+}-?`GxnP^KoCpOnshyzkWzRsymD>On@Nn zg6oXQY;Yy;r(0W<`h(^lsG8Gt_qE40^&Ww~XyU_K74f@4@E`v|*B*FWvo2z1YdP~X znW^6?2f6*{JJ&fkIpa}Q*TF;gfmwgfz1e*k6ZAQCv+D8$nC2B8KXd#C;eAR9lQ<&C zPJWef4ZgaO#t6^R5#cfkTeb-ary`+9I5k=|GXjNbORR4JYd+d;(QhB>!92)&U`_I(F@t1Vb zFJzAOV}|wDuR$RljhAE+E|MI5zW#{*IL?u0@QZBKKh?j~51@hcGA>2&Dls-2ZyNkH zs^-OL8}rQl>`k5FMlKE97?={6j?ds_)Q&TQ?SfrU{l*3-g8%Qp7a(q$Ei25{$iH<` zx+(n>KN?^XjM_ME_|(>2ufq-z$M@(TAR zwvis{RJNr#c)QlB>($Plk)Fw(PtbjPvOk;fHY2s`VWC%O&(L|^mh zAFc53g1t)Dr!(7%n3^T!j1NLUM_&$9f^}=vGFHkuVLaRsWF$Mt6d(r4xh!- zfe&y^>|swngjXUw*dBc|HrOZV!W}UnI5>DM?BY#$XdlM)AhAnMm~A`1^SSsK0^r!e zI2E$l7^2~hu5{k*obP-eC2qI#0Np0s)!ua;%&-duxIe1?^>|>XxNbwwp97X%jFP{M z4QQ?FC6tnKSlG8v?>~SCsRK=gxZAO-MWfUAboXTn`cdbHxJRPQ&!T1?cW1+cuS6GX zRzukEnyZlG|o!Dhow#~il>1rtyRZi} z?$6wN-QB5(J}?}2!U4XhmVvXjvqgWZn&>Cj;IgZiY=5fvad2)e7$<_>7>kQ-ly(DX zXBG3|b?q%}2bJ=b_MLWE3-@(oTHffJ=$nidcpHq+4Bu>2v3q^@qhUOR0=)`urYrni zs(!=_u|Bp&;J|rQ;KdDL5>w2jqt?M|MFhNonSptM#{!>IHJyT&2Coj@j25~cSGBD? z%vQ?(1uVvmFsO_vDACX3PC2YNoE@DPJNr5JxsIZMo#XDv+2*?McR#~#-4(vhqw4B) zY8qb0rJUrx7sk6TMTtGtjKpq0Vdt!Bm4B590*xfP>Fq9%L{Tr)&2!mG^1= z`5ou`9`vp7pP`4bOV8o%KZrl9PR}sztMk>6nxPTf-P7TB;@-0Oq+Ig8Mc#`#|JjrY&>-%3Y1fJfJ`+QIFQ2s{jO7#5r> z7*3n5E==wky_H3%L*?w^b+9(ge8XtxANYnk4DA%|+9F&yYjND1h1a4RKkZa_>StV= zsi7S0L#?}SmSqKO`&;JuL6E>aP(THEa5#RH@i1s#sYg|Z=L*kg&s1vtOHa7Bhc^J0 zE#Pav5C6XxWPUysH3zi09SgF#^V0j z?Yx0|o&a+F#vKRNny2Q2S(l^yJ@4ra`}P;`L^p8x3@Yzs&hI6Qw(9Ybt8~KXMT_`8NA^`oBlzO2fZm zi*ZO?v`7tjXW~{^3ASqDF24Y8U5`t#7fj0#{D$-NC-j+y3ZFFGECtK;rswAe{|evH z@-v7|->h8V>cDRLqk4z8h|co4|7*X^e9+ot{f$lf0z7RK0uSO*dk+P+5BkjQ!3S`Q z?PN|n7r+>zPdW%yxhVO=|-*h~f?eg>ze;Vqd8ihmYf?SQX8p3VYP zzbN>mR3_rv`aZaT0ZjK$bhydrm0y~}(T?|7=LRl;UzmiyZZb@l;9neaU$wDy3C{f; z_`|DlgS|tS?}vZE$(H_{X+2H6MW+7>l+w$GZr1>nRZB zE8cDN&M%m;KY=XUYu&WoY@R_BqHDDYY@jo>`O%^rW>=tF{`92Rp7AKj5k0uBKJ^Zd|~W@%i0HveNZ}4+nMdn&ZHkM zg3%TpRLwNZ{^me9-r>@HIsu)1s(G7vmwC7Joi4!(^|<+j`84Y628m&}puxRmzK;qk zyr#SHkbRF!>M+chaG7?px>y%lJ=lu+N`Gn4y22WaYi5)+MmkHU!13K_&9LTL^QEWs zF*vj*t!LoTHcB_?R%@H}F1P4oHe}%={T8MF5L{qLAY3{~yMfGl!DKiC9_byu3f*r+ zU^I?|@zOPVJBV#I(`jK~vGj|sLIqe$e&a<@oN$W1&7J%(@CnS|SJET;6CLKvU}*51 zU>gXD>X7xdZSy5RG{mx8ad zWeOMQj^IbA(mUZt_e%dKb(`go{DSa*wnLwe65?ErL+&cSzvIxMM&O`}Qlr)GYK$6- zk1n3Op{hRBgrOgx4pI|wMY2^Zeg;P1_0`w)C@jW9AoW1)oeI zq>w$x_k9R9`l`%6!A_t)a>-_z>s zZ{J=Jx8y63*dao^&%KjF5QUi%FWTLgE^-s-b& zaoH=saM+hhzx?*&Uitb~r+ibZPd?%lkNoKldEt*g=8iwz8((meGrj}{|AZ^P<|I%2 z_J5d{vj4-Z)P~k zTkepW!fz!L8h#_GWUFfVb0UAik*cTU*X+NMva;=WNX|FsH*zeszmcFjmdg=|8}YZR z)v+6h^h^@DnN+k4k&-DOA5$!oF=cSe;&z|7*|9S3axCeRia$W)TEx9A;=YRfN}Wuu z>}MYnIh9zrE0IbOd6Y~X+ai6^k~=Adtr97d7MF}2JR{O1B1e)4k`bwqmb^#-3Xn*L zh+Ie=SrCEA1R9G2feGxDj<+M5q-WmojAxNrMy|7l6i6c(&PbWrRApLo0J}^k*~}c7 z%FHK;SxN@8Ql>9!(KAH5gEfjn zzcpJ^kVznrY`oKXGVQp6j#ELlu|_hn&FDgrt?5OD#9|7&WhN=bY%&CeWD-kc8nJ=| zVgv5QCSRmX8mg@s!$ITUDWTd8n*F_>~HFaJ^owp>P8r>~*uCQ+mkefy_x#n3Unir5_-k_GWCYP&8 zD>su`&$!}4sw#Qq$3l+SRxTA zFjh8Iuz)HkA@SH`MM%sf9JyJXcRsnqGE#_p$Q(v-x^Xx`r;!|7z=l}NR#+_<=a_KY zYR(cKi5*boB-3DkipcI&klL%q0TKzj7t5I?Ne@5?X}W4osgW~^;e1rMjx@BpJkF$q zGpQrp*650YA5Wm)h`lL?6DTG>RYQ-lv)84PAn&iDR@N}%; zyOz;81e@H9uQU!PmPzV*0ja7Luu0|gi3V?Xcx4qQWitCo9{!GExw2=$(&FQ*tZz0TLWug zhog=rTbe+sG?&b15lmbKcd(i}Xd??6CEo@~WuKo#wsQskj$+uka?WUv@a!u5o$Ab# zcupvhnIb%v1>CaL+_GwTSQ{D2cn-FCRg!&+U_!)mbJCd&xy*(#68^PP z@33=<3ezBgTaw8+&SDniaZAK`7L&>^gBPqKf8WG3h~-R^@F%2`qR(Rnlya(-oN6Pz zKZf3~(EC$Kyl2w)3pm}?oNl%3_xrU-5=1d%)m4(|Y3QK~==3XaA61Yxucpt})9D+@ zt=UPJM{(k@q-&DMkf)Iz&x2_!rNeKh$Jf%`?IggXP)TFCsVWsPh>Uj@`R-h9YZa+& zabNAEw4+F9$H_`aWkbu9^^i+nUrO>?^mS1e6|ltnL3ZLc$J5ml$n0g3kX}khUrjHs zhMB4-0o{nR%nm0NEpPH5>SP*qQYgE4DY?gbdUzCxP5VrfU~)$4jZ6?cDN4k@rmq7ja6tgGAA_W6Aic zNuf zh58;(WhK*rGjJy?rJ~AZH95c)qDKq@RZQb$h6TLCP=Xp$3z|5+qB2kn@{dNxW__jcmXQUNP8C9X0YoK@43zk;=)&k-q>>ehHOR2Y(=HCWaRR62Su5r2h-i zHY@2FwR8;!wUS7VQ`ATiyLtucb3JttNy!^qbHfhn>0hLgN5>P7>00qD;PNVe&3SB5y*Z;v&lgxy=H*<#9GE=;y_p zP#LOoCE7PZ7C{E0hW_bV?TME=U_2Pb%vY-Gy4THuU|qh5sZY`azsZF^Gc+(MK)g~^P^=dKVEj31RR-S?@0l5q{|$B zw#?w?G06&K`d(!3OJ(j}r0#3vF4O={Y;uXLeFRB+G38=GiwSZkN|BlRO!lH2$?z7) z41F=%QK{UIDrII~B<7oBT3#^M(UP@}hqLxczB-Y9l_HtyO!+d7*qI9Cn>fXEuu}ON zP9>AFhHh35u56;C+2!ju(e$-gI-4RV=K%TQO^ST&CX;TfRCYwy*+ba*=#(rc~a_N_azkz) z>)Rw>ml1oJnA8G|Dd4dLUX)3s&!)(?WHRNBmcuJDd99mTF*vPUPVp*~+&VeOo9Mz~ zjz{uFObnAep1m!B4v;M8x#$1_%jL)(kk4!{lwCmJx^meEYUH~w4Pd+`v{bu%?qzp#{TPV8~< zV8JwYx1}KW3TAvW7|>)(%c6r9v6y^kUZ7U3y z8L3FQQDwjx6mqi~6gv}m5V&puh_0Nw5yP|)6ehw z`~COhMRw=Torg2$oH=vmoHMgU-&t#O*lac@{!G(m+kkKS=jWf_{LzEg!^gfh-1c(n zu1h!AL%S}Wwdi|GJ&Tt-bl;M@zV9i$>%j*f3VXhLk7r5bLC^Od^e8iCdcObA-S=Fb zo<7uTHT|;>pTBI+s_l#8f1PG<@m@S{zv!;TU-9pSi=XA+vlbu5cc*#B;)D3!vuelU zT%Lc=;@|P_TNiim?_%qF4*$OGd!>u0?SUgH4%lpW|9FV)`OBBgh`;N$jq?mk8fvpW zGR$TRC-H3Way+|vvdT_hl*X%M`oO>Vw=HM5Kq7zbM^RBJ{&nuN$Z5z=x0Rqy$eV6k zP7T_I+nykTtWUSi3-S!{;T~@DNH*KTKMb>t>686GCZ8E*dtu1em%2K9&+;%{Z($fS zflOm3X6W0a`#=~yKJ`1Utnlx)Akg;*W$a+KR?*!YEjHq{2*TV(`~k!@jU_G zeg64vwuY-0i-LTN7%MOL@HyrDS1(z*q!e{IPJkN@Tf<=G?s?!L6zs`FVc^Pk5x%#c zQ?3BH|Np-}7*Mr&UYDwcz3w?`^dpb{qqMW8sj^dA^^4#(rftAy@-z7GHCCkQ)eE~# zQ(MJf@z2~7wGEQmEV2~Vz>8|D){6>5v^A7cnWQk0(&xBTW)Ebyn#Gx+(x>^`Qr?ov z=6Q2M*`0D-*oQJRHgVbLUR~Oad+XES0vY+K3hon`xSrDoaw?0hMhx*VfTH zHcX4Y%zLz(#qQ{H3&$ci`rIP%^#FZoQ5sT9^bLGg@;XiTwnXoyS2pT#Zqv??7V>&R zn&QpWW_jH+XWu?Yo+ZzgZwE&~0A$&fD zBI~n32@E8MN-4~UIRd%If~-ZUe}k7RD&0m3fj~ z)R^HC#R4i72@X|;EWrBmE7J@yY6N{)@ByE)xeWjo)I04#vw?Rq#S>1Qk{V79Of+Mu z{>d$2rySksqFy5|r0iyM%!}_N`NUQ`f9GV)Pe$KMacrTM8+#o3q-`#MV{QwY%>z(0 zO2D#sa999{3J7xw>Ze@WbsosBvKsF*XbL!Dk9nU!O3^&PRCO~+2jEL#Acl_a_*M40=q}OCig-88j&s|}RJ8}Zo;c^K)gO6) z8kHqaf-F{Zx2jr=*UfWIf!ZN<)VQo*DBiE3KBBvU;t?U%4Zb#SD`tkdORBpVz(>!T zQtg#USOp7o<#Jm{S1?=Hh$rQZ1{SXDEqi)c2kVs0+ZI=CcF;hJfJl9o*AryB!YRhy zESoKsY`pIuYJ=>kB@)QKe^jVeoBC3dw}?@T2HD$Y@!&1hiI$$^Ek#n;yRz@|$_-Yh z?09%VOtBi}EsEyQF58C|IYfXAKpAs*3*j++^Rm%+Z9`?TYVT(rN?q8hD9}s@i-Z4VEa~ZhQ;5G0Ezkz0FBjqOwN>(sOqjFW)p2 zn0v}gWC^ml{vf+w4YK#+tkxuCo~kF0dJW739@Fe6w%EhTMy^71YO+KX_%Y;l5kKar zEuaIsHHnpgO>mJ6UTbti5~^%^iN&0SYlt~ZOVG%4m+`Mcv=%J|tLn+W--tI_;UfGM z<8jJ{V-3A$D4YWCe_;0=W&jZMl1cYzskMOp>>xsB~YT_E5!iHF|nz`M2eI zJLcoaDfaO2DM{g>(Mr`;;hB;e84~~*hANu!vkhjWYHpErznv$L^RjF<1kJ{vxjph) zh@nZfw9#zL-5VGhhrhN>TKy*wtssBaZ#PJ*A4O6v-ExaQ$tBkhscDdE z4gl;acBy6`eJ4pZZTMz0fXRxB0K)mqp)2+?Po6x*I;C|7qD{$NH&GMlQN34sFn20@ z;I|t|(3vMQjLL^@w=?t15g;?jbZjH3WgjSAmc|4gDNCE>#Aqidd?u&#nrx zb_IjY3Sp7=$mXN#QLpPK=xd4{-3*hZ$F^CZNORlJ+i)qX5kMt>d}SJdL+4V>6qG(L zxu-gjpS~CQL6)MhRYX+uuogYw#niOp(!BI1E~8p^BtK8ziZr1cAYyn22%@!^cA_SY zfhHRsQI$9Bz8Z;JT-5U{-bTr{Li~GP`aJ$ULh;^BWzo%u2fPc>S#q{`5%MlVp5lE# z%2K=w@0BVQ?_zXS#4gYazr+|DiX{WFt*8mrz5=&I;>`goCQ2rMAALt(90hdqgsMe9*009L%M1PHj(h5kYeOs6eS zfRk_vFfz>(8$n+=v7wxT{5`F8#RUu;sb#7(S-`(Rb88WV%_B3hLaMCDP$5B<_=eh~ zte3srG_>liGzEK?s=4!_IAN|Tb^go&^YvNG*G|--`5I!Mh1e-+{PHJ&oL3<%iWOWj?E(OiO!a=qhcn`dak(K`rsTLaII&*CY+CzD(h?LcBu029o zi7MSdK{Mf03;YrVIj5Bn*Who$DXqNHTuU$&v4>nJ)gHa)aa(iXKD#1iHBebaDruyT z7JQ5dy!0COWaw{~asCuYQFa7Ncw_`U-wB+co~=l~JJ}|)T{8PTqz4|7vuC*E>@SLt zkuT}a;p~7c%^1s01=-ua&X&MK$!Jb0>dZbM=g)BBRi)F{BNg>zpJGLotT8+AOS6?| zT_0Fhr+C$7#p?$%1zx2Ymj{WJ)5}$Vl(Hhf0|!Q4g*eNK-tG0+jJDIJNm(tZPtX92 zcr$i1)54o!fl5F_iX0k)E}4b;9%D7Cq88QO&*oRgt5NU!t)>JJ&?Hcus)kV&+K(|4 zRb|Hlf06!x*M6@oJvhy;&97whA16KrD(M5L^v!=rx@G=D+Wg0>%I~vDwa;P&p>>I< z!J1?#YpH>cm7M`8tFV<8sDw7eS&Vp0)k?5~SnO7{<(VOEp=Y+rKEi@jtdjZyE;B;x zJ+N4(%0889IJfGvJBZhergg+-POrj#OtJ)=mRvHHcTo>BUkOR8T3a4BH)cw|6;~*5dh1(Py7QgIIrOc_9PcSk$F!f}SN; zAuVS~*EBBi@Z2=ydY5ES?gYvm+EPvRF!u*k%@I}e`d6JKs!r)sm2?&%EBez>^~_G} zdN@5Xf=>gvCqU3vMf(f&szBu)!y*N3!auC8zKb@XR^g<*temEGooB2&GI zs&sutqGF6!dTa|v`A^+IfFLEk7I~S-W3v~9wCkFGT!mb_qW!sszjb<1!YuX!;Ds%L zf2>78g>`NiTN}Go)rvY){T8=U7dfJ6kq_jPvBuNM+I)j;X*9+e>$3`U&*(-`1gc&O?OpA5pvuCHLT)mehAIntB^c-8+9)J zJ<3UQKal2PT8&tcCS~nF?b#?fj|Pu5Zr+=yK)TEv7su4R*4PZ>+^(Rpq7VwF-^-go z{drrc3SI_^dC`(q>ZVzw1JouJm_`dklgNagGGZF(12dd7sft57pJw4BNZ@1rF}J2h@{i z;te|pRTi&}X1qSpWDkQC+6^s_=0r=sZJyOXJ7By7W`Mf<*z$BRfAY`p6-!f@JO4Yb z@CY^9;0pR0BA?_o2t8kATVh`bU7y=Rs#myZuZ0mrMzG|q1?e_Tc9{)Y@3E&!<4>4q(@Cd z`XZ5TnSu0hk@iu3l1M*9=@VGVfrsZPeN?3PQ~F(zW;EWtB5hKBvq&FTk$z32ucY*! zMS3o!eb~Dnqi1bQI7l`yV z1lx5Y{T$_ACDIoZA$^HR@1XpVB5hK7h)Cy7NBZ;`KKAq}NdTZIO0_ zklrrR*He0vNZ(KCzl!u>O8>V=k0Ka;A=1+*y;`JSCm#5bNIyjR4~z731jB!c^c?E< zPLXC*<~EVuOl78u^l?g07U?Sq4_AxyA;RrAk)A>M=Zm!C7Nm!Y^fJmnORJ!s{zpoG zCenu~{h>&Yx)tezBAr5YcZ;--^0$ceCvZp@uZVOh<^MsXAE)%MMS2INe= zq=$>NkJ3pZ{Sc*3oD%#`>7ydOpVIG&^sw1T?-l8rDBUd5ODX-DNdJz~e-`P{G)I0T z((RQ0bEG$rrUH?d)#NAJlE0sAsf64G3u(pMkP!F2R=zkq{5weFJ)>!HV99MifY@Z` z{guA5x6nGlm!ZF)>D)uy+(Ra*+tkK?I*i6^X|3#}%}g;FWMNo8Zv`sGa#d`iiXmcW z;e{UZW*Hw(B+J>whpLC!LK-$%s(xO|nKYE3m*uw&wXMZ^8bDoIxS~gT$oT$BF0xhj z?W;LR>0>!apQ?>#9RxzM@oo-jtj;s4mOP5y>CWRw+9;`A{OMvE$2?e(pu#T%R{XGp zS$YH(@=MS*;F-?h8QsS;C-emFTT!tk%T!p<$qr&M3!u-tf^4~qr3P{jv1x9zF?&yT zW2khGxy9GPK9gp2*Pf`jNMY{=8{bQk9XnK(GS!~u4o0^)RdaWw+c6_UEp1bL2g@%4 z_LAi6eG1!)LW(`jg*D4bhA-%PewVCeGBwR?^BpLIk$$1mCTmbl$m4^dz_JIZNGBT1 zeh3;D!%oLO-RJ?q3=d&Q5Xesi@~TmfExOQ!zcl>0@t0x429WKi75-f~;MT^Hh|G7o zqF30W_d0E4>I0BFj7Q-D!Go+9+f{Z8hesuNuwjIev1Mw5|}*CqQmwxnTiCXLRcusfWA+%}nY)1VH(z$n%H z2?JxPzCC5>1lBEBYrB4gtPq>&+Hl{!_ud;|1!?k0qw#c7T>Ed#-s0;iyGLdPZhekj zK6xm6d-j%4=@zrm*UGx28Ak0fqT8-u;}OtpPmm=|wU4m{qYa?ju1L4+xDABctN7Z8 za3F1Vn*vpfB`NkXZWYuGnyry;&1YZgj9m!)kk-%FYt5%2Ylt>N(PXC>D@;jwgf+hy zH6L?`-RdF^I}l(ur^(S%_DWJwp23&`x@^K=x_nZ=*I0f{z*pcdPY#y0#zx_}%$d74 z<_?zLoDnQ-P#xIiC$WsWfX`9kk{vUhAmd)&!LlK;E}xCf0S*gw#btkz?EGqJhwQt} zUGA=JSV4N;XsYU53k#a>wzTq(d6V$aIkq!ro$MP`;glVPPG4vF5JfLAV-AIF5BOTk z*2%1qGbKnTblk7wN0K@04i{URsn#AMrG1#;{T6Y ztK63pddqe5H22SNOL?62MF0K#p%(M8W$4kQ9wpRXV!T&F%lw zF}2{g zdV;WeM_PG$ur!!~9M!Qyn^b4Hn#uWEB#22F+OjbBLN-)D0 zWdeNw6YQA}&A{dI7N5P+zsfb+qTX{|;N=CE1lrUKSGNIQBX>$fIh z#e(5C%PwrXyHHeNbJ6?*WN4Bonf&kf_h`O3S)n4Cp(_C6J)p5ZYjh$j!8Bx5Xp5OcGs%2->qq7j@*VO6#@iqE-vY9@bEVcTrbJ)M-wggL=o!>mKtg)Et&qjAIRZ{ zRkka{{$-3nk0Dy?yRqWk6k-i*e<-^J_%0t=RJ(VDb0QW4;8w18CZXe*SPazC=@1Q$ zpkq6_EUa_7O;```e`ll(c+G(&d^+4%yJ0uwHYxJYW#P}m_mB$PMxE_2zU_o$BQ_+& zFH+%H2JROF+kWn%xBT-1<(R%=kz5ZUX0U_#7nDO-wHpgha9KN?-1gM^KI1f^r10c6 zQ-~C!;DJo>*PI9^nNYvD%NWEaku+f8fd6H*6x++euZz}_tK;_Wad`#@5-p0z=D~vWJjAe zJyT}QC+~Mz`i*aU*-W&|C3LZnCR2|C)08^9;p{g_hI-9_*eV6AivGqRAW*h|y!=T^p- zW{|Ya3e|GY5d*SPpYep$8yL8VEU9bh@V(^hy0d|Iw8MI_TXF&?+!v3UgFPp~qi0 z#ihcx?AuxP5e6^;e>oV$q>z69BK8(Jp?(0?(ihwH+f7Wp8;V!}i+OQcc`iPobI7-pyn~HC)yIg`A zyCPYsKN%YnEZq@PB}Np>El;VX2PpAS7PU8(=XU-yQWOzW|6 zDs;f%zQVNfE~=$I5wA4CuGGEA%g9w{(<7O3)mK9!BOwlHu5g9trz9*f{U8(Nmw`lD zJ}Vxe5Qi$XOxOt2dnLK*ON83sb7;iJTN(+pD7tbD+%vn3Pk^b|`AU7r>*0B#<^0~3 z)Oy{b%~7_4Xfh>{ie} z1vg}Y=pOW(9{CROMR>GKuC{jLbFxy<`+CtY6{A3mX4P!t0Lb;nsJqA-g+0&NM1e5% zhV*5Nu$o^%P+WpN%GJb_m+_G`*6a=cCNbpLUkMC zn%S$zgKrM_e&CW;KMMq_r7P0Z(p%lW)8RshpHev^#8R{OtBw}PO(;bhgL+yu5jvH% zK>pAkvH=1n19oyq)#{t|G>x{9#@TU@K`Y&AOCu(mxdDrxO+EP`S7f2UJ_3-UD{1rF z1D%?UQfv2y5mi};rKgow-;C!4>t5NFC8X_bkk1RM>DhDX+Tvda?2if>Dqfg<`W7no&-v5z!sT0%G~ zLTng~b1+m4`({)ezf_Nn)|v(>znj*yR9YCC2U*j;N02N96z#@PAXZSI8_{Ee0vQ$s3>oDJ`_-2K`|$GT z682XPiv68CX`%ijK_~WMy?kZS0TU#}C#O}eglx)IkcwcMrW%){ZQ@GW%SB6JiNOvc zTAE>NDa?doVT*+*N@|+LiuvW|fera^_k#~_)-xp4(H^_N8f(iSV=V`ZfdR)aO|vgO z2hslntkRlVfY2Y_$i?3b@9hNdt^aRKohFdxYa!pc6U0^O?E!?A<;nFUAZD&rCU1cx z)BR6Rxp0|Nt};A&0VN$(M?H9jEiMI=HOAVcP1|K@Q$s98+GIx}H5euM@$S~e0wBXiQqiDA=CZS@4^mNhwP|^MXT>I;3 zoyt8FJ(C{Ji=G)8&W)b&l#LHxNh<5b)n}@J`Eoa=U&(k1vy3E1&n$=}H>V`U(wkEp zF;{bnE#_!Wv71e**;0LmyjEo|4V*~4Pi{Sf2lRDBn4X_&Cx(=Nt1IGUa#j;eg`OZQ zfHe2RQfMSCzb?dD6`wz?{9E{h(Md(v1sMo=9u#;rVI8z{>tGUD^KNspEzqrU8$$WA zE8@UIyj@{--XqP}10{G8+9nlv0%^e1ve=IzX9P7I-;5%Zp6rApE1Usr`(@UEiIwoz zyP&lkgdC4xvm(~u+P#&oxP#pAV0~14onqTH3JXmlCyCHATp_*4k1!Awx!Qac zAtQcc&*%J=TNE573c3d=_<|^yDGI)Kf>+BNq+lfq(oousM`<->%fO*V{w3u@DRZ~+ z*uUd@*;^2gLwnh)dw>o5bz~_JjdvLo4fbwP_J>mKcwmRvqL}!kgpgxJ9aDS+>B*}P z65|N`^fRJ!)L|?xDOBz zE`98Bda9ip-&6zr4>d1eV;1jQtkc5*f{u zfr$0m+pTft4BWB{o+4v8SPJHfh;zL?c1e(JH^zOIWCItKe*(^-=R5Hn?XgRbHCSpN zw`am~_JB9Dk4Z8o_mEuQ1)kv!6E*)1SA>=Vsg}0jh8-pzg&miDUy3bwttr*<0NDIH zU6EuqH7f=y#8i*UR2P%eFc%fyk@5%0-m%-b6=U#E-WCR}Zh>#b*!3v@WCo095r=&8 z9YPxHlXwil{k4$CuglWU8Ylt~;ou92gAEyjKtXTVhh(&}cv3E+?3&93%?3BodLZj?qurhqghnS4jGcv;%$F=@j+%QC5!=c;ZmtNTq ztjW@2jk0e~cmg_i`)d$Z7((3J&zcCz5@4_dkON3R2l6RY1r;nnNZfjG;6m7Q1ir;W z#AFxQamXNr4QC`nCi2ughjG$lGDI6;Q|^OJUx%b~y$`G5!^BRcutichL&b(cJ`i3b z-AOjzw(y;V^&Q3`xDUX}R}EV9W)vlclDfdb?-&EbRF zj4Hi@%OfoN`3MvCs)WABet>oA6bXCilb0YA&1H=EggV@9}`dUx8fo6LwP(5Rm!} zYS3q3h73mYY>|WH^*JBrAeZshF~Z#rFzef-({oB`*{~}`D`i$Xe%IPzP zb-Z4mGbr&fz%P*rw*YMviC_L#8^x)gVH%aL#NLc=7W>#6v2V8aW_h$>6e55@%u)JgnJCGffq7j)XIKuIyR&} z`9XYRDM92U7C-a6S`>^S-sB4EY&snnv=%RN9ZNM&0P9sNGvQX_!H@_)Y%a`%8HJx_ zHBCwB$vu(%6@6Mzjf0=C961qyfVKuJqXG)fw&2+Q;v4(ke+0GZF3XnM&pjK|=6X1X zB`=_mS`99q8 zor_fMDc;L#G_~l>-~K^w$lHO3mk;CN-j=C;8-~5+89?(_yKz08o?gf2MQ=u4-SQRo@!SzGtK_<9jv+PatN zp=DJjN|6Of(SApg;og>2TnN}v>k2%h7AZj5x(0kAubXOV>w56DF$dL*oHXDO_!|oz zxBZAH1$rz3Z5Dd)4Z1AK)D~qC(zdDEs#er{Jqz_P@)N^EO`N7o{}@40gVc;y>!4my zrKwMq_rJMHr&VPwRnfow4wVL&=c!uGK=|Ul9I>j*w|e=evIdpaHq$%=I&6d~S|5eU z9TG&i8KIaa-CPpMafSI;i@S z1ny=IZq#R^7(!@=JPs$?1UTCxMqf=J5hoVcz1e5yG=ciV7`z4~e^slI4@DzF?dBS{ zrAqu~?ZD_GfH}7vu`e})F2p!Ra0sBWI}AlfAY3-x38gW_s%fNhbU6Yk?uLD3A^eFM z<=+Wn2Z>ZBIT^Rauut-jfj{Aike=2UjON?I`GdSfs3Q)>LSqOqTWo~PRA&+MyNH;! zeMg3MkS+2kEgod&=^ZDJXXNL+sz0hiQNHgb6SmlBRj);!0uvA{pQf*)axo6HbBN70 z27I!(Gep_1}sg0w}H;ERRIdbz_@V~BojwLVDEaLOdQDr7sA!Nq;-z7d z*A^An+bD0uE=sbQEqh{-H-k_Cu&uC0%$e#x8*_w@8D6|W$2{Cmj>&UJTf|DU#E1tQ zC*5a32Cw*7Hxl3>)`dv`Gt-?|J`m=lmUcp&sXKzP`4(iBWA?)srl%c|3Vbb=Vd#lifp5!$4<_2| z_B~A%%Jx{ROQJVA+0VC#^H8j-s%zAnWXA5@$9YH@z<5XmW0}f=KE*nW1KduGZLhDz zGG4+mG&tU%Ho%}qEgVJl5KzJK!mscs&f$hy)??J6LAD>qB(VX;z6Tik#Q|W*LpvKh z==6{pNx?k~zI|nf6HBDu2V`I@lCocz?fb-MW4#pX2;X}5kwu(maJ>p=basTuNwVl5 z;tC<5z*l$4u+h%TUzQQMn9a#hvbR83V1`sk@awzejW+mnjA<~W^pQ6iPxg^F8P#ke z?g|Mnx8%xzmx?xy-eNrsz_yJUk4ZuL_ql6SVr|mqZ=iXiX!pFKMH+&7QBPl4O@bq_ zM%_8NclyxvBXbk-f+i3yn&Gmd-x@z2W4@fP@nhpl`1V+;wZ50OQlviwTOCVk+CXEc zH7-GGY$0g>N;tM|F!IRk6pVn7Ex;!1r)C5uKWiJA$BgQKnTWs-vRW=pNDeJN8#PT_ zz0q(M+!X4GIil^R%>EH7H3Pm6C7lfaK$T0MZr5+MBhaJ-(rZW3mYlzl`eNHIYg8^fAp4r6ry8(Xz9LBdUEn)hHj3J%N_1sQ9#vVI z3hPOU?0dKD5xOI1pYoxHf#80%x z;~?XDoT{&I>ED5HNWqebR#vZ>*;ue?zyi3= zGFYNhOh~SFvKQnrxO0wFzfYK`JyzMs>n%wWp>MB|lrW+@OkXULu3e(t>BRYuuBEhK zQD`RusmVsR5axA-y|1ut84RWW29N+J2x_A)_7PIy;*bR&;+#fZH3|^b7R%LN5r3C0 z0w<&|#W{TuY$gM7TuvE7&@$SLq_S9moeb#rK}o9^YgLP!PlKCDy~GD6`?giWVU5Wacu@@8rjqYqs633$BnYCcfnE}RcQA?o)sgajI8 zP_0t1a9H(XJELdNqO9L(hYdx0*a@47OS>}-OqA6p46fh(ReT?6#p+H;2mrUd5!ABD z*^LmfFtE&k1J78uj~2s-n}9%$@iaXT4dXhpHn|>ZSg(0CE_dQ{D6uin(5O)f`yS?Z z$_5BiTdacpI0K0r=rn(%fR+(BVian+YRUZ9smPS>B`L3i;I`P%jShM~A{AoiOJ|0# z)VcLEpRcvTncWi0#q_xbW`HX~>~>ndsHM|;VeUcM`VQIr3CXe(oueC0cA5>bWWK#Q zXR5_vPv{kWWo8ll66D{*bi-MzO$1c!-ioW?2~m9SmR}LjZ#E%sAX@hr)#zAyr6anf zDth{+Wy55%DZuu??p*nn9QArJ>GtAa4Z`JR&FPg{hL`FYAyKLN^yg@~^5N>!-S{pa zQ+@gfzROZJ(ePvG)u*@6(lJ9@95La z*lfWYAZd{87aVd2(G_mBMfmd=WBQE-F@%UArCYuh3BT#J5Jcd#G-ywYD6)74>Ih8^ z^8XwkC!5b9o0$dpSO;za!3^~Egm<&U726Rb=?SqS8}21TC?R{>_)Q17`*smqJxXjv z3{6*$eNoxzJ6!$?DoaYkZezuOg5bZllLvI=LOY~h&4ZW=m8q<=Y5l7nW35I+=qdo8w*9$BZBpca}k+41oJ-?R9tMVj8nrnqb&E)Le=u zfyP@=0CSq1fkBFtgc4&x?o^Wpapp7Y%Jg0q4?gfB*Jl+P&T%E090^ZA7CxnP0=Iv>>lDd zCp#lp#4oJe6#_URj2noJhAF@C#BwfIIHUPktO4+PM?a6sXAS~WNg*xv$2ts!rP}G z9!hVARh|BF*$^)8nh;XfM=yj@L1!bm?hUTO9X&!Dyt@*HqlT_lkOpcVb~B%-rA-C( z86K>p-U4Zp;xVH=9vsr?NsSDbHf^DYA$X7iXR1!iQb9}>T*rbCOZoTs>zFv{B6enF)EDRUr zZzNNCB+yb#-}rCK-zY4q>?C&Kgi}5{68kxTMHW?;2`?A+bFT}Fs>!%T{#?Bd_Tat| z=(wio0IV@Is$94x3^K&fwm*_Gv7u`P?+o)ElOB^B>NA+`YADQ=?~(oddW<>$b+Z3Q z_O?Xn8~<(oyp;>3+G~+)32b(|VC|1IDcbj2wDKLQR^E=k{n)c?#;%{zhqdy5W1n&o z`xN{YrQp?Jw2j9Lj6Z&h#wyGU{xmYo;y_E_Rk-`|qgB*XeG7s;n(J^sR-h8t^G7a3 z6jLPyoV;!PdI#Mw+EX8>#Cvkmn*qcqx&hr?;h|)D++iG^K<&d_1;0CqvhK1GuZ3Ce!0zq*2I8lAko&5G%hW$IX(n6 zExYJdvrQ|4*0+PBfX0mR^1*HbFeW1;as(pu2dZ5MMu|(-h&p}rsrY9b0f@E$?}=zoGq9y>(jqO| z{2d|f`ykZ(K17>;Serix(c1YqPGl2OR}skAK-b~+u=%gj2KtN^_=HVcp1-OJZ=}Zp z8_;9q!Mp``h3AmPjD2WK`YaU+c@NH@pC4p!3AC!&9rezkb#@-Dx-)WIVfQ>l7odrQ zTX3mCR?omGyLQ;5a`)1H(|D`}Qm}shs|q?Moe@6ABDM{xvvC#pA#eVMutZ&Q252|l zy$V3CB2rt!m3>j+L_F<>I`Cl-m@ z&mr+4bZ4$1j1#s6g}Z?bP?%`em%@X@()dYos_+71_a%%kNRd7Y_U%?!dk6u79me~h z?pg@BG@YRSktjMIp9pS1jcgOeZo&h}64SC=Okmy9lovcPN0?7iodzJj366jKG z2IOQwzcWeEen}Zh-b}F0DJ(6RnB>G)>Siw#6BO|Wu+rWJY8TTv%cRIqD4|23gOVS= zbR|k-fog{#wi2%!lW;k%o>7St>U2Fq1w0W)GXvR8!R#Fc(J4cdB1h%y9z~m7Qfo@9 ze}L|+c@<)%izwzP4=BVQW;r4`&^kqUQHH8d@&~fdAU5K2XCQyf=aC}t4fJ2-b2o~3 zJYaQVq#!cjWt`=mAi0rEDR^WNNQF5}cK-F0?WYUUa_|JJN>M}C8Z-~MKX*jLMHL=w z5~<%T>X$bYLNhsNMdkNMShaDISu{2tp>xuB90ZP0Pkmq_nfX7!R0Sxi`oZ)JU|LI3 zErR|D1t1wkN@xXvP!Ol{#4sexM|h zj>5RevW@OX?n>jtgK5G8?0Wkk3ehhd>wSm^YH+pywqQ`EI636_0SNeF_7T3$6yd5+ zBJKD9?uoe)Ok7kVMvMzEw4#y#cJ97*>5(;b~>@a?DMO<#< za3IO-MZhR#G|iyCGg|0C|I=Li;3UnpHYK001X8V=&$Zhz*ZAa9@}^_1Az)j~HBhz= z7~+dz|GCzh6dC5587{|U!;xe@*{o^Skc3!SJq^?BpAO&3a5dgwL_Gfpg5?e~yI`WD5Q7=a_$xIR>(V3;uU=%-?^G4GPmY%&`%d z$LAOw)VAhWT5IIOLFUk3wql}PBI1OVd}nK9bpMHXfaVxim5K27LNUqcbX(|ir=@;0 zN;4Y83=6RE=gy6OFkv7cn6{>wjAxo=&d)a#5Pw?J3>QZCnP#jwjRh9U+54qe8szK_ zxN8~|OgAmCP@zedMw1LXnZz7(T61hdLOLnPAz3BFWkTrkStq1r-{~bLU0iJP$ri9d zN_881FB9{O`}Aep&kQpLn2zQd`?`5H5p{%q^q}Hjryz zJD@P%4;x@z@Wl@M zCJ`Y#egj1&ZaO-=8}|?8;v&=1^?(m|JwJ~O zC2uvw<+e9+H6H^3qSr$+7}xUtXyd9Le# z0@dB^*Kaf<_D{5iIuYnFePEEiyqZJPi}YUDho6Gd24AI6B~Pe~6?hS~GF zcmuRm=_$VwMk}+awxQCA(Bboh`IK;pGuw^E4Ig8*>OrV|*{{i{pb|$F3-02MMC;aq zbNA&mE^rK33FyS_J$9qwBfcWZabq`}a`z((J9OBp%CF<(GnQ#Q3*wXq-CBEC>D3(5ErjXin1ZJ;H?x50EMVHJ7uwAh zK8QoO{)StoF}G<5A7JQUqOZ!H?HvML!C}Rj^AK;kfFt1tv+Ny$U%IC2A)6ghyg`x^ z2aVT`r`mGc5W)`EG@Zw~M*+s+Q>k|Vl_h{A4G_8Hx}+jUM{Kg}>y8YOo0HOG?&#U1 za0(^y0$)S%Rpm>MT%h{)FU7XA&|Z}{G?E&mqxhXc2ZDfGgAPilzV;=*Nr*c?s@ekC zuo_~6J{ufML=l7l9mKX0fD7#w6O?Yg=|>tNZZx$+99mN97Iz|ozrz>~XYpDJs-KFz zH3Udp{4PwVl7m$}9oQKtZ|H7af!=$2Z4TQg`ma2M~y+%gB@YTnN(^J+U|HV$n&mat8Y3Xl+1Jz0r-i3Kx z&*BJMe6E&x-E<>JX0OAVyQ+XYNu$dH5ofk~Hk5jWJxPd@HxcT{uSc#aCtwZu-i;6@ zNAtlvlJ^W%YQuFx2dU~ss2b~lUvV|<4C3{6;x0p~mj;v~gn;N4OGAA{dPOu4FZi5Q za2N_&jw}oNydN1i?bZ^>sI$uLT`wZZDSbcc2~d^%R|#&bt2cO8H;JyE=WP(;x!>)2 z)QOk=+WxjirjR3$Vw+}g>se=6Lu|a&!WXahwm>NH^he2vfi)qgAVcY1@_wrncLBxy zqCh0`>kdk?9&V%&EGlIZ{T3PD2NUV2Pb;Lz_P-C)R)P8 z+c4P%&>U{q!SoAIj-LtR>mc`GK&ya33HG0dIbZJkTR$O?4z^AW(0y0zVC-VRC-b8q zm@k`Cr}<0t(aAS_uE=dnIDgjcz~u~&*(>l?*I_wEtIr4t4j z@pHMyshY?Gv#=$+y2~G=t6s=%a#8<&IpB&u1Ay-lfb&TVz~f--A;3>NB0{XaZ5(*H z-^lv_{)h$mo^bMJa5DHKF80Zj!vROs_3vj!?U-QvrI`Y}h49S-6|1_3~Exb%%5rJ^6b z0mNh>#CF+FP6$|{#1DDo)CV5IQx;t{=7D`0VY|4f9}#)3u1iy}uK2Js|8pc)riw7`2JOcTz|OckQ8WyXs($)1iy2n zJFkb4@Yf9lF3kH^u>Ih%n+yAP$>IY(WW6ww6M?LKlUNIY0J8wucA>0k_k| zom$}W+`Sz1Edr^(YOKeJc>;eso!MFs_5%AOMmo0vj0Ni?u7j=LUKjG-8e-pnJfM%c zQSr_5&XaVyDg$9gl70+{=Dg z1Cny8Pm8qA7dX(L&Q5HNu$zF`ERRG)pAI3M#BR}mF7E6Imp zyGF#G>UbMyJ#4)EVJZa@Jl04jCU{e-O$HTXE_zdsQZ=|N?EBHM zH-sOZfvXbcwsU#ti_@HkrU~SRQ)P!qEFQxpx;Va`V5=WuN`VV+Ach*q|!CESGqr-FV^y!5a+(GVzAuID=@B+5%z+C$5OS zwWdL^0_gL&;_Dfd6^{0BR><#9`Kot0<*yk`m{^#DciK=hjP(grrlCA-e0oWo%JU&Tnz;06=F;P*2B&f^F^45O)NJ@w)Q`zk@({*DX2jW1a|;?$aeb`sMA^Epk=xZLIikn*NAv~na7153Q><$; zCeG^9xYDmsq5JfvhbRlzQrD;1 z>l^*!nq^%5l&{q9mQU!1@D!5MyM~SpLC5{`cnc%9`~tlrdpn1p_n5HhkOXj zqkJ=!@>m}%aU{#*8vT=-!_x(Zm7%+-`Uv3nQcen7#ziR3pt=Jw93Wj-VZWq)ndlwY z8?r5MsNwD^ElT-8+^zD+Y%nbfhv)P;M79B^UV0Cb5dr8h8N8Z`HlHIO#IwjjG*Gkv zXfX&KeveA~##>9~j(i)`N=RiI7Cf zHCxkdHdw|QG@cJPhYd;)>CqF_{1P`^s1gqa$_iQgO$NbFM)oySl&&V}F!FI}U@RXu zhWMUtKxgF;a%(mq!B3&UCX)zUa*Kl~S=dri;1WMiTnW=K-}J=o!*P3LV!t*Rf2r)r z4)lNvgAtktpO&4%W%CO&$}eCu>6`{^IJlt++c_wp#&18hV=12Q@~z}2!ZJ1@$ft0O zqeaDuFgl?zcs>qiD83KFa}nf<$U|{B!-ffg(SPFsCmbNe;Xy=?_3%k%9p~bct?yZ` z2HI0tQ|#+bXY}r+t?}X(s!~|nmKV^FzjnNT>$clyOhdu)FxF&jz(F)VUOGm{b8v#A z@2<_?=Y(Z$1JI|3jcqnu21zHkqK!CzGRV=b_pq;l zs0O-hkk12oH69D7vfm#874cK4!P0KrgQ4W#lMycPMKa27z>4JZMFhP*1-$}e9L=0w zjiLN;;Y;|dknZh$g@?u>=Jf`nTXFW0HmsK%C9)$jxW{PeLb9~exR1WsE~UQHP(Gn# z+>(J4hCyw9CLzTi)QW6H+C8p7-F$aYE63E^#tn${)69vnz;@UNX>|Jl(`YQP@qd^4 zg^7$bZ#zepotOqEcL-%*4^R;?Fk0XZ{JnrbgqlDa6QgK>t>-Yx3%^(Scjo9E?Z7r9t+Hm&R8F zcV&<9G?HSE9iexm^KwGc?+4oHC#Q>ZvJY#K4V;+Te0Z?VB_?JI(Hoo9b4a=s9?kwF z73YTgEU&olqMG1=ikGiugcW`$>&BwN4_+7P8I8gGp}7C}+(X$g5n;P&lQyeK^z#hy zx%i*)%An5)GF2)`oiuq52(%}-vev} z#>U^$i9G&_vi$YvdPIm7Al{gKv(eM`$i>*EZ^F+(LUSF-9;bG3c?NI(O*Bt;Th3;I ztU=dzv9>1;+fS{`==r*(eK&{rDep5thb0?@TRTpZguPq%4iAw1^r*t3 zw5Za8hPzmzw63c8?nsInU5+blZo@B8M;qKSe%+*t?#{6;@Wtk1gPXePy~Ed!-6=#N zE$&c-S`qS!8;34bqnE;Ka2KRG{eE}ricexg;DCZZHFt0RPpRJu4?)4ZHMdA^rwhLz z>CC6nKK{P!J++ikLDhln?1c6{Ptm*E>B?Yn&%n#X2*RWSqzr-9;tEfo`%||PT6}A$blC^u(m8)05dzaH z+<1`Zbgf(Dq9AKC9E2c^ACA?y9@F(ZV34CR*wReGGsukK$s<9@4=-Y?@yT0+&~8HL zXu2SWwPIn;Q1P37+8q=>?KZcs_>`^&InFrH*x#G2fO#^EMM2-2baz5iEE%3#ENhKN z5Gg{ITgNKGjpVi+m!(P@;lY<67;2nUH>5V-T# zALVC-sY*o-KPybtlzJ?WgJ@`OOGD#$C`0JaI{pEclq^Wxk?Cz7C#Az-{K9AQf^ zCI8EbL$-dfzqS}5my6s&2H-l6cq3_}`P@iNRTp z7AQjaZNte01+Uc=o09)4DiFS$3eaYl6}#}eOlB)_$S}x@)hG=!WU|U`ik;8qWU9JO z(#QA>w`cyH#z*~c$p00`@=TSTQJGF?mN9X>_z1z_hzJ-DeoF;fv4mgTmRuAM>XF8W zyg4Xww|J5o*^tmw-)zqf%!RJai>S_q3Vrf)8tNGoX)6P zdYSafmZ~>gR4XZRKIM$S1;EDmJ!DF;tog9vV?xY5*Y75NpM(3|5C|o$UO;2iS9s(% zFe;mz{SSUF(CGOkZQgg+cNhcK#ir|+v zZNrffsiqDOI5tw28tqA!R{s!B^5kREj~+#$Ycf6rh~K8Z(d8&)?P%_81{L;0>K zG0H08rV{sBaNLq;;PYSb2Bc^nvZzRtRV14_x-3y{rzj^n8q3QJ=;#memOjR)sHIao zQ*E)A1r&PU>PH5vet*3BI;;9?DAlzDh!-tP@7uz-cFqR^gr@dN7Ih7w(q61CIC zyCqhQqoU1|PYUc6#BLB7A0k8A)Ieu;T+xP;(H`eAs|J4Unpk2RFVGr2g@gUkQ>kUi z(NpOa4%q>YitBmjMlU7oI_Ja+;c72va^$|>ZTuIS<|-R>HDV+JAiwKO}#*I{#?F8q(A>Irzn{XWbJ@M9qx75PRRr2JIr08lO6l`@2dy5Zu2u}Mw zG2Sj?j(DsY2{P;VLv-wh414bhLdsSt`Ui^;f3Zr@E%)pl-zSnzKa?W6`dhqkwNdg8DC-8I4Dt=-1rcq11gi->oV)njVB^!_eBRruHoMCqj? zspQYLb4C!u=QP@FTpDj~y9HA>FC^8xhG+7C1A$*XZVmFktui62%+K*`?%*NwK+ts@ zkcbb-b>L>q=9$s2JmJOBuZZ+trB~dGXsmn182=!eTsnu~`bxkxosac!tWXqLWfhr3 zMegJchGA6zbs-ZvPU(<#=;8^ zwPHuT(*b+b9U-zu1!wV02Qux7veGhAF7Pb~m67pq zIDTxxs<<15ENK&NwA~uHG=Lwk8ifT3gED^da|)OWrz1iv73avYy*pI-SDka}BnqE-0ownirOZFP!hH5097kPZUfrcYo&*>m4GA7P_` z`479Jz6VP18(%nVf<^9Avahys2axgB&)};BHUjwN`e;{HxCmDkVOJCF8Wo<5&!lh; zJ}(Ym!P8^#c}aLA_a``CS{WM$BXE}&Jp595?EIJJ#zww0KQ{cODY2n1-54A4QdTVK zrST#CK^JT^A?-zP9S}`M8{Abm?#FZh5=UCNPZ6!wV)gp}yNnD-B_VHl@3#DHOy)|Qf#2L0yoIJJI1OM}p@f73nF2>iB&0H#wlDL0PLJ8~s zx%fdNlo~IZX~O+ixMmwa4wg>8?gy3F)3y7jrinAA&{Gw7^l)Ve_KSmEI>C?gP>3*m zD+h2)6dNJpr#HMd;H>eJ^F{cfJnpO<-HFhh#(;Fohl+N$H;?lCC%) z|2f>;l=T~))s4Opcyo)(51+e7smInIbX3`6UKg5I;HyPXM>uKs8)s^5 ztWafwmmW%p0~SKUV3v~Gs+h>wfR{ny;TeoBS&ocU9I$v13{#}qFTr84WiopR1bvwo zWm6H>p8XX@oo7bo(*!<(2CDM!3>Uv{IA{bf@-v!{qm?(ZCS1MJ5WY^){|{~N9v@Y8 z?*Avu00DwKC@NO0QPMUxX-S3J#Gy4CXJDc;5RXKof^r(Goa3d4GlDjO!AT&K%>cIE z`l}aCFGqTMkyEN-Et;SvK~Mr(jkgwCTX)XrX{uI(wVm(#v-V6#u($Ka&zEGcS$pku zdDdFbdT#4^Lf9YfHEo))J% z2zvR?knAda1Y#X!m^&@%aN$#C#oE2OJ^RI8c4YEC?O!PMyg5@iJ$Y}HAck$LcD%07 zVEEfpWd9UL8!PMWov0lOl4oUO=Q@{_S&)S~i>-r}h8YS#P12I~fll zi^fv5YC?5hj>|>osP-VvX`c*aR=mcF>h}9ElL?)U@9=JReGkEApN@Yg)cSf{J{#_2 z#0Y$YsqY%pC}j}*np3mp1fAxc zeNLpUsv^=>6!g6o@;zDS`$guoIg4Y{=PX_Q@i|{!J$23%v64C0Vn)3pRx~Guss9b} zabCHQ@3*-`U|jRP`SxuFQs~a;79QgYLz@7Htwq+ZIm6ocEBX|1zH9n6x5Izd9G0-H6ArgZy?GR57#@tN^_fH4?B5MT8gvjb;X8)`tO z3W%ixG7s`@UqLAKNi3H%aIu$$*_M@a-Wvx#NIl*Xsj?ygz5JwB*l>KRk?-V*bFBNp z1Nj0?k}E0lh~X~x?lpcTMy_GShCs2sR4Sfj=9cTBaPot!3Gw}n3PODU@4XWh;v46^ z6@_6eijq2TrB_E0Ef{kT=PCCsHK^GG1+Y>v7(7KODXu+h?y`rl?Mk0CW!&LN-d|jU z37QtMyB%T5W@)z~730Is@tUzg%5TOKX~emb+}FHe%}^_8KYIE3CFi95Gk9XY0|lr- z$jnOA&4?tkNwxrn&WhYfAfXP8R6f2-%r)^9QU1%K|u!@Cbc@L~2|tJ|vk{ z&BZ0LYn+a9o%^@oGL}ht6gR8Zu*aL|JP;ki-G0 z2^S@^n@iZ^5$7Him5Y9yMtw_VDW}4?RG3DA5u#)#Z|lgk0@GpHpC`Lg$VrZWI_Vs$ zlUnjR+i5o)bx#@Y=n~^_b{;+CR5sob{(tD}VZI^PVaeM*il-5NC*Q2c-tnMEVKtU& zy3%9+qtdJgQumcBWh2RYFOs^hB$y%?L;6Ngb4%EUEJ-aaLZJEnYj~`FAGgy++?eQM zsiejSQ!CMHE-a^#8$RJ9MD2`3tKzB# z&YG4N_0$$)dQ#9+TXMS4K(ceHU9s=RUq(_7^^RxOQV%`HBba*V74Pw;m-(*u>qGD1 zFET}ny~kAVF`Y*^y}pXa!{|4ts!HwAZZVDV;c#QWrIjCgAMNlSojiV4t0IU7ZvTvr z4Vl_r$yyAyZ*LT0>Pd!qfWNXN>+{L<*ylq6WU`YSzUbuWfULE5a>JDJKNvDa9x31`^g=}S$n&?rpX^jDXEP0l9@8|0!rB6- z8JFM7QL&EwS%X%hHy7U~jeybIlXCwXzwX~ z#mI-#U;K5=B#4JdHPXvqwI3vqc2w5=_V)@4qQ2jsn+{%6fW&x=Q(VnugI}=Yw@>4J zPjWhc-=z))O*AzPw~Pl(5e8M6#P?O^Y%jCg%dGW&g}q0;_qduz7`7?3y_po>BzUB@ zw|YO?c~I*s-s5#;wr?Nw-o5K(7ECgq74cC2ih1%y2@ggyO^;NxK9c$zs~@y=9rrL0 z;H0j@ME1I>)OEFN2>uWAFG5Z|Ra^&gcjIF0g2Oj7fM^AEyzsPtB92QQl-<;PYe7R4j)G+V; zjUS43;3m{z>-)dO-+SEssh{+YACVO)1B1=LAdDps@Q}hvM>F2X@6+#spCHBD=YAY? z!k*fs&BWF^`BYPdd)Y1K^6sW-WV`=ctbIo{`mvM4M^%t6fDQ2;+V}jLss{lAgbk?9 z*;K>~x_f?LzEGMnCEjDI9<*x!b=r9#SI4A9is2RZq9M+_dCYsz@%>DSPIq9tps~mO zqIdXh>NJoa``}q#hyN#R1Q-j;-Mc>NVTrO+^ac_xJ@(-;B_aM0g)j*t;)aw060s*Q za#a~fM2N}b>@n1AUG_Uew42j?8x5tQ$x>SWtp}{u^}O{0yU}IpE_9w3tK?{3gp=P< zG3cmKue4Wqr4mQJ(*EIoG5S^VJ9<@+IbY3;)8y7O9?(wCp)oP+$-MIW@7Qx%J9{r?hyCBQ|`l6(GYtjIW#7YfM~t;i6 zO1!t;ygbSs4us@8ySbbq*ZJVvH2WiozAN-tyi7qZIvMzb+9jkFB&Ceu1Sx>&|uQEei z+)Ft>awzTtjZ_9`TisQ44MxJ!Xx@zJcYrb z5s2`$UBYDUC23vz!jPx>krviPjQC%B+9NhZbP4HLE)8)%_Uc@^l=S7fw5a&SCLLN&vcXGkBDugz z-a&G{m%Nu`t(UxyWQ~`+pXBLY@*$EHUh*-LWnL0N*w~Z2@Ucin>#HzA!!37%IY^qW?*pjVSm;o$tHh6%9lBbyGFHc&$qK#dEuN9DU(@LP?ECR zu)>PS+HTa!f`3%|BNZrzji-7-J8~=}b^^sW?h)I%HL;y#2fk3 zve<3?6XCU5>a%fnYpAg<6)G6OOv2c<<<5AGz-g%W#MI_$9NPgC-fwqEqk(lhmlL+R z&;1^ZgfLhat?mqJI}S$Eh*H@qI7{nfQS{3ff%Ay=yGT zbLGc5!Oi~s2W!6k4=N>;;j-|Z@64rhx2SV#>E^mt8nHgxbJLjE3_f2ypx)S-yEwp&@eO{EoHrA?{w5r3SG1Oi9RT-s8kE~O z=*%m_P{~iQXabyI8q09&tp}$Tg|9l$h~KobFl9rFOyP@yV?e%*gJu=xSDoEGzqBB+ znmq`l#^sKUXV`{*n^3MFJx;K&9bpbxYn9_}!76V?mT#4xjRoazMhYW6nalZ-4JDTr z7o_UBj#LZgqUc{izC{wGrua! zUk;ztIx$Bc)-Wfa!CS%haOvN}8T})1hTZW8PTq)f$i3oyxTOoZ^YxbO8<)c~_ttUL zUpOSUnM>ftm+Syi(H+*zXzz;8ljM2`bU}qOe@^D!6{X62PMODPk*(MAF)%G@sJCYB zx}ikcxM1p2!PHm%1K0Tt0~|LTTL3T58}X z@+P5=kh5NpVk*06$tr*L9qUr_L2tfr(5ie}O;}9n;}u=mP8__1(z6Q~Bv+et z^OTkTZ^otabUs)eUm6?FXDd(0SmZVO9SGaUm2s{?bzPagPQy0a*QZNUGQi^qG)K1k z?e7p6PeN3Gs2%&_>Kmqg1Vx1kzfwMMA0PdVDlYpctGJvh=;^Z9^@q_Zo)o)3f=}m% z-#Ob_JoOt4*C5l29tTi;tn)=et(8xyA8G%T)cCgDc=dWFweTPGJ;QiAqTH5^{RrvU~&?fQJ6}H4Us{Vsp z^|r8sQF}xjbK})ER-vf#iO03kV2xqQ&`$Zw&>f=9@(&!%{;R_(Anh5jx@(Asy;*T7 zo^gYL92WSohXtfpV0YK%^>1kTMOuB+&?#Vp%_K&*r2rXKc!Ar(K%?me;E9b#l1*My zznCMc>7E4T(qAnMR=kSpnea7v`X%Vpo9%r8{N=o5Ld5&Pt0At*IX!r(Vj&i>V~akr zW4p9t!}%TCr5)QDZGyKfIrf-l?bxmsu9y}l$*@JZ6tY2gu?AO83Hnfla-pWnPa({; zLXaUE1-Fl7j*QMUH&XY#d$Ilipaz_FdrN6;^=d*j%TmHvUKnyBT0S5z5r?qo&ds?H&BYnz*bFM>OguL%gee@A|->lB$!~L9gg~46Wyo5p`72ZRni+UE%Ku8 zbh>TS;Uw!(n>mhX4~EQ&i0BB0>b}=$q&&4tnEn@N^dLQxoz4gDY&5_IRn_p!;&tDUNo$W>n{prdS{v z*)233oC03^a2|)#>ixDAG10jUk%C+yEjb5_-R@=yr_zSzd{zT@xM;^sV&ZotcW$K& zo*Uyup8wm-6xpkL-#v}LWh_|o6+P=FRFOB8PtQ#+o|bh#E|-ICIqIxUw4jp~*pfs) zPhMHOeE)E z<$OQRG9NBr0{Px^?q$3W!^=dV2zP59M9V`QntXlkH!t;uCdTb+A#Cu2Og^VH_oQ zt-r?ho5)fTe4!|Ke2Qz9#IyXTzpJyvSr_KN8|_QSY=&jYhhwxm#ySoEj+i{dUYHEO z)h20k*tumXuia0-qf_hFvPN|m%V!AQdiPi|?c~qPRDnOwh1-u!L>z~yt8 z+@)b>S}ykna_#q8%cM7A$V-?l#4*tw@ggr4=g)Cx^2hkeY@8i@*e_{?KrV$}zx(3Q zn1X?wEMLXMELH!@6}>Xr%jDsn#e#GJ{6tBfm6WO2Dzv)$pp@HB2xx4 zMPY~48ksUAEmEoIk#ci7)H$Nl*Cf<}`|omZl6<22Beo-xZ7$A!C5DslD-)AeP~}z zp%p2_sEx~Vtk*7QqFpm7KAzHc&ADvbuGZab+m}KCAI79UaffF_u`v2v)Ek-YoX`Ei zNuZW!7nmlxE87(ebm0t%$1Wbb>XMI_)McNFKW}>s{}>0!#cofAY{Y&^MA!ps5z*!F zyW!!(srvkdNlrQ=f@t765Nem$&~uSKOLYZt@iS-``o=7kUxHAlYcxj*X9%#(mHaafh_-OE0u>^smg!u zwL(>+Te-rtGMiTDOjI4BrD&BFu-c7QMV$3oi(xKy>X8Z^tgGmwh#O`#f+r4QV^+A5 zqIVo#KYcY2T;VRav}Ue9KDp+cqIeOos+n7i!zXA8cxYxoxP{oi+5^re^KGsr9}>qk zvwNjE34fqDJDH@N{l+%npLnbh1XsYF^@r+7tS$;Xw1{W(QPfF*AARFTGNXmEN(cbx zLO)@3=jkq{i4SC=&4>3MYt%efGsm>VCmxithbKZCmn+A?HZWs;L%h-b2-4QFUe8OSTq`PiXG<~ z=$W-fNCeM*kUI7_gKi&ALxHjfN=y+w3zn`!eoc#+n{v&ZNrAr)6|StJxChwR{9&Id zUo#~RxObT~X8Yqu)tpxppFl&4YV6|Jafb33hB0-y-(n%5h7=^-v)|Rt^KW^;HM1D? zVZ65oS@N3M{qA$DA5S-(UvtA?+MWZ`_9MZx8Lgw%+)_ywk2s^yQ!}6vF z!80Tc$sc0%xUE}_KQZHIeXZzAf|3QoOo7%Ap(<*=2V5a#3C3NvqfM7FwCQz1dYi{T1GhnaJg(|5TH zvM;dw>u>~W6mXH`R+Mbb7d?|H!)V%HRa|84Mptw*+r{KER*fezl|zHgX~ zI5U|v6Ys^Z4_A1#>l_aZuK4{L^w*PH7KZ>q2Nln(SY407+Gc+ z-tt2vgP(NQk6DE<^{&_i;avx35mkxD4BV~OVng0}xW38UAkpnf*~98)rtS&~*b(O- z{!oV@UN>W}2l0g-#3u^ko(|esQk4nhaW|bAHB*1%yLMXPyX@nsCG>vuxg)Qn+cN)l zL+3)a-zxGKnpJbm(HB`yrFxZ|xNNbLLI$|}J zaTwI8P-+Hu8XjtRzYG5PP~^yaa^woz9;9tnQyl?FI{tt+nQ-#pV8p@b15@OolK8O* z>CGPeea5&87;8UJDC_pOK#F}>sF-(?-V`ghUi;H#dw}%P4MgSMWmimx2-)Xu`i=H- zLlq=(1T^jJi=;x;?u#5GiO1S?I_QK?HB`s1^bYSaEC6$g`{NDfBFRGD9^{|vv5_1| z9mo-MAcYRP*S)9hf3Jrf%+V+8z^Rq%9ttNve3goR`z>{}p*r8pS-ECnXVA^k>OP$X8tlA7!YupTGcEnjkq+E8 z$YFwVI0yV#B3W;B_%N{kAm24lhAHq&j@DyA!F~|9s3p|V<#vI1M8W9V+WCPyq$!A> z>om+(Bfn)=puJ!w8V;ht&_CDSR%pPKhtGMO2$@q8k1eMm7JsAU`F#36^mE|++>i9+ z!zcAgfqQdU^In5BCxe%Dy=R|$35rpn%GyX8LC364{IS&HnF*Uj6MQ|l^o-2`T4il} zFIbn9RkF2)e@3yvu7A;O#^I*<&4R$)B^XB^EOnoNKs@q9C;#w~p8mlW#$j$ap^I?u z{3_0-+fIA0R$a){`rUu?lEmSy3_ITvx<goptsQO1fTYCUJypAUa8w`HF)6doM*j zo~-YMY<**9tUL6k;4kVW*!~^Wo2_3alvOW*N24&-(ovTNJh{ZI&Ni8xS>Zk;eLyT; zTXTz`6RQTLdb~wZ%H(A0m;b{~_QNcQq7)E^ZDDFXc8gX-yqzfG?KngS9tQEI$#=k+ z+LsyU+@fus7dj2^VF(j%6}rp*U1QwC-RetU$!3jar(&qa%tUPVtOIR&N$g7Zm0$l8 z5Uo&W4S+-ggE|!p#oWL(N9R&(>N`1>6_x-+5FRGDwb)SQUM@*g$%v!GoIOy#!zWaJ z`&4n4z(XwVmHKGf5oHt__;Nbm*+v(O?pE6_ zua31UF|XgG#o>N`SvEU2J+)LV*8N5pz?@NrbT!8m?YMKDso)_4QFr#8YU_wXDv87&<%Rk&)g>%G%nq(DC=X3s~dGEU$Ujnt9FC8;*0FTiKY%9Iu(We<1N%AwFx% zGfjXgISi)8&{XtqV+X!Gslb{U`p{Z;GuVjg+?llHd_&)7d-wm3b-(!}@$15NbiI;Y z8Xz}@5I|QV)Vg-J2jD2br$hWaNAWfv>YsYX6jm*%P^!xnK|J*@XqX`}T@nnY)8b{!O<>{#|0bFu}0#f(K(EFgD?g6cZwDhPu-Q6M8(kN;%lEi*Lf z;TWC*w)26ZMAP+KG4a}AcMOC&4#H%)k37#zrSH)V0raB5npt=ob?z}}8aLHp-#z9; z)j4%*na0XZUf|vc7q48(3cTb!4%nZTwNjQ<`Mx_2Z0c;(>0wI&Qg zd&XTvw~aS{RD=*8&Mp-A3%fWQoZD4!|B&2T^*Xz{-tu?3W4ivwXP^3e`_vx$)E9!S zk9t*s!*I4^wMr+WtE0%?xP1S7<`d4wcB-%g=)xD`g&ae($iASnAK#r^vBmxaLyU@j zA!ir3qnP?25H zKOjqxV8w3qpC@E9^HtX*uP)-haWMXse$XcObu#qz*^2#C>Z~&aNq>vK;>ApGZaO$E z8|YvCCA;F;bns(^srmlQ={OWBqw4s{`LfN^^W~1CI?Jwj+4lV^GoG~1u6QwZnV)HO zKlKZy4H@Sn@Y)4|UTb0Rux&uF=0On+R@+A21)X(hV>NG=mzDDuts7bo6371WGFC(R zUKYXARyi7(#i&Fp38wTk^x%NqHQ>jmap=^2<~$D~OmaHyF4xCwg)~n+%#$j%TEE1U zYo1=t%@Y!VJ(<(7xZ|xIc#27S$`0&dlJ-d6I5z0Kn3>9|l)i>W>B{1#Fh{F=Q4VcO zRpdlxoxV*^t+fNtoC|S|{sN!B;Oxril060#bl>w#D|PiA4=p}z&D?XtCsoM=DzVz+ zVufbLQ$Hot6l1LH9B{q-F04_!Y)qV9vTlCX^nQ1&SUnhDc>KUFGOY4F>fXSA*Zc=u#IT%8LVgCmKsmy@%%IU+q&cc zA6n&7eN#>29%*=IQ6J`Tm0g(&)yj6YBB<^%hE|Jzp)U;dq~ydNr*c>3`=l@dduqj} z_;#<^<>c(+-R_iCbGt$%#L+8Pu9NAxuPZg)8Q<0kCElGHZ#XB}^;H=>iE{2Rs`PlM z{GDS%t0M7~m0uMHvy;+B%1O^qaNvB-@CzoqU7#y=g4m%w?y7zr-@2m#!49Rps4VOi zj9rs-WQ13gGT&imiFU{%=iLkU!-bnWPzA9sG8r7- zIfln8E3xy7)oXR@OcZ+IPq=utb{ZooJv75a3*$8sGdf0C%PRC2Kw zYaZ4~(mchvMb99nt?nNn%QFjdGLR#LXFN#uvjfv7WpbuTG)kIYxh>xv#Of(n zlR5}mSbbbDWfJKN#vqsx8R4!t7Q)tC(F*i{*S*_X^iXw&opxi;XBRup>wKT>&0$L! zQkk5Z?LwEa;{uNAk3kvuB!@uWtQ$W^48l9djV^u^g@k;2gi9)8JH+wL3FBULyedJD z{-{Ut;8((sJf6l~B*>>C*zb%q-+_pWI#0-6?>(7`r34 z{|8JSCc5*|{%PU##w`rM`GtG>zshUXplonud~!nKYY;Gyg2VSWY(v2;EU)cAYGx$B zSC_F{M#MO)H&@t2vy8TrsufvSp69>_9v|#@8=C~T=^04O^wP^iZEvmmf^)aGS)X*UY60H{mzhA$(@>wf>^!Nrs=9_)1W`N@N^FE%7FQzc|tJoBUP|k&fQ&3LT9Hs6*`@zYm6aS zduCzOvevv-tW7&9m+OGlmZBSvvLDAoc-1`c3U$SnrOeYNNJ#E$qJI;mV|650^MEFY zxq<33^}BQaOVbV4LkLKMlkTU zS%zM3!^LSkTVp`eJb`4&BxPo5>^wyfbLGv8bQ@oTpEK+R(hXhQ=K;7%cJ*NAm?mdqg zK8&CvhK_%XPIR{#e-Z_b8H%%0!_s_x7NBa%N^IxPnzc~++QLxBZ!?pLSn#P($M0-o zRYicgXty(%v4S1nHTCE#N=jDa0r`^UEGSUF_iNzWfSg#n+=*lwo_5ds5Yd?RASOeE zmj1Kt`!mjuUlTDoE@gT$a*Z{A%uM!3$Y(V5YEM2h1X84Gk@Vf#Wx6i()r)AGD-+kl zNMPgxy+q_l=eauP+-dG6Zj9xM!l2053#P;GJCvC=T$Z5LUfCwf`i8VqQO2`i*xlHP z$@wMN6B%C21NCe`9T>6}4z*=DP5+|X&x~5u*5{PEuhrqOY;x>aoR$%(ii|#Gl-63eJ(+1Bf`wasLpFQb zdbJvM?$ur}QaJY%va!eVe#~i+Ki;=uWwcyh>V@W%6U}vdhg6-l z0sbG(N!|Pt=rG6aYP6uaWde?Zm7%>W85OR|NSW|G73vj?h;;rDxV(m7Pz2`3!4+6f z$4^FdutNfllHHzUK(yvHJ4Dm|kvrb?qlHDz9RigRF&!N7M$)M})Ne_jI4p8d>`=sD zuJ{uW^Nas6FtH$WEQzhZo5%(pdp8dhjaV!Up%&=t4)sfR)aSM>Wm1BH-&mWj2X911 z*qIw+^d0WdBZeVIKD^KUd5Iv8n%9`1?=ai;1x>h2(4R3gKP>8^kE~cah3Pr5ENB(X&5ek zxK+%_H|4-E0^*QT9>mRD4BFkHQbzq=>|^HE3Ww$JtrZ=XTw94^FZUJK9H^tOLfY9U zLL6XDyx!V)C#%NH!urcdB%c`J(#f;q(Os`_X^{I~(m~6=)A^$hSTqTRv)-D;;7~;k z5!8SkS}M5*;s)kqzBvni6%Gs$^c9Q##GDf*#)`st6btmPcspG2tHkOOm@;qEV%|UN zb%l(Z&GlpMH=z(UGyI~NSkHH^+yDtZ)iq)63k`N?p7r4L)45)T=}lp#WUlp~|8sSi z-%P5@J}IyU_N>To7&GO^otrK`S!%tI^K>NbKQmbI6eM*a6Mz@AE<5}6PF0I=RQ$wV zk4x*)wm29LJiFpfiJr>kbZaZckcO8A@zu43v>e*$WX^ovblO>fo2v#EvVS~%M1L0c z^wZ1n;&ML@W_;WB0K^`%Kp^o z7)H&{=;>K5c=gk}S?@)g`mn=5Y_o$9cHHHyt&W#itxK68tfeaPfBaM9RF2bF<)aD- zC8xO@uRk>o#G>idS;R3B&WD2(VBG@L-<^~8A4McVe^FiF{p+FWB1MJPgIFweY6hNQ z2BLvCR=g$8VLQx68_Krv4Ec72om##>x~{1|eAUa1obm`EK4e0C;fSxh;xAEOR~G1D zlVawDM%Akbkka>DtBAtx{t}j^6GdB5)R{;>VOrO4KN&&*kQ0H)cdO|s0gE9Af@QTS zuM$e~k=G$ZH1Lj95H7XK`5Fyn1Y8}QR1MOeq$8x7AG5*!B&*EA1`C&p8>_dow``#| znm_d_$g`7YT{>1)NSq<-=6%dt=0=R$ehP0%rwj3iU#j8<#;;9d*#G^|Mi!mYMJh+8a#ustkw`TS!_*CN! zEI#L!hKX_W@G^^H+^*0cU8GM5>Z%t^MJn=<@x9W{gw{W`kF>dA;B(JhFuc^h?(%6(3us(hg;JA2-8u2bY>ssO+f+hGo%P>n(1I^;9Z0GC2DSHij8 z|Kf-N1k-cy7sJ*0Adp#VwVrIy`J;vl@Ypw7blqh|?zIbbk}Q-O_WWvR$okpA;_I)- zv3Qhm7w{gzY7dt=Dm`DArU;@B!x`EYzm&e+!30yb-qmd{ulZF3%BPW1lUJPdFkVv% zpp4&|(KX{xV8|TUK`Vkri7_M|^-Qd85dYcHseTyF(r1L3PM>>Vf!6FsNufPDT?U=$ z=CSOLb<@anrh=hIUyK3Mdl~85!^|7R9k|F%{hMekc@p3-s1FhgI70BN(HUL~$w!wW zogTa6V=M#Y;UdA);jvb*EBR=(UZg^|rtJ^BEXe0nXtTR2O64H?^q#UCtd*6jSr zx+H7O?6KCpLbieS9=Fg82t6(?Fx@-#ow#B$_z@e6#qBU2S6~$)N z(F?e%7hM0`G2E?bD8y#<)=or>A77g-0A%rT*3U8@&s^w4H#@tYJvga96ESRQ?rqW9 zJ%Boq`GOO@HSS)G&|9IPf?_EL0@Shg+TRKe;pC%R87LIaWV3TNZsV5*c`}{J z(VYRsj%?lS*}mEj7nF!j{{vAz7L^f1<!TdtET05!IS*L}W93r@zZW@}+ zf{#yY(^h^31OFM(vK7d+EUZo6QZAL)1GkXMH}hI7Ob9+q+CFW!b;ShXlQLJ?I|OeQ zMDTD0XqZ+X&+8L24c==zFti$FM$6vJ%VbZ_eCcrZr^$Zc^aC75LDg!R-KwfJh71zx zw_>+vzGpf-+(9OvO~v_VP-DWkQ3xxNu1tW!TUzHjtv?pFojc>MA8TRitT$8X9p9l1 zOljLpAlx0Qm-0m(sE;jsReVR3ZQA2bi%lqaZ{1x0zczMhe&R+hW|TWjZEx4W1iR}{ z$=Y9Q@(6i{VR`u{3QB?VYenASdh9P=fsfgJ;rj%=1t;uQ3wHA0fSv5T%>D1{Cvet= z63W!6vc-MlGI{yAARKj$i=;#K;kCQ8@M#GIog-~jm}4#4ZsZoW^b06Vw@}X()luqx zCszj|H-I8~0bDPV;YFuI#|53Nb~@xPE0Vrh)g#_s@?CP}G!+AEn#Bm421U%2=4h4y z=|N;hL6m{9R@>+K1>me!P)AA+i85y5~-(Cl>^cq z5t}q3Ai7D6QOyd}wa0M=Dr~h`S^a#Uakai^wf>sttOIl3Z#8R{AAhl0pG8KI_DgL>n2w7QQSZ4K<0R(0m%@7r>A8SmG1D-4eshioCV=9OjTOT zH<*}M=Xsui3G2>pKP@Ni0xpTVM}N7{!=}DN`~Q^8mRcJMjQ~Qlf>F|YhhETUNRQmH z>+A{n{(P98aNFj2N8X0XMx~HHQ*nHY+u6eu8J2!ytquS7o=n-G-n$98h1VUja-KhsrJ&(C$0z2)lG7-t>gBoqC{Q5!ueC=RJ-XHjLF7mtb^P&6xiXRAQ z?$N?`&&t!>rO4lvlN=|1&O*u=VWFMAAa~5<4j{b{^-|~DCdvkzN5{n?CRbeFd&g0E z)Dzosn`Sd3u$>)SS+7X7FT#n?)7d@lg*eW(E8avJf&QZ|otE5RQ%y8P6Wr!`Xunc- z%AaLB_E&}PwL~Vugbw)>x68OggN~pm+iRx^aO0Y&Nvs%3)V#ZLfxUe&Sbf5Z%aR}X zo7w1fg=ssH96D>|=lOBonDkupqZ}gdJfEHW^)Z_-^(;-eE)4C!l3Nbx-0@A~tCE6lfu5HrPKo7_6SMVkzHJyEmEx*54& zHu=FAYr{1ptOxDFWT%E5e+fJtGoqLOSJz$u;GLa8Ednc7)b2VyM_>fA0az(`5|Yqk-a`sYlHPs~0=oCHd&`E4+;u#`y0RFb=m4$lF< z*kiur7MC%(%I6X~A~h=Qr{I1l6X;NKKPnrS3f17;&Qj) zwT4T8?7F5`>wGw#lJU>1B@>u-?v;oUS!Vm545F{{?Xi75p^8_-O?}a($4yyxA_aqp z-hz=PQi=maY0?SGm5PCc~dK$DAtrBe~gq$#YrsY0ovKGT@$-#*2@$)U%dvF7)OS9^=gwA1dNgz&U3@JjPfA}|Qcl2=x;^5%zG z8@ugpzs%j|1NhhB9LwL9q$0W{)Lw~*Vg6F6oA2g}EDNEKXbzrITIV^vK3)7pt@<t4x8q0YM!d1n zX}zDp0m)^W2?z)*=j>#ePQ``wQRnPZaLS^|1#&qxH_<$XTPv;1M?otTp~c?REZH5A zu?2}k6XNhXi;$;GMfOzw%-dGu&I-E?u!+lXP_#!MsIDFRk)86x(g9&2i+buq6N zQ~F~08=5+1;C{2=9}RL`m$qEab)~LwI@Y!Y0%n|TeYWc+JARh?{{1>WdQs@Ri_g!m zqsPx-RiB0cHvuDp2$Iik+X5Zmo|j7_a}-g8V0z&)(^F?$%0Dq<+a2rF8VbCGibtJe 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 ZPx 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%0D<=Er$KqdATUe%B5 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