Vuo  2.0.2
VuoCodeHighlighterGLSL.cc
Go to the documentation of this file.
1 
11 
12 #include "VuoCodeEditor.hh"
13 
18  : QSyntaxHighlighter(parent), codeEditor(codeEditor)
19 {
20 }
21 
22 void VuoCodeHighlighterGLSL::highlightBlock(const QString &text)
23 {
24  // From https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.20.pdf
25 
26  // Keywords
27  {
28  QTextCharFormat format;
29  format.setFontWeight(QFont::Bold);
30  format.setFontItalic(true);
31  format.setForeground(codeEditor->keywordColor);
32 
33  QRegularExpression expression("\\b(attribute|const|uniform|varying|centroid|break|continue|do|for|while|if|else|in|out|inout|float|int|void|bool|true|false|invariant|discard|return|mat[234]|mat[234]x[234]|[ib]?vec[234]|sampler[123]D|samplerCube|sampler[12]DShadow|struct)\\b");
34  QRegularExpressionMatchIterator i = expression.globalMatch(text);
35  while (i.hasNext())
36  {
37  QRegularExpressionMatch match = i.next();
38  setFormat(match.capturedStart(), match.capturedLength(), format);
39  }
40  }
41 
42  // Built-in variables
43  {
44  QTextCharFormat format;
45  format.setFontWeight(QFont::Bold);
46  format.setForeground(codeEditor->builtinVariableColor);
47 
48  QRegularExpression expression("\\bgl_(BackColor|BackLightModelProduct|BackLightProduct|BackMaterial|BackSecondaryColor|ClipPlane|ClipVertex|Color|Color|DepthRange|DepthRangeParameters|DepthRangeParameters\\.diff|DepthRangeParameters\\.far|DepthRangeParameters\\.near|EyePlaneQ|EyePlaneR|EyePlaneS|EyePlaneT|Fog|FogCoord|FogFragCoord|FogFragCoord|FogParameters|FogParameters\\.color|FogParameters\\.density|FogParameters\\.end|FogParameters\\.scale|FogParameters\\.start|FragColor|FragCoord|FragData|FragDepth|FrontColor|FrontFacing|FrontLightModelProduct|FrontLightProduct|FrontMaterial|FrontSecondaryColor|LightModel|LightModelParameters|LightModelParameters\\.ambient|LightModelProducts|LightModelProducts\\.sceneColor|LightProducts|LightProducts\\.ambient|LightProducts\\.diffuse|LightProducts\\.specular|LightSource|LightSourceParameters|LightSourceParameters\\.ambient|LightSourceParameters\\.antAttenuation|LightSourceParameters\\.diffuse|LightSourceParameters\\.halfVector|LightSourceParameters\\.linearAttenuation|LightSourceParameters\\.position|LightSourceParameters\\.quadraticAttenuation|LightSourceParameters\\.specular|LightSourceParameters\\.spotCosCutoff|LightSourceParameters\\.spotCutoff|LightSourceParameters\\.spotDirection|LightSourceParameters\\.spotExponent|MaterialParameters|MaterialParameters\\.ambient|MaterialParameters\\.diffuse|MaterialParameters\\.emission|MaterialParameters\\.shininess|MaterialParameters\\.specular|MaxClipPlanes|MaxCombinedTextureImageUnits|MaxDrawBuffers|MaxFragmentComponents|MaxLights|MaxTextureCoords|MaxTextureImageUnits|MaxTextureUnits|MaxVaryingFloats|MaxVertexAttribs|MaxVertexTextureImageUnits|MaxVertexUniformComponents|ModelViewMatrix|ModelViewMatrixInverse|ModelViewMatrixInverseTranspose|ModelViewMatrixTranspose|ModelViewProjectionMatrix|ModelViewProjectionMatrixInverse|ModelViewProjectionMatrixInverseTranspose|ModelViewProjectionMatrixTranspose|MultiTexCoord0|MultiTexCoord1|MultiTexCoord2|MultiTexCoord3|MultiTexCoord4|MultiTexCoord5|MultiTexCoord6|MultiTexCoord7|Normal|NormalMatrix|NormalScale|ObjectPlaneQ|ObjectPlaneR|ObjectPlaneS|ObjectPlaneT|PoSize|Point|PointCoord|PointParameters|PointParameters\\.distanceLinearAttenuation|PointParameters\\.distanceQuadraticAttenuation|PointParameters\\.distanceantAttenuation|PointParameters\\.fadeThresholdSize|PointParameters\\.size|PointParameters\\.sizeMax|PointParameters\\.sizeMin|Position|ProjectionMatrix|ProjectionMatrixInverse|ProjectionMatrixInverseTranspose|ProjectionMatrixTranspose|SecondaryColor|SecondaryColor|TexCoord|TexCoord|TextureEnvColor|TextureMatrix|TextureMatrixInverse|TextureMatrixInverseTranspose|TextureMatrixTranspose|Vertex)\\b");
49  QRegularExpressionMatchIterator i = expression.globalMatch(text);
50  while (i.hasNext())
51  {
52  QRegularExpressionMatch match = i.next();
53  setFormat(match.capturedStart(), match.capturedLength(), format);
54  }
55  }
56 
57  // Built-in functions
58  {
59  QTextCharFormat format;
60  format.setFontWeight(QFont::Bold);
61  format.setForeground(codeEditor->builtinFunctionColor);
62 
63  QRegularExpression expression("\\b(abs|acos|all|any|asin|atan|ceil|clamp|cos|cross|dFdx|dFdy|degrees|distance|dot|equal|exp|exp2|faceforward|floor|fract|ftransform|fwidth|greaterThan|greaterThanEqual|inversesqrt|length|lessThan|lessThanEqual|log|log2|matrixCompMult|max|min|mix|mod|noise1|noise2|noise3|noise4|normalize|not|notEqual|outerProduct|pow|radians|reflect|refract|shadow1D|shadow1DLod|shadow1DProj|shadow1DProjLod|shadow2D|shadow2DLod|shadow2DProj|shadow2DProjLod|sign|sin|smoothstep|sqrt|step|tan|texture1D|texture1DLod|texture1DProj|texture1DProjLod|texture2D|texture2DLod|texture2DProj|texture2DProjLod|texture3D|texture3DLod|texture3DProj|texture3DProjLod|textureCube|textureCubeLod|transpose)\\b");
64  QRegularExpressionMatchIterator i = expression.globalMatch(text);
65  while (i.hasNext())
66  {
67  QRegularExpressionMatch match = i.next();
68  setFormat(match.capturedStart(), match.capturedLength(), format);
69  }
70  }
71 
72  // Operators and other punctuation
73  {
74  QTextCharFormat format;
75  format.setFontWeight(QFont::Bold);
76  format.setForeground(codeEditor->operatorColor);
77 
78  QRegularExpression expression("[{}\\[\\]()+\\-~!*/%<>&^=;|.,]");
79  QRegularExpressionMatchIterator i = expression.globalMatch(text);
80  while (i.hasNext())
81  {
82  QRegularExpressionMatch match = i.next();
83  setFormat(match.capturedStart(), match.capturedLength(), format);
84  }
85  }
86 
87  // Constants
88  {
89  QTextCharFormat format;
90  format.setFontWeight(QFont::Bold);
91  format.setForeground(codeEditor->constantColor);
92 
93  QString integer("\\d+|0[xX]\\d+");
94  QString floatingPoint("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
95  QRegularExpression expression("\\b(true|false|" + floatingPoint + "|" + integer + ")\\b");
96  QRegularExpressionMatchIterator i = expression.globalMatch(text);
97  while (i.hasNext())
98  {
99  QRegularExpressionMatch match = i.next();
100  setFormat(match.capturedStart(), match.capturedLength(), format);
101  }
102  }
103 
104  // Preprocessor
105  {
106  QTextCharFormat format;
107  format.setFontWeight(QFont::Bold);
108  format.setForeground(codeEditor->preprocessorColor);
109 
110  QRegularExpression expression("^\\s*#.+|__LINE__|__FILE__|__VERSION__");
111  QRegularExpressionMatchIterator i = expression.globalMatch(text);
112  while (i.hasNext())
113  {
114  QRegularExpressionMatch match = i.next();
115  setFormat(match.capturedStart(), match.capturedLength(), format);
116  }
117  }
118 
119  // Comments are last, so the style for commented parts of the line overrides any above styles.
120 
121  // C++-style Comments
122  {
123  QTextCharFormat format;
124  format.setFontItalic(true);
125  format.setForeground(codeEditor->commentColor);
126 
127  QRegularExpression expression("//.+");
128  QRegularExpressionMatchIterator i = expression.globalMatch(text);
129  while (i.hasNext())
130  {
131  QRegularExpressionMatch match = i.next();
132  setFormat(match.capturedStart(), match.capturedLength(), format);
133  }
134  }
135 
136  // C-style Comments
137  {
138  QTextCharFormat format;
139  format.setFontItalic(true);
140  format.setForeground(codeEditor->commentColor);
141 
142  // From https://doc.qt.io/qt-5/qsyntaxhighlighter.html#details
143 
144  QRegularExpression startExpression("/\\*");
145  QRegularExpression endExpression("\\*/");
146 
147  setCurrentBlockState(0);
148 
149  int startIndex = 0;
150  if (previousBlockState() != 1)
151  startIndex = text.indexOf(startExpression);
152 
153  while (startIndex >= 0)
154  {
155  QRegularExpressionMatch endMatch;
156  int endIndex = text.indexOf(endExpression, startIndex, &endMatch);
157  int commentLength;
158  if (endIndex == -1)
159  {
160  setCurrentBlockState(1);
161  commentLength = text.length() - startIndex;
162  }
163  else
164  commentLength = endIndex - startIndex + endMatch.capturedLength();
165 
166  setFormat(startIndex, commentLength, format);
167  startIndex = text.indexOf(startExpression, startIndex + commentLength);
168  }
169 
170  // Don't highlight anything else in comment blocks.
171  if (currentBlockState() == 1)
172  return;
173  }
174 }