0d399d33dcbe15f1f7812fc39d3171f5e6816817
[platform/upstream/doxygen.git] / src / htmlgen.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  * Copyright (C) 1997-2014 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby 
9  * granted. No representations are made about the suitability of this software 
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include <stdlib.h>
19
20 #include <qdir.h>
21 #include <qregexp.h>
22 #include "message.h"
23 #include "htmlgen.h"
24 #include "config.h"
25 #include "util.h"
26 #include "doxygen.h"
27 #include "logos.h"
28 #include "diagram.h"
29 #include "version.h"
30 #include "dot.h"
31 #include "language.h"
32 #include "htmlhelp.h"
33 #include "docparser.h"
34 #include "htmldocvisitor.h"
35 #include "searchindex.h"
36 #include "pagedef.h"
37 #include "debug.h"
38 #include "dirdef.h"
39 #include "vhdldocgen.h"
40 #include "layout.h"
41 #include "image.h"
42 #include "ftvhelp.h"
43 #include "bufstr.h"
44
45
46 //#define DBG_HTML(x) x;
47 #define DBG_HTML(x) 
48
49 static const char defaultHtmlHeader[] =
50 #include "header.html.h"
51 ;
52
53 static const char defaultHtmlFooter[] =
54 #include "footer.html.h"
55 ;
56
57 static const char defaultStyleSheet[] = 
58 #include "doxygen.css.h"
59 ;
60
61 static const char search_functions_script[]=
62 #include "search_functions.php.h"
63 ;
64
65 static const char search_opensearch_script[]=
66 #include "search_opensearch.php.h"
67 ;
68
69 static const char search_styleSheet[] =
70 #include "search.css.h"
71 ;
72
73 static const char search_jquery_script1[]=
74 #include "jquery_p1.js.h"
75 ;
76
77 static const char search_jquery_script2[]=
78 #include "jquery_p2.js.h"
79 ;
80
81 static const char search_jquery_script3[]=
82 #include "jquery_p3.js.h"
83 ;
84
85 static const char search_jquery_script4[]=
86 #include "jquery_ui.js.h"
87 ;
88
89 static const char search_jquery_script5[]=
90 #include "jquery_fx.js.h"
91 ;
92
93 static const char search_jquery_script6[]=
94 #include "jquery_pt.js.h"
95 ;
96
97 static const char svgpan_script[]=
98 #include "svgpan.js.h"
99 ;
100
101 static const char dynsections_script[]=
102 #include "dynsections.js.h"
103 ;
104
105 static const char extsearch_script[]=
106 #include "extsearch.js.h"
107 ;
108
109 static QCString g_header;
110 static QCString g_footer;
111 static QCString g_mathjax_code;
112
113 //------------------------- Pictures for the Tabs ------------------------
114
115 // active tab background luma
116 static unsigned char tab_a_png[36] =
117 {
118    31,  42,  59,  69,  73,  74,  75,  77,  77,
119    77,  79,  80,  80,  82,  81,  83,  84,  86,
120    87,  88,  89,  90,  91,  91,  93,  94,  94,
121    96,  96,  97,  98,  98,  99,  99,  99, 100
122 };
123
124 // normal tab background luma
125 static unsigned char tab_b_png[36] =
126 {
127     218, 228, 235, 233, 230, 227, 225, 222, 221,
128     218, 217, 215, 214, 213, 212, 211, 210, 209,
129     209, 197, 198, 199, 200, 201, 202, 203, 204,
130     205, 207, 209, 211, 213, 217, 219, 206, 188 
131 };
132
133 // hovering tab background luma
134 static unsigned char tab_h_png[36] =
135 {
136     181, 191, 198, 196, 193, 190, 188, 185, 184,
137     181, 180, 178, 177, 176, 175, 174, 173, 172,
138     172, 154, 155, 156, 157, 158, 159, 160, 161,
139     162, 164, 166, 168, 170, 174, 176, 163, 145
140 };
141
142 // shadowed header
143 static unsigned char header_png[12] = 
144 {
145   255, 240, 241, 242, 243, 244, 
146   245, 246, 247, 248, 249, 250
147 };
148
149 // function header
150 static unsigned char func_header_png[56] =
151 {
152   248, 247, 246, 245, 244, 243, 242, 241,
153   240, 239, 238, 237, 236, 235, 234, 233,
154   232, 231, 230, 229, 228, 223, 223, 223,
155   223, 223, 223, 223, 223, 223, 223, 223,
156   224, 224, 224, 224, 225, 225, 225, 225,
157   225, 226, 226, 226, 227, 227, 227, 227,
158   228, 228, 228, 229, 229, 229, 229, 229
159 };
160
161 // tab separator
162 static unsigned char tab_s_png[36] =
163 {
164   187, 186, 185, 183, 182, 181, 180, 178, 176,
165   174, 173, 171, 169, 167, 164, 163, 161, 158,
166   156, 154, 152, 150, 148, 145, 143, 141, 140,
167   138, 136, 134, 131, 131, 128, 126, 125, 124
168 };
169
170 // breadcrumbs luma
171 static unsigned char bc_s_png[240] =
172 {
173   150,187,187,148,148,148,148,148,
174   147,175,186,147,147,147,147,147,
175   146,153,185,185,146,146,146,146,
176   144,144,177,183,144,144,144,144,
177   144,144,159,182,144,144,144,144,
178   143,143,144,179,181,143,143,143,
179   142,142,142,165,180,142,142,142,
180   141,141,141,144,178,178,141,141,
181   139,139,139,139,167,176,139,139,
182   137,137,137,137,146,174,137,137,
183   137,137,137,137,137,169,173,137,
184   135,135,135,135,135,150,171,135,
185   133,133,133,133,133,135,167,169,
186   132,132,132,132,132,132,154,167,
187   129,129,129,129,129,129,140,164,
188   129,129,129,129,129,129,154,163,
189   127,127,127,127,127,128,161,161,
190   125,125,125,125,125,141,158,125,
191   123,123,123,123,123,152,156,123,
192   121,121,121,121,129,154,121,121,
193   120,120,120,120,143,152,120,120,
194   118,118,118,120,150,150,118,118,
195   117,117,117,132,148,117,117,117,
196   114,114,114,142,145,114,114,114,
197   113,113,120,143,113,113,113,113,
198   111,111,133,141,111,111,111,111,
199   110,112,140,140,110,110,110,110,
200   109,124,138,109,109,109,109,109,
201   107,133,136,107,107,107,107,107,
202   111,134,106,106,106,106,106,106
203 };
204
205 // breadcrumbs alpha map
206 static unsigned char bc_s_a_png[240] =
207 {
208   241,241, 21,  0,  0,  0,  0,  0,
209   162,205,117,  0,  0,  0,  0,  0,
210    54,231,225,  3,  0,  0,  0,  0,
211     0,198,215, 78,  0,  0,  0,  0,
212     0, 93,211,186,  0,  0,  0,  0,
213     0,  6,232,235, 42,  0,  0,  0,
214     0,  0,132,203,147,  0,  0,  0,
215     0,  0, 27,242,241, 15,  0,  0,
216     0,  0,  0,168,205,108,  0,  0,
217     0,  0,  0, 63,228,219,  0,  0,
218     0,  0,  0,  0,207,221, 72,  0,
219     0,  0,  0,  0,102,208,177,  0,
220     0,  0,  0,  0,  9,238,240, 36,
221     0,  0,  0,  0,  0,138,201,138,
222     0,  0,  0,  0,  0, 77,187,158,
223     0,  0,  0,  0,  0,159,204,120,
224     0,  0,  0,  0, 15,241,241, 21,
225     0,  0,  0,  0,111,208,171,  0,
226     0,  0,  0,  0,210,222, 66,  0,
227     0,  0,  0, 60,227,219,  0,  0,
228     0,  0,  0,162,204,114,  0,  0,
229     0,  0, 18,238,238, 21,  0,  0,
230     0,  0,114,205,165,  0,  0,  0,
231     0,  0,216,225, 60,  0,  0,  0,
232     0, 66,226,216,  0,  0,  0,  0,
233     0,165,204,111,  0,  0,  0,  0,
234    21,241,241, 18,  0,  0,  0,  0,
235   117,203,159,  0,  0,  0,  0,  0,
236   219,227, 57,  0,  0,  0,  0,  0,
237   211,201,  0,  0,  0,  0,  0,  0
238 };
239
240 // doxygen logo luma
241 static unsigned char doxygen_png[3224] =
242 {
243   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
244   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
245    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255,255,255,255,255,
246    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 91, 91, 91, 91, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
247    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,255,255,255,255, 32, 32,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
248    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,253,253,253,253, 32, 32,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,255,255,255,255,255,255,255,255,
249    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,251,251,251,251, 32, 32,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,255,255,255,255,255,255,255,255,
250    32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249, 32, 32, 32, 32, 32,249,249,249,249, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249,249, 32, 32, 32, 32, 32, 32, 32,249,249,249,249,249, 32, 32, 32, 32, 32,249, 32, 32, 32, 32, 32,255,255,255,
251    32, 32, 32, 32, 46,132,190,190,147, 61,247,247,247,247, 32, 32,247,247, 32, 32,118,161,190,190,161,118, 32, 32,247, 32, 46, 89, 89, 89, 89, 46, 32,247,247, 32, 89, 89, 89, 89, 61, 89, 89, 89, 89, 46, 32,247, 32, 46, 89, 89, 89, 89, 32,247, 32, 32,118,175,190,161, 89, 61, 89, 89, 89, 61, 32,247,247,247, 32, 32,104,147,190,190,190,132, 89, 32, 32,247,247, 32, 46, 89, 89, 89, 75, 32, 89,161,190,161, 75, 32,255,255,
252    32, 32, 32, 74,230,244,244,244,244,244,244,244,244,244, 32, 32,244, 32, 74,216,244,244,244,244,244,244,216, 74, 32,244, 32,187,244,244,244,159, 32,244, 32,117,244,244,244,230, 46,173,244,244,244,131, 32,244, 32,131,244,244,244,173, 32, 32, 46,173,244,244,244,244,244,230,244,244,244,131, 32,244,244, 32, 74,202,244,244,244,244,244,244,244,173, 46, 32,244, 32, 89,244,244,244,187,145,244,244,244,244,244, 89, 32,255,
253    32, 32, 46,213,241,241,241,241,241,241,241,241,241,241, 32, 32, 32, 60,227,241,241,241,241,241,241,241,241,227, 60, 32, 32, 46,227,241,241,241,102, 32, 60,227,241,241,241, 88, 32,116,241,241,241,199, 32,241, 32,185,241,241,241,116, 32, 32,143,241,241,241,241,241,241,241,241,241,241,130, 32,241, 32, 74,227,241,241,241,199,185,241,241,241,241,171, 32,241, 32, 88,241,241,241,241,241,241,241,241,241,241,199, 32,255,
254    32, 32,128,237,237,237,223,128, 87,128,237,237,237,237, 32, 32, 32,182,237,237,237,196,100,100,196,237,237,237,182, 32,237, 32,100,237,237,237,223, 59,196,237,237,237,141, 32, 32, 46,237,237,237,237, 59, 32, 46,237,237,237,237, 46, 32, 59,237,237,237,237,169, 87, 87,182,237,237,237,128, 32,237, 32,196,237,237,237, 87, 32, 32, 73,223,237,237,237, 73, 32, 32, 87,237,237,237,237,223,182,223,237,237,237,237, 46, 32,
255    32, 32,207,234,234,234,113, 32, 32, 32,234,234,234,234, 32, 32, 59,234,234,234,221, 45, 32, 32, 45,221,234,234,234, 59, 32,234, 32,140,234,234,234,221,234,234,234,194, 32, 32,234, 32,167,234,234,234,126, 32, 99,234,234,234,167, 32, 32,126,234,234,234,180, 32, 32, 32,126,234,234,234,126, 32, 32, 99,234,234,234,167, 32, 32, 32, 32,153,234,234,234,126, 32, 32, 86,234,234,234,207, 45, 32, 45,234,234,234,234, 86, 32,
256    32, 45,231,231,231,218, 32, 32, 32, 32,231,231,231,231, 32, 32, 98,231,231,231,165, 32,231,231, 32,165,231,231,231, 98, 32,231, 32, 45,191,231,231,231,231,231,218, 72, 32,231,231, 32, 98,231,231,231,165, 32,151,231,231,231,112, 32, 32,165,231,231,231,112, 32,231, 32,125,231,231,231,125, 32, 32,138,231,231,231,178,125,125,125,125,178,231,231,231,178, 32, 32, 85,231,231,231,178, 32,255, 32,191,231,231,231, 85, 32,
257    32, 84,227,227,227,175, 32, 32, 32, 32,227,227,227,227, 32, 32,123,227,227,227,123, 32,227,227, 32,123,227,227,227,123, 32,227,227, 32, 71,227,227,227,227,227,123, 32,227,227,227,227, 32,214,227,227,227, 45,201,227,227,227, 45, 32, 32,175,227,227,227, 84, 32,227, 32,123,227,227,227,123, 32, 32,175,227,227,227,227,227,227,227,227,227,227,227,227,175, 32, 32, 84,227,227,227,175, 32,255, 32,175,227,227,227, 84, 32,
258    32, 83,223,223,223,172, 32, 32, 32, 32,223,223,223,223, 32, 32,121,223,223,223,121, 32,223,223, 32,121,223,223,223,121, 32,223,223,223, 32,172,223,223,223,210, 45, 32,223,223,223,223, 32,147,223,223,223,134,223,223,223,147, 32,223, 32,172,223,223,223, 83, 32,223, 32,121,223,223,223,121, 32, 32,172,223,223,223,223,223,223,223,223,223,223,223,223,172, 32, 32, 83,223,223,223,172, 32,255, 32,172,223,223,223, 83, 32,
259    32, 82,220,220,220,170, 32, 32, 32, 32,220,220,220,220, 32, 32,120,220,220,220,120, 32,220,220, 32,120,220,220,220,120, 32,220,220, 32, 95,220,220,220,220,220,132, 32,220,220,220,220, 32, 95,220,220,220,207,220,220,220, 95, 32,220, 32,170,220,220,220,107, 32,220, 32,120,220,220,220,120, 32, 32,170,220,220,220,132, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 82,220,220,220,170, 32,255, 32,170,220,220,220, 82, 32,
260    32, 57,216,216,216,216, 32, 32, 32, 32,216,216,216,216, 32, 32, 81,216,216,216,167, 32,216,216, 32,155,216,216,216, 81, 32,216, 32, 57,204,216,216,216,216,216,216, 93, 32,216,216,216,216, 32,204,216,216,216,216,216,204, 32,216,216, 32,118,216,216,216,167, 32, 32, 32,130,216,216,216,118, 32, 32,118,216,216,216,191, 32, 32,216,216,216, 32, 32, 44, 57, 32, 32, 81,216,216,216,167, 32,255, 32,167,216,216,216, 81, 32,
261    32, 32,189,213,213,213,116, 32, 32, 80,213,213,213,213, 32, 32, 44,201,213,213,213, 68, 32, 32, 68,213,213,213,213, 44, 32, 32, 32,165,213,213,213,165,213,213,213,201, 44, 32,213,213,213, 32,129,213,213,213,213,213,141, 32,213,213, 32, 80,213,213,213,213,165,116,153,213,213,213,213,116, 32, 32, 56,213,213,213,213,153, 56, 32, 32, 32, 44,104,189,116, 32, 32, 80,213,213,213,165, 32,255, 32,165,213,213,213, 80, 32,
262    32, 32,139,210,210,210,210,174,174,210,210,210,210,210, 32, 32, 32,127,210,210,210,198,127,127,198,210,210,210,127, 32,210, 32,115,210,210,210,174, 44,139,210,210,210,163, 32, 32,210,210, 32, 68,210,210,210,210,210, 91, 32,210,210,210, 32,174,210,210,210,210,210,210,210,210,210,210,115, 32,210, 32,127,210,210,210,210,210,174,163,163,210,210,210,115, 32, 32, 79,210,210,210,163, 32,255, 32,163,210,210,210, 79, 32,
263    32, 32, 55,194,206,206,206,206,206,194,206,206,206,206, 32, 32, 32, 44,171,206,206,206,206,206,206,206,206,171, 44, 32, 32, 67,206,206,206,206, 67, 32, 44,183,206,206,206,113, 32,206,206,206, 32,183,206,206,206,194, 32,206,206,206,206, 32, 67,194,206,206,206,206,206,171,206,206,206,113, 32,206, 32, 32,136,206,206,206,206,206,206,206,206,206,206,113, 32, 32, 78,206,206,206,160, 32,255, 32,160,206,206,206, 78, 32,
264    32, 32, 32,100,192,203,203,203,157, 55,203,203,203,203, 32, 32,203, 32, 43,135,203,203,203,203,203,203,135, 43, 32, 32, 43,180,203,203,203,112, 32,203, 32, 66,203,203,203,203, 66, 32,203,203, 32,157,203,203,203,135, 32,203,203,203,203,203, 32, 43,112,157,157,123, 55,112,203,203,203,112, 32,203,203, 32, 32, 78,146,203,203,203,203,203,203,169,123, 55, 32, 32, 78,203,203,203,157, 32,255, 32,157,203,203,203, 78, 32,
265    32, 32, 32, 32, 54,110,110, 88, 32, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 54, 99,110,110, 99, 54, 32, 32,200,200, 32, 32, 32, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,200,200, 32, 54,200,200,200,200, 77, 32,200,200,200,200,200, 32, 32, 32, 32, 32, 32, 32,166,200,200,200, 88, 32,200,200,200,200, 32, 32, 32, 66, 77, 77, 77, 32, 32, 32, 32,200,200, 32, 32, 32, 32, 32, 32,255, 32, 32, 32, 32, 32, 32,255,
266    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,198,198,198,198, 32, 32, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198, 32,109,198,198,198,176, 32,198,198,198,198,198, 32, 98,121, 76, 32, 32, 54,109,198,198,198,198, 43, 32,198,198,198,198,198,198,198, 32, 32, 32, 32,198,198,198,198,198,198,198,198,198,198,198,198,255,255,255,255,255,255,255,255,
267    32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 33,159,191,191,191,117, 36, 41, 41, 41, 41, 41, 34,108,191,191,191,191,191,191,191,191,191,117, 36, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
268    32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 78, 38, 64,190,192,192,192, 66, 66, 41, 41, 85,128, 65, 34,107,190,192,192,192,192,192,192,192,139, 48, 39, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
269    32, 41, 97,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 96, 36, 95,147,148,148,139, 55, 41, 41, 85,121,128, 91, 38, 75,137,158,190,190,190,170,139, 97, 49, 37, 41, 41,105,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 97, 41,255,
270    32, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41, 36, 45, 45, 45, 48, 38, 41, 41, 76, 76, 76, 76, 76, 37, 34, 42, 33, 33, 33, 39, 48, 59, 41, 41, 41, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 41,255,
271    32, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,255,
272   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
273   255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
274 };
275
276 // doxygen logo alpha map
277 static unsigned char doxygen_a_png[3224] =
278 {
279     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
280     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
281     0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 66, 66, 66, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
282     0,  0,  0,  0,  0,  0,  0,  0,  0,145,247,247,247,247,145,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
283     0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
284     0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
285     0,  0,  0,  0,  0,  0,  0,  0,  0,247,247,247,247,247,247,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
286     0,  0,  0,  0, 16,115,181,181,132,247,247,247,247,247,247,  0,  0,  0,  0,  0, 99,148,181,181,148, 99,  0,  0,  0,  0, 16, 66, 66, 66, 66, 16,  0,  0,  0,  0, 66, 66, 66, 66, 33, 66, 66, 66, 66, 16,  0,  0,  0, 16, 66, 66, 66, 66,  0,  0,  0,  0, 99,165,181,148, 66, 33, 66, 66, 66, 33,  0,  0,  0,  0,  0,  0, 82,132,181,181,181,115, 66,  0,  0,  0,  0,  0, 16, 66, 66, 66, 49,  0, 66,148,181,148, 49,  0,  0,  0,
287     0,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247,  0,  0,  0,112,214,247,247,247,247,247,247,214,112,  0, 16,247,247,247,247,247,247, 46,  0,  0,145,247,247,247,247,247,247,247,247,247,247, 16,  0, 16,247,247,247,247,247, 66,  0, 63,165,247,247,247,247,247,247,247,247,247,247, 33,  0,  0,  0, 96,198,247,247,247,247,247,247,247,165, 63,  0,  0, 16,247,247,247,247,247,145,247,247,247,247,247,145,  0,  0,
288     0,  0,112,247,247,247,247,247,247,247,247,247,247,247,247,  0,  0,129,247,247,247,247,247,247,247,247,247,247,129,  0,181,247,247,247,247,247,148,  0,129,247,247,247,247,247,247,247,247,247,247,247,115,  0,115,247,247,247,247,247,165, 30,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247, 63,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247, 96,  0,
289     0, 16,247,247,247,247,247,247,247,247,247,247,247,247,247,  0, 79,247,247,247,247,247,247,247,247,247,247,247,247, 79, 79,247,247,247,247,247,247,129,247,247,247,247,247,247,129,247,247,247,247,247,198,  0,181,247,247,247,247,247, 99,145,247,247,247,247,247,247,247,247,247,247,247,247,115,  0, 96,247,247,247,247,247,247,247,247,247,247,247,247,165,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247,198,  0,
290     0,115,247,247,247,247,247,247,247,247,247,247,247,247,247,  0,181,247,247,247,247,247,247,247,247,247,247,247,247,181,  0,129,247,247,247,247,247,247,247,247,247,247,247,145, 16,247,247,247,247,247,247, 33,247,247,247,247,247,247, 33,247,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,198,247,247,247,247,247,198,181,247,247,247,247,247,247, 49, 66,247,247,247,247,247,247,247,247,247,247,247,247,247, 16,
291     0,214,247,247,247,247,247,129, 66,247,247,247,247,247,247, 33,247,247,247,247,247,247, 96, 96,247,247,247,247,247,247, 33,  0,145,247,247,247,247,247,247,247,247,247,198, 30,  0,165,247,247,247,247,247,115,247,247,247,247,247,165,115,247,247,247,247,247,181, 66,115,247,247,247,247,247,115, 82,247,247,247,247,247,165,115,115,148,247,247,247,247,247,115, 66,247,247,247,247,247,247,181,247,247,247,247,247,247, 66,
292    16,247,247,247,247,247,231,  0,  0,247,247,247,247,247,247, 82,247,247,247,247,247,165,  0,  0,165,247,247,247,247,247, 82,  0, 30,247,247,247,247,247,247,247,247,247, 96,  0,  0, 82,247,247,247,247,247,165,247,247,247,247,247, 99,165,247,247,247,247,247, 99,  0,115,247,247,247,247,247,115,132,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,198,247,247,247,247,247, 66,
293    66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0, 96,247,247,247,247,247,247,247,129,  0,  0,  0,  0,231,247,247,247,247,247,247,247,247,247,247, 16,181,247,247,247,247,247, 66,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
294    66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0,  0,181,247,247,247,247,247,247, 30,  0,  0,  0,  0,148,247,247,247,247,247,247,247,247,247,148,  0,181,247,247,247,247,247, 66,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
295    66,247,247,247,247,247,181,  0,  0,247,247,247,247,247,247,115,247,247,247,247,247,115,  0,  0,115,247,247,247,247,247,115,  0,  0,129,247,247,247,247,247,247,247,145,  0,  0,  0,  0, 82,247,247,247,247,247,247,247,247,247, 82,  0,181,247,247,247,247,247, 99,  0,115,247,247,247,247,247,115,181,247,247,247,247,247,247,247,247,247,247,247,247,247,181, 79, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
296    33,247,247,247,247,247,247, 14,  0,247,247,247,247,247,247, 66,247,247,247,247,247,181,  0,  0,165,247,247,247,247,247, 66,  0, 79,247,247,247,247,247,247,247,247,247,129,  0,  0,  0,  0,231,247,247,247,247,247,247,247,231,  0,  0,115,247,247,247,247,247,181,115,165,247,247,247,247,247,115,115,247,247,247,247,247,214, 63,  0,  0,  0, 16,112,247,247, 33, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
297     0,214,247,247,247,247,247,198,198,247,247,247,247,247,247, 16,247,247,247,247,247,247,132,132,247,247,247,247,247,247, 16, 14,181,247,247,247,247,247,247,247,247,247,247, 79,  0,  0,  0,132,247,247,247,247,247,247,247,148,  0,  0, 66,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 33,247,247,247,247,247,247,247,198,181,181,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
298     0,148,247,247,247,247,247,247,247,247,247,247,247,247,247,  0,132,247,247,247,247,247,247,247,247,247,247,247,247,145,  0,145,247,247,247,247,247,247,247,247,247,247,247,181, 14,  0,  0, 49,247,247,247,247,247,247,247, 82,  0,  0,  0,198,247,247,247,247,247,247,247,247,247,247,247,247,115,  0,145,247,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
299     0, 46,247,247,247,247,247,247,247,247,247,247,247,247,247,  0, 30,247,247,247,247,247,247,247,247,247,247,247,247, 30,112,247,247,247,247,247,247, 96,247,247,247,247,247,247,145,  0,  0,  0,214,247,247,247,247,247,231,  0,  0,  0,  0, 96,247,247,247,247,247,247,247,247,247,247,247,247,115,  0, 30,148,247,247,247,247,247,247,247,247,247,247,247,247,115, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
300     0,  0,129,247,247,247,247,247,247,247,247,247,247,247,247,  0,  0, 96,247,247,247,247,247,247,247,247,247,247, 96, 16,247,247,247,247,247,247,145,  0,112,247,247,247,247,247,247, 49,  0,  0,181,247,247,247,247,247,148,  0,  0,  0,  0,  0,129,247,247,247,247,247,247,247,247,247,247,247,115,  0,  0, 46,148,247,247,247,247,247,247,247,247,247,247,247, 33, 66,247,247,247,247,247,181,  0,181,247,247,247,247,247, 66,
301     0,  0,  0,129,247,247,247,247,181,145,247,247,247,247,145,  0,  0,  0, 46,148,247,247,247,247,247,247,148, 46,  0,  0,112,214,247,247,247,145, 14,  0,  0,145,247,247,247,247,145,  0,  0, 33,247,247,247,247,247,247, 66,  0,  0,  0,  0,  0, 99,132,115,181,181,132,198,247,247,247,247,247, 82,  0,  0,  0,  0, 66,165,247,247,247,247,247,247,198,132, 33,  0,  0,145,247,247,247,181, 79,  0, 79,181,247,247,247,145,  0,
302     0,  0,  0,  0, 33,115,115, 82,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33, 99,115,115, 99, 33,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,115,247,247,247,247,247,214,  0,  0,  0,  0,  0, 99,247,247,247,247,247,247,247,247,247,247,247,247, 16,  0,  0,  0,  0,  0,  0,  0, 49, 66, 66, 66,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
303     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,108,224,255,255,255,255,255,255,101,164,255,255,255,143,250,255,255,255,255,255,255,255,255,255,255,255, 98,170,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
304     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,136,251,255,255,255,255,255,255,101,130,255,255,255,153,250,255,255,255,255,255,255,255,255,255,255,121, 98,189,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
305     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,198,252,255,255,255,255,255,164,164,255,255,255,255,176,249,251,255,255,255,255,255,255,255,255,150, 86,192,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
306     0,165,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,164,198,255,255,255,255,201,133,164,255,255,255,255,255,145,203,255,255,255,255,255,255,255,117, 79,194,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,165,  0,
307     0, 66,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 73, 73,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 47, 70,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102, 66,  0,
308     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
309     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
310 };
311
312 // magnifying glass icon (raw png)
313 unsigned char mag_sel_png[] = {
314   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
315   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
316   0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
317   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
318   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
319   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
320   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
321   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
322   0x2a, 0xbd, 0x00, 0x00, 0x01, 0xb9, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
323   0xe4, 0x94, 0xbb, 0x8a, 0x22, 0x41, 0x14, 0x86, 0xbf, 0xda, 0x16, 0x3a,
324   0x10, 0xba, 0x03, 0x2f, 0x78, 0x03, 0x51, 0x11, 0x4c, 0xd4, 0x40, 0xd4,
325   0x37, 0x30, 0x31, 0x30, 0xe9, 0x07, 0xf0, 0x15, 0x14, 0x7c, 0x1e, 0x31,
326   0x37, 0x33, 0x11, 0x73, 0xe9, 0x56, 0x44, 0x84, 0x36, 0xe9, 0x40, 0x50,
327   0x54, 0x14, 0xc4, 0xc0, 0xa8, 0x6d, 0x50, 0x6a, 0x92, 0x1d, 0xd9, 0x9d,
328   0x99, 0x75, 0x0d, 0x26, 0x58, 0xd8, 0x3f, 0xaa, 0xe2, 0xfc, 0xf5, 0xd5,
329   0x39, 0x9c, 0x53, 0x25, 0xa4, 0x94, 0x7c, 0xa7, 0x7e, 0xf0, 0xcd, 0xfa,
330   0xf7, 0x81, 0xbe, 0xf7, 0xc5, 0xf9, 0x7c, 0x96, 0x93, 0xc9, 0x84, 0xe5,
331   0x72, 0xc9, 0x66, 0xb3, 0x21, 0x99, 0x4c, 0x92, 0xcf, 0xe7, 0xa9, 0x54,
332   0x2a, 0x04, 0x02, 0x01, 0xf1, 0x2a, 0x50, 0x48, 0x29, 0x39, 0x9d, 0x4e,
333   0x72, 0x30, 0x18, 0x60, 0x59, 0xd6, 0x27, 0x43, 0xb5, 0x5a, 0xa5, 0xd1,
334   0x68, 0x10, 0x0c, 0x06, 0xc5, 0xcb, 0x19, 0x4e, 0xa7, 0x53, 0x2c, 0xcb,
335   0x22, 0x95, 0x4a, 0x51, 0x2a, 0x95, 0xc8, 0x64, 0x32, 0xac, 0x56, 0x2b,
336   0x66, 0xb3, 0x19, 0x93, 0xc9, 0x84, 0x48, 0x24, 0x42, 0xbd, 0x5e, 0x7f,
337   0xbd, 0x64, 0xdb, 0xb6, 0x01, 0x28, 0x97, 0xcb, 0x54, 0x2a, 0x15, 0x34,
338   0x4d, 0x13, 0xa1, 0x50, 0x48, 0x2a, 0x8a, 0xc2, 0x7a, 0xbd, 0xc6, 0xb6,
339   0x6d, 0xea, 0xf5, 0x3a, 0xa3, 0xd1, 0x48, 0xf6, 0xfb, 0xfd, 0xc7, 0x61,
340   0xc3, 0x30, 0xa8, 0xd5, 0x6a, 0xe2, 0x53, 0x53, 0xb6, 0xdb, 0x2d, 0x00,
341   0xc5, 0x62, 0x11, 0x4d, 0xd3, 0x04, 0x80, 0xa6, 0x69, 0xa2, 0x50, 0x28,
342   0xf0, 0x6b, 0x1c, 0x10, 0x86, 0x61, 0x3c, 0x60, 0x80, 0xf8, 0xb2, 0xcb,
343   0x89, 0x44, 0x02, 0x00, 0xc7, 0x71, 0x00, 0xde, 0x27, 0x5d, 0xfe, 0xdc,
344   0x3f, 0xe2, 0x1f, 0xa0, 0xe2, 0x8f, 0x63, 0x93, 0xcb, 0xe5, 0x00, 0x18,
345   0x8f, 0xc7, 0x98, 0xa6, 0x89, 0xeb, 0xba, 0xd2, 0x34, 0x4d, 0xc6, 0xe3,
346   0x31, 0x00, 0xe9, 0x74, 0x1a, 0x80, 0x5a, 0xad, 0xf6, 0x80, 0x3e, 0xed,
347   0xf2, 0x7a, 0xbd, 0x96, 0xc3, 0xe1, 0x90, 0xf9, 0x7c, 0xfe, 0xa5, 0x29,
348   0x1c, 0x0e, 0xd3, 0xe9, 0x74, 0xd0, 0x75, 0x5d, 0x00, 0x8c, 0x46, 0xa3,
349   0x8f, 0x17, 0xfc, 0x0e, 0xf4, 0x3c, 0x4f, 0xee, 0x76, 0x3b, 0x16, 0x8b,
350   0x05, 0x8e, 0xe3, 0xb0, 0xdf, 0xef, 0x89, 0xc7, 0xe3, 0xa4, 0xd3, 0x69,
351   0x6c, 0xdb, 0xe6, 0x74, 0x3a, 0x11, 0x8d, 0x46, 0x69, 0xb7, 0xdb, 0x0f,
352   0xe8, 0xd3, 0x0c, 0x01, 0x3c, 0xcf, 0x93, 0xae, 0xeb, 0xe2, 0x79, 0x1e,
353   0xb7, 0xdb, 0x0d, 0x9f, 0xcf, 0x87, 0xa2, 0x28, 0x5c, 0x2e, 0x17, 0x7a,
354   0xbd, 0x1e, 0xc7, 0xe3, 0x91, 0x58, 0x2c, 0x46, 0xab, 0xd5, 0x7a, 0x0a,
355   0x7d, 0xbc, 0x14, 0x55, 0x55, 0x85, 0xaa, 0xaa, 0x9f, 0x0c, 0x7e, 0xbf,
356   0x5f, 0x36, 0x9b, 0x4d, 0xba, 0xdd, 0x2e, 0xd7, 0xeb, 0x95, 0xeb, 0xf5,
357   0x8a, 0xae, 0xeb, 0x7f, 0xcf, 0xf0, 0x99, 0x5c, 0xd7, 0x95, 0x87, 0xc3,
358   0x81, 0xfb, 0xfd, 0x4e, 0x36, 0x9b, 0x7d, 0xad, 0xe4, 0xff, 0xe7, 0xfb,
359   0x7a, 0x1b, 0x00, 0x59, 0xa8, 0xba, 0x68, 0xca, 0x4f, 0xc5, 0xa7, 0x00,
360   0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
361 };
362 unsigned int mag_sel_png_len = 563;
363
364 unsigned char mag_png[] = {
365   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
366   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
367   0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
368   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
369   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
370   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
371   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
372   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
373   0x2a, 0xbd, 0x00, 0x00, 0x01, 0x92, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
374   0xe4, 0x94, 0xbb, 0xaa, 0xea, 0x50, 0x10, 0x86, 0xbf, 0xec, 0x08, 0x29,
375   0x36, 0x24, 0x85, 0x17, 0xbc, 0x81, 0x18, 0x11, 0x6c, 0xd4, 0x42, 0x8c,
376   0x0f, 0x61, 0xe1, 0x2b, 0xf8, 0x0a, 0x0a, 0x3e, 0x8f, 0xf8, 0x0c, 0x36,
377   0x62, 0x1f, 0x92, 0x88, 0x88, 0x10, 0x9b, 0x14, 0x42, 0x44, 0x45, 0x41,
378   0x2c, 0xac, 0x92, 0x80, 0xb2, 0x4e, 0x73, 0x94, 0x03, 0xfb, 0xb0, 0x4d,
379   0xb1, 0x8b, 0x03, 0xe7, 0xaf, 0xd6, 0x62, 0xfe, 0xf5, 0x31, 0xc3, 0xcc,
380   0x1a, 0x49, 0x08, 0xc1, 0x4f, 0xea, 0x83, 0x1f, 0xd6, 0xbf, 0x0f, 0x4c,
381   0x3c, 0x0f, 0xd7, 0xeb, 0x55, 0x38, 0x8e, 0xc3, 0x66, 0xb3, 0x61, 0xb7,
382   0xdb, 0x51, 0x2a, 0x95, 0xa8, 0xd7, 0xeb, 0x18, 0x86, 0x41, 0x32, 0x99,
383   0x94, 0xe2, 0x02, 0x25, 0x21, 0x04, 0x97, 0xcb, 0x45, 0x4c, 0xa7, 0x53,
384   0x6c, 0xdb, 0xfe, 0x62, 0xe8, 0x74, 0x3a, 0xf4, 0x7a, 0x3d, 0x52, 0xa9,
385   0x94, 0x14, 0x3b, 0xc3, 0xc5, 0x62, 0x81, 0x6d, 0xdb, 0x94, 0xcb, 0x65,
386   0x5a, 0xad, 0x16, 0x95, 0x4a, 0x85, 0xed, 0x76, 0xcb, 0x72, 0xb9, 0xc4,
387   0x71, 0x1c, 0xb2, 0xd9, 0x2c, 0xdd, 0x6e, 0x37, 0x7e, 0xc9, 0xae, 0xeb,
388   0x02, 0xd0, 0x6e, 0xb7, 0x31, 0x0c, 0x03, 0x55, 0x55, 0xa5, 0x74, 0x3a,
389   0x2d, 0x64, 0x59, 0xc6, 0xf7, 0x7d, 0x5c, 0xd7, 0x8d, 0x0d, 0xfc, 0x00,
390   0xd8, 0xef, 0xf7, 0x00, 0x34, 0x9b, 0x4d, 0x54, 0x55, 0x95, 0x00, 0x54,
391   0x55, 0x95, 0x1a, 0x8d, 0x06, 0x7f, 0xc6, 0x63, 0x03, 0x8b, 0xc5, 0x22,
392   0x00, 0x9e, 0xe7, 0x01, 0x3c, 0x27, 0x5d, 0xfc, 0xbe, 0xbf, 0xe2, 0xb1,
393   0x81, 0xb5, 0x5a, 0x0d, 0x00, 0xd3, 0x34, 0xb1, 0x2c, 0x8b, 0x20, 0x08,
394   0x84, 0x65, 0x59, 0x98, 0xa6, 0x09, 0x80, 0xae, 0xeb, 0xaf, 0x07, 0xf3,
395   0xf9, 0xfc, 0x7d, 0x97, 0x7d, 0xdf, 0x17, 0xb3, 0xd9, 0x8c, 0xd5, 0x6a,
396   0xf5, 0x57, 0x53, 0x26, 0x93, 0x61, 0x34, 0x1a, 0xa1, 0x69, 0x9a, 0x14,
397   0x6b, 0x6c, 0xa2, 0x28, 0x12, 0x87, 0xc3, 0x81, 0xf5, 0x7a, 0x8d, 0xe7,
398   0x79, 0x1c, 0x8f, 0x47, 0x0a, 0x85, 0x02, 0xba, 0xae, 0xe3, 0xba, 0x2e,
399   0x97, 0xcb, 0x85, 0x5c, 0x2e, 0xc7, 0x70, 0x38, 0x7c, 0x0b, 0x95, 0x9e,
400   0xcb, 0x21, 0x8a, 0x22, 0x11, 0x04, 0x01, 0x51, 0x14, 0x71, 0xbf, 0xdf,
401   0x49, 0x24, 0x12, 0xc8, 0xb2, 0xcc, 0xed, 0x76, 0x63, 0x32, 0x99, 0x70,
402   0x3e, 0x9f, 0xc9, 0xe7, 0xf3, 0x0c, 0x06, 0x83, 0x6f, 0xa1, 0xaf, 0x9f,
403   0xa2, 0x28, 0x8a, 0xa4, 0x28, 0xca, 0x17, 0xc3, 0xe7, 0xe7, 0xa7, 0xe8,
404   0xf7, 0xfb, 0x8c, 0xc7, 0x63, 0xc2, 0x30, 0x24, 0x0c, 0x43, 0x34, 0x4d,
405   0x7b, 0x9f, 0xe1, 0x77, 0x0a, 0x82, 0x40, 0x9c, 0x4e, 0x27, 0x1e, 0x8f,
406   0x07, 0xd5, 0x6a, 0x35, 0x5e, 0xc9, 0xff, 0xcf, 0xfa, 0xfa, 0x35, 0x00,
407   0x70, 0xf3, 0xae, 0xcb, 0x89, 0xcd, 0xd2, 0x46, 0x00, 0x00, 0x00, 0x00,
408   0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
409 };
410 unsigned int mag_png_len = 524;
411
412 unsigned char search_l_png[] = {
413   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
414   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
415   0x08, 0x06, 0x00, 0x00, 0x00, 0x90, 0x8c, 0x2d, 0xb5, 0x00, 0x00, 0x00,
416   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
417   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
418   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
419   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
420   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
421   0x2a, 0xbd, 0x00, 0x00, 0x01, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
422   0xac, 0x54, 0x3d, 0xab, 0xda, 0x50, 0x18, 0x7e, 0xce, 0xc9, 0x39, 0x31,
423   0x4d, 0xfc, 0x40, 0x30, 0x46, 0x14, 0xec, 0x50, 0x44, 0x17, 0x2f, 0x9d,
424   0xba, 0x15, 0xda, 0xd1, 0xa1, 0x2e, 0xdd, 0x3b, 0x14, 0x4a, 0xa1, 0x7f,
425   0xa6, 0x74, 0xbd, 0x43, 0xff, 0x84, 0xfd, 0x05, 0x82, 0xda, 0xa5, 0x83,
426   0x1d, 0xdc, 0x8a, 0x88, 0xa0, 0x44, 0x83, 0xc6, 0x28, 0xad, 0x1f, 0x49,
427   0xde, 0x2e, 0x8d, 0x78, 0x6f, 0xaf, 0x34, 0x68, 0x9f, 0xed, 0xbc, 0x70,
428   0x1e, 0x9e, 0x8f, 0xf7, 0x1c, 0x46, 0x44, 0x38, 0x45, 0xaf, 0xd7, 0x63,
429   0xb6, 0x6d, 0xe7, 0x6d, 0xdb, 0x6e, 0xba, 0xae, 0xfb, 0x6e, 0xb3, 0xd9,
430   0xdc, 0x6c, 0xb7, 0xdb, 0x04, 0xe7, 0x1c, 0x8c, 0x31, 0xfc, 0x0b, 0x2c,
431   0x22, 0xec, 0x76, 0xbb, 0xcc, 0xf3, 0xbc, 0xcc, 0x68, 0x34, 0x7a, 0xed,
432   0xba, 0xee, 0x87, 0x6c, 0x36, 0x7b, 0x93, 0xcb, 0xe5, 0x44, 0x3a, 0x9d,
433   0x86, 0xa6, 0x69, 0x50, 0x14, 0x25, 0x3e, 0x61, 0xa7, 0xd3, 0x61, 0xf3,
434   0xf9, 0xfc, 0xc9, 0x78, 0x3c, 0xbe, 0xd5, 0x75, 0xfd, 0x79, 0xa5, 0x52,
435   0x11, 0xa6, 0x69, 0x22, 0x95, 0x4a, 0x41, 0xd3, 0x34, 0x08, 0x21, 0xc0,
436   0x18, 0x8b, 0x45, 0x28, 0x00, 0x60, 0xb5, 0x5a, 0xa5, 0x27, 0x93, 0xc9,
437   0xa7, 0x62, 0xb1, 0xf8, 0xb2, 0x5a, 0xad, 0x22, 0x9f, 0xcf, 0xc3, 0x30,
438   0x0c, 0x48, 0x29, 0xc1, 0x39, 0x47, 0x5c, 0xbb, 0x00, 0x20, 0xda, 0xed,
439   0x36, 0x9f, 0x4e, 0xa7, 0xaf, 0x4c, 0xd3, 0x7c, 0x51, 0xaf, 0xd7, 0x61,
440   0x59, 0x16, 0x74, 0x5d, 0x87, 0x94, 0x12, 0x97, 0x40, 0x2c, 0x16, 0x0b,
441   0x93, 0x88, 0xde, 0xd6, 0x6a, 0x35, 0xdd, 0xb2, 0x2c, 0x18, 0x86, 0x01,
442   0x21, 0x04, 0x2e, 0x05, 0xf7, 0x3c, 0xaf, 0x59, 0x2e, 0x97, 0x9f, 0x45,
443   0xca, 0x38, 0xe7, 0xb8, 0x06, 0x3c, 0x08, 0x82, 0x46, 0xa1, 0x50, 0x78,
444   0x74, 0xad, 0xb2, 0x23, 0xa1, 0x94, 0xf2, 0x69, 0x26, 0x93, 0xe1, 0x51,
445   0x66, 0xf7, 0xf7, 0xd2, 0xf7, 0xfd, 0x07, 0x2f, 0x9e, 0x9b, 0x73, 0x55,
446   0x55, 0xb3, 0x91, 0x55, 0xc6, 0x18, 0xc2, 0x30, 0xbc, 0x1b, 0xf2, 0x19,
447   0xd5, 0xe7, 0xe6, 0x5c, 0x4a, 0x39, 0x06, 0x70, 0x5c, 0x8b, 0xb8, 0xeb,
448   0x71, 0xd6, 0x32, 0x11, 0x75, 0xf6, 0xfb, 0xfd, 0xd1, 0xea, 0xd5, 0xa5,
449   0x10, 0xd1, 0xb7, 0xf5, 0x7a, 0x1d, 0x84, 0x61, 0x08, 0x22, 0xba, 0x9e,
450   0x50, 0x51, 0x94, 0xaf, 0x8e, 0xe3, 0xfc, 0xdc, 0xed, 0x76, 0xf8, 0x1f,
451   0xe0, 0x89, 0x44, 0xe2, 0xc7, 0x72, 0xb9, 0xfc, 0xee, 0x38, 0x0e, 0x7c,
452   0xdf, 0x3f, 0x5a, 0xbf, 0xdf, 0x76, 0x6c, 0xc2, 0x46, 0xa3, 0xf1, 0x2b,
453   0x08, 0x82, 0xdb, 0xe1, 0x70, 0xe8, 0x2c, 0x16, 0x0b, 0x04, 0x41, 0x00,
454   0x22, 0xba, 0xb8, 0x1c, 0xfe, 0x67, 0x05, 0xbe, 0x78, 0x9e, 0xf7, 0x79,
455   0x30, 0x18, 0x8c, 0x67, 0xb3, 0x19, 0x45, 0x25, 0x9d, 0x53, 0x49, 0x44,
456   0x38, 0x1c, 0x0e, 0x38, 0x2d, 0xf3, 0xce, 0x6f, 0x03, 0x60, 0x29, 0x84,
457   0xf8, 0xe8, 0x79, 0x9e, 0xdb, 0xef, 0xf7, 0xdf, 0x97, 0x4a, 0xa5, 0xc7,
458   0xd1, 0x53, 0x54, 0x55, 0x15, 0x52, 0xca, 0xbf, 0x14, 0x0b, 0x21, 0x1e,
459   0x8c, 0x87, 0x9d, 0x1e, 0x5a, 0xad, 0x96, 0x00, 0x50, 0x27, 0xa2, 0x37,
460   0xaa, 0xaa, 0x36, 0x0d, 0xc3, 0x28, 0x26, 0x93, 0x49, 0xa1, 0x69, 0x9a,
461   0xc2, 0x39, 0x8f, 0x95, 0xc1, 0xef, 0x01, 0x00, 0x35, 0xe5, 0xd5, 0x5e,
462   0xd0, 0xed, 0x0c, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
463   0xae, 0x42, 0x60, 0x82
464 };
465 unsigned int search_l_png_len = 604;
466
467 unsigned char search_m_png[] = {
468   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
469   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13,
470   0x08, 0x02, 0x00, 0x00, 0x00, 0x35, 0x5e, 0x4b, 0x4d, 0x00, 0x00, 0x00,
471   0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xd6, 0xd8, 0xd4, 0x4f, 0x58,
472   0x32, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66,
473   0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x41, 0x64, 0x6f, 0x62, 0x65, 0x20,
474   0x49, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x61, 0x64, 0x79, 0x71, 0xc9,
475   0x65, 0x3c, 0x00, 0x00, 0x00, 0x30, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
476   0x62, 0x2c, 0x2f, 0x2f, 0x67, 0x60, 0x60, 0x60, 0x3c, 0x7e, 0xfc, 0x38,
477   0x88, 0xfa, 0xf8, 0xf1, 0x23, 0x88, 0xfa, 0xff, 0xff, 0x3f, 0x90, 0x62,
478   0x62, 0x00, 0x03, 0x5a, 0x50, 0x2c, 0x10, 0x1b, 0x58, 0x6e, 0xdd, 0xba,
479   0x05, 0xa4, 0x00, 0x02, 0x0c, 0x00, 0xa5, 0x07, 0x0f, 0x3c, 0x7e, 0xe1,
480   0x45, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
481   0x60, 0x82
482 };
483 unsigned int search_m_png_len = 158;
484
485 unsigned char search_r_png[] = {
486   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
487   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13,
488   0x08, 0x06, 0x00, 0x00, 0x00, 0x9d, 0x92, 0x5d, 0xf2, 0x00, 0x00, 0x00,
489   0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b,
490   0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48,
491   0x52, 0x4d, 0x00, 0x00, 0x6d, 0x98, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x00,
492   0xe0, 0x38, 0x00, 0x00, 0x82, 0xd5, 0x00, 0x00, 0x7a, 0x07, 0x00, 0x00,
493   0xca, 0xb4, 0x00, 0x00, 0x33, 0x44, 0x00, 0x00, 0x1c, 0x76, 0x84, 0x36,
494   0x2a, 0xbd, 0x00, 0x00, 0x01, 0xea, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda,
495   0xa4, 0xd4, 0xbf, 0xaa, 0x1a, 0x41, 0x14, 0x06, 0xf0, 0x6f, 0xf6, 0x9f,
496   0xb2, 0x0a, 0x6b, 0xa5, 0x56, 0x8b, 0xa4, 0x92, 0xd4, 0x69, 0x7c, 0x03,
497   0xb1, 0x59, 0x49, 0x11, 0x52, 0xdf, 0xbc, 0x43, 0xcc, 0x2b, 0xa4, 0x4c,
498   0x97, 0x67, 0x08, 0xa4, 0x11, 0x2c, 0x52, 0x5c, 0x42, 0x24, 0x60, 0x8a,
499   0x34, 0x29, 0x42, 0x50, 0x41, 0x21, 0xa0, 0x97, 0xd5, 0x55, 0xb3, 0xbb,
500   0xee, 0xb2, 0xce, 0xee, 0xcc, 0x49, 0x91, 0x28, 0xc2, 0x0d, 0xe6, 0xaa,
501   0xa7, 0x9d, 0xc3, 0x8f, 0x73, 0x98, 0xf9, 0x86, 0x75, 0x3a, 0x1d, 0xc2,
502   0x89, 0x12, 0x42, 0x24, 0xf9, 0x7c, 0x7e, 0x5a, 0x2c, 0x16, 0x3f, 0x96,
503   0x4a, 0xa5, 0x5e, 0xb5, 0x5a, 0xfd, 0x52, 0x2e, 0x97, 0xfd, 0x46, 0xa3,
504   0x21, 0x8e, 0xfb, 0xd8, 0x60, 0x30, 0x38, 0x09, 0x65, 0x59, 0x86, 0x24,
505   0x49, 0x10, 0x04, 0x81, 0xf0, 0x3c, 0x6f, 0xb3, 0xd9, 0x6c, 0x7e, 0x58,
506   0x96, 0x75, 0x5b, 0xab, 0xd5, 0xde, 0x34, 0x9b, 0xcd, 0x5f, 0x07, 0xc8,
507   0xf7, 0xfd, 0x93, 0x90, 0x94, 0xf2, 0x80, 0x85, 0x61, 0x88, 0xe5, 0x72,
508   0x49, 0xe3, 0xf1, 0x58, 0xc6, 0x71, 0xfc, 0xc1, 0xb6, 0xed, 0xe7, 0x8e,
509   0xe3, 0x84, 0x00, 0xc0, 0xa4, 0x94, 0x27, 0x21, 0x22, 0x82, 0x94, 0x12,
510   0x52, 0x4a, 0xa4, 0x69, 0x8a, 0x28, 0x8a, 0xb0, 0x58, 0x2c, 0x30, 0x1c,
511   0x0e, 0x85, 0xeb, 0xba, 0xef, 0x6b, 0xb5, 0xda, 0x4d, 0xab, 0xd5, 0x8a,
512   0x34, 0xc6, 0xd8, 0x29, 0x07, 0x8c, 0x31, 0x28, 0x8a, 0x02, 0x22, 0x82,
513   0xae, 0xeb, 0x30, 0x0c, 0x03, 0xb9, 0x5c, 0x0e, 0x86, 0x61, 0xa8, 0x52,
514   0xca, 0xa7, 0xf3, 0xf9, 0xfc, 0x67, 0xbf, 0xdf, 0x7f, 0xa5, 0xe0, 0x81,
515   0xc5, 0x18, 0x03, 0x63, 0x0c, 0x9a, 0xa6, 0xa1, 0x50, 0x28, 0xa0, 0x52,
516   0xa9, 0xa0, 0x5e, 0xaf, 0x6b, 0x00, 0x5e, 0xac, 0xd7, 0xeb, 0x47, 0x0f,
517   0x86, 0x8e, 0x41, 0x55, 0x55, 0x61, 0x9a, 0x26, 0x2a, 0x95, 0x0a, 0x6c,
518   0xdb, 0xb6, 0x82, 0x20, 0x78, 0x76, 0x36, 0xb4, 0xc7, 0xf6, 0x93, 0x55,
519   0xab, 0x55, 0x26, 0x84, 0x78, 0xac, 0x1c, 0x5f, 0xf3, 0xb9, 0xa5, 0xeb,
520   0x3a, 0x2c, 0xcb, 0x82, 0xae, 0xeb, 0xbb, 0x03, 0xa4, 0x69, 0xda, 0xd9,
521   0x53, 0x29, 0x8a, 0x02, 0xd3, 0x34, 0x99, 0x61, 0x18, 0xcb, 0x8b, 0x56,
522   0x3b, 0xc6, 0xfe, 0x4e, 0x76, 0x77, 0x15, 0x44, 0x44, 0xe0, 0x9c, 0x0b,
523   0x22, 0xfa, 0xaa, 0x5c, 0x83, 0x48, 0x29, 0x11, 0x86, 0xe1, 0x86, 0x88,
524   0xbe, 0x5f, 0x35, 0xd1, 0x6e, 0xb7, 0x83, 0xe7, 0x79, 0x3d, 0x55, 0x55,
525   0x7d, 0xd0, 0x05, 0x25, 0xa5, 0x24, 0xce, 0x39, 0x4d, 0x26, 0x93, 0x45,
526   0xb7, 0xdb, 0x7d, 0x42, 0x44, 0x50, 0x2e, 0x59, 0x49, 0x08, 0x81, 0xf5,
527   0x7a, 0x9d, 0x4c, 0xa7, 0xd3, 0x77, 0x42, 0x88, 0x6f, 0x00, 0xa0, 0xed,
528   0x0f, 0xb3, 0x2c, 0x3b, 0xe4, 0xe9, 0x5f, 0xf9, 0x23, 0xfa, 0x93, 0x6d,
529   0xce, 0x39, 0x56, 0xab, 0x95, 0x18, 0x0e, 0x87, 0x9f, 0x82, 0x20, 0x78,
530   0xdd, 0x6e, 0xb7, 0xd3, 0x7b, 0xe9, 0x27, 0xa2, 0x7b, 0x08, 0x11, 0x21,
531   0x4d, 0x53, 0x70, 0xce, 0x11, 0xc7, 0xb1, 0x74, 0x5d, 0xd7, 0x9f, 0xcd,
532   0x66, 0x3d, 0xce, 0xf9, 0x4b, 0xc7, 0x71, 0xee, 0x0e, 0xef, 0x70, 0x34,
533   0x1a, 0xe1, 0x7f, 0xff, 0x51, 0x92, 0x24, 0xd8, 0x6e, 0xb7, 0x61, 0x14,
534   0x45, 0x9f, 0x39, 0xe7, 0x6f, 0x19, 0x63, 0xb7, 0x8e, 0xe3, 0x44, 0xc7,
535   0x7d, 0xbf, 0x07, 0x00, 0x5f, 0x77, 0x46, 0x8c, 0x30, 0x2c, 0xd8, 0x9d,
536   0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
537 };
538 unsigned int search_r_png_len = 612;
539
540 static unsigned char close_png[] = {
541   0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
542   0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b,
543   0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0xac, 0x77, 0x26, 0x00, 0x00, 0x00,
544   0xd8, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x75, 0x51, 0xbd, 0x12, 0x46,
545   0x40, 0x0c, 0xdc, 0x18, 0x15, 0x0a, 0x14, 0x14, 0x1a, 0x43, 0xeb, 0x35,
546   0xbc, 0x7f, 0xa7, 0x43, 0x67, 0x06, 0x33, 0x28, 0xd0, 0xde, 0x77, 0x7b,
547   0x23, 0x2a, 0xdf, 0x16, 0x97, 0x9f, 0xdb, 0xcb, 0x26, 0x39, 0xc1, 0x83,
548   0x7d, 0xdf, 0xcd, 0xb2, 0x2c, 0xd8, 0xb6, 0x0d, 0xe7, 0x79, 0x22, 0x8a,
549   0x22, 0xc4, 0x71, 0x8c, 0x3c, 0xcf, 0x91, 0xa6, 0xa9, 0x90, 0xe6, 0x8e,
550   0x69, 0x9a, 0xcc, 0x38, 0x8e, 0xb8, 0xae, 0x4b, 0xdf, 0xbe, 0x36, 0x0c,
551   0x43, 0x94, 0x65, 0x89, 0xa2, 0x28, 0xc4, 0x3b, 0x8e, 0xe3, 0x2f, 0x91,
552   0x2f, 0xa8, 0xc2, 0x42, 0x56, 0xd1, 0x78, 0xf3, 0x3c, 0xbb, 0x04, 0x2f,
553   0xda, 0xb6, 0x45, 0x55, 0x55, 0x74, 0x9d, 0x65, 0x2c, 0x22, 0xb8, 0xef,
554   0x1b, 0xeb, 0xba, 0xc2, 0x67, 0x8f, 0x4c, 0x10, 0x7d, 0xdf, 0xa3, 0xae,
555   0x6b, 0xe7, 0xd3, 0x32, 0x56, 0x90, 0xe7, 0x53, 0x46, 0x31, 0x0c, 0x83,
556   0x73, 0x95, 0xa8, 0x31, 0x93, 0x9c, 0xc7, 0xe3, 0xd4, 0x0a, 0xb6, 0xa0,
557   0x44, 0x5a, 0xc6, 0xc6, 0x18, 0x77, 0xcd, 0x41, 0xbd, 0x24, 0x49, 0x94,
558   0xfb, 0x12, 0x59, 0x51, 0x5b, 0xd2, 0x16, 0xed, 0xfa, 0x20, 0xdc, 0x6f,
559   0xd7, 0x75, 0x9f, 0x6b, 0xd3, 0x2a, 0x41, 0x10, 0xa0, 0x69, 0x1a, 0x57,
560   0x59, 0x28, 0x47, 0x99, 0x2f, 0x30, 0xcf, 0x7b, 0xfb, 0x41, 0xcf, 0x1a,
561   0x2c, 0xeb, 0xeb, 0x07, 0x29, 0x9d, 0x65, 0x19, 0x6c, 0xab, 0x6e, 0x5d,
562   0x3f, 0x07, 0x0a, 0x79, 0x90, 0x0e, 0x11, 0x45, 0xc2, 0x00, 0x00, 0x00,
563   0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
564 };
565 static unsigned int close_png_len = 273;
566
567
568 static unsigned char closed_png[81] =
569 {
570   0,  0,  0,  0,142,  0,  0,  0,  0,
571   0,  0,  0,  0,142,142,  0,  0,  0,
572   0,  0,  0,  0,142,142,142,  0,  0,
573   0,  0,  0,  0,142,142,142,142,  0,
574   0,  0,  0,  0,142,142,142,142,142,
575   0,  0,  0,  0,142,142,142,142,  0,
576   0,  0,  0,  0,142,142,142,  0,  0,
577   0,  0,  0,  0,142,142,  0,  0,  0,
578   0,  0,  0,  0,142,  0,  0,  0,  0
579 };
580
581 static unsigned char closed_a_png[81] =
582 {
583   0,  0,  0,  0,255,  0,  0,  0,  0,
584   0,  0,  0,  0,255,255,  0,  0,  0,
585   0,  0,  0,  0,255,255,255,  0,  0,
586   0,  0,  0,  0,255,255,255,255,  0,
587   0,  0,  0,  0,255,255,255,255,255,
588   0,  0,  0,  0,255,255,255,255,  0,
589   0,  0,  0,  0,255,255,255,  0,  0,
590   0,  0,  0,  0,255,255,  0,  0,  0,
591   0,  0,  0,  0,255,  0,  0,  0,  0
592 };
593
594 static unsigned char open_png[81] =
595 {
596     0,  0,  0,  0,  0,  0,  0,  0,  0,
597     0,  0,  0,  0,  0,  0,  0,  0,  0,
598     0,  0,  0,  0,  0,  0,  0,  0,  0,
599     0,  0,  0,  0,  0,  0,  0,  0,  0,
600   142,142,142,142,142,142,142,142,142,
601     0,142,142,142,142,142,142,142,  0,
602     0,  0,142,142,142,142,142,  0,  0,
603     0,  0,  0,142,142,142,  0,  0,  0,
604     0,  0,  0,  0,142,  0,  0,  0,  0
605 };
606
607 static unsigned char open_a_png[81] =
608 {
609     0,  0,  0,  0,  0,  0,  0,  0,  0,
610     0,  0,  0,  0,  0,  0,  0,  0,  0,
611     0,  0,  0,  0,  0,  0,  0,  0,  0,
612     0,  0,  0,  0,  0,  0,  0,  0,  0,
613   255,255,255,255,255,255,255,255,255,
614     0,255,255,255,255,255,255,255,  0,
615     0,  0,255,255,255,255,255,  0,  0,
616     0,  0,  0,255,255,255,  0,  0,  0,
617     0,  0,  0,  0,255,  0,  0,  0,  0
618 };
619
620 static unsigned char bdwn_png[7*8] =
621 {
622     0,  0,  0,142,  0,  0,  0,
623     0,  0,  0,142,  0,  0,  0,
624     0,  0,  0,142,  0,  0,  0,
625   142,  0,  0,142,  0,  0,142,
626   142,142,  0,142,  0,142,142,
627   142,142,142,142,142,142,142,
628     0,142,142,142,142,142,  0,
629     0,  0,142,142,142,  0,  0,
630 };
631
632 static unsigned char bdwn_a_png[7*8] =
633 {
634     0,  0,  0,255,  0,  0,  0,
635     0,  0,  0,255,  0,  0,  0,
636     0,  0,  0,255,  0,  0,  0,
637   128,  0,  0,255,  0,  0,128,
638   255,128,  0,255,  0,128,255,
639   128,255,128,255,128,255,128,
640     0,128,255,255,255,128,  0,
641     0,  0,128,255,128,  0,  0,
642 };
643
644 static unsigned char sync_on_png[576] =
645 {
646   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
647   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
648   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
649   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
650   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
651   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
652   128,128,128,128,128,128,128,128,128,138,128,128,128,128,133,128,128,128,128,128,128,128,128,128,
653   128,128,128,128,128,128,128,129,205,186,128,128,128,128,160,210,134,128,128,128,128,128,128,128,
654   128,128,128,128,128,128,139,217,255,181,128,128,128,128,152,255,229,147,128,128,128,128,128,128,
655   128,128,128,128,128,156,236,255,255,181,128,128,128,128,152,255,255,243,164,128,128,128,128,128,
656   128,128,128,128,175,249,255,255,255,223,196,198,198,197,211,255,255,255,253,186,128,128,128,128,
657   128,128,133,202,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,214,137,128,128,
658   128,128,135,217,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,225,140,128,128,
659   128,128,128,128,189,255,255,255,255,238,224,225,225,224,232,255,255,255,255,201,131,128,128,128,
660   128,128,128,128,128,167,245,255,255,183,128,128,128,128,155,255,255,250,179,128,128,128,128,128,
661   128,128,128,128,128,128,150,231,255,188,128,128,128,128,161,255,238,158,128,128,128,128,128,128,
662   128,128,128,128,128,128,128,136,216,188,128,128,128,128,161,223,142,128,128,128,128,128,128,128,
663   128,128,128,128,128,128,128,128,130,141,128,128,128,128,135,132,128,128,128,128,128,128,128,128,
664   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
665   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
666   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
667   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
668   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
669   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
670 };
671
672 static unsigned char sync_off_png[576] =
673 {
674   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
675   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
676   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
677   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
678   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
679   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
680   128,128,128,128,128,128,128,128,138,128,128,128,128,128,128,133,128,128,128,128,128,128,128,128,
681   128,128,128,128,128,128,129,205,186,128,128,128,128,128,128,160,210,134,128,128,128,128,128,128,
682   128,128,128,128,128,139,217,255,181,128,128,128,128,128,128,152,255,229,147,128,128,128,128,128,
683   128,128,128,128,156,236,255,255,181,128,128,128,128,128,128,152,255,255,243,164,128,128,128,128,
684   128,128,128,175,249,255,255,255,223,196,198,198,128,128,197,211,255,255,255,253,186,128,128,128,
685   128,128,202,255,255,255,255,255,255,255,255,225,128,128,255,255,255,255,255,255,255,214,128,128,
686   128,128,217,255,255,255,255,255,255,255,255,128,128,198,255,255,255,255,255,255,255,225,128,128,
687   128,128,128,189,255,255,255,255,238,224,225,128,128,225,224,232,255,255,255,255,201,128,128,128,
688   128,128,128,128,167,245,255,255,183,128,128,128,128,128,128,155,255,255,250,179,128,128,128,128,
689   128,128,128,128,128,150,231,255,188,128,128,128,128,128,128,161,255,238,158,128,128,128,128,128,
690   128,128,128,128,128,128,136,216,188,128,128,128,128,128,128,161,223,142,128,128,128,128,128,128,
691   128,128,128,128,128,128,128,130,141,128,128,128,128,128,128,135,132,128,128,128,128,128,128,128,
692   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
693   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
694   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
695   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
696   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
697   128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128
698 };
699
700 static unsigned char sync_a_png[576] =
701 {
702     0,  0,  0,  0,  0,  0,  0, 29, 98,157,207,231,234,211,164,104, 38,  0,  0,  0,  0,  0,  0,  0,
703     0,  0,  0,  0,  0, 21,143,234,255,255,255,255,255,255,255,255,244,155, 33,  0,  0,  0,  0,  0,
704     0,  0,  0,  0, 70,221,255,255,255,255,255,255,255,255,255,255,255,255,235, 93,  0,  0,  0,  0,
705     0,  0,  0, 92,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,116,  0,  0,  0,
706     0,  0, 68,251,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 96,  0,  0,
707     0, 20,225,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,243, 41,  0,
708     0,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,172,  1,
709    28,238,255,255,255,255,255,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 42,
710    99,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,133,
711   160,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,204,
712   212,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,224,
713   234,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,237,255,236,
714   235,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,230,255,236,
715   216,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,226,
716   168,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,208,
717   107,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,147,
718    39,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 53,
719     0,159,255,255,255,255,255,255,251,255,255,255,255,255,255,255,255,255,255,255,255,255,190,  3,
720     0, 31,239,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,249, 54,  0,
721     0,  0, 91,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,119,  0,  0,
722     0,  0,  0,116,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,145,  0,  0,  0,
723     0,  0,  0,  0, 98,240,255,255,255,255,255,255,255,255,255,255,255,255,248,119,  0,  0,  0,  0,
724     0,  0,  0,  0,  0, 45,168,252,255,255,255,255,255,255,255,255,255,184, 58,  0,  0,  0,  0,  0,
725     0,  0,  0,  0,  0,  0,  0, 45,131,201,222,234,236,224,204,142, 54,  0,  0,  0,  0,  0,  0,  0
726 };
727
728
729 //------------------------------------------------------------------------
730
731 static const char tabs_css[] = 
732 ".tabs, .tabs2, .tabs3 {\n"
733 "    background-image: url('tab_b.png');\n"
734 "    width: 100%;\n"
735 "    z-index: 101;\n"
736 "    font-size: 13px;\n"
737 "    font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;\n"
738 "}\n"
739 "\n"
740 ".tabs2 {\n"
741 "    font-size: 10px;\n"
742 "}\n"
743 ".tabs3 {\n"
744 "    font-size: 9px;\n"
745 "}\n"
746 "\n"
747 ".tablist {\n"
748 "    margin: 0;\n"
749 "    padding: 0;\n"
750 "    display: table;\n"
751 "}\n"
752 "\n"
753 ".tablist li {\n"
754 "    float: left;\n"
755 "    display: table-cell;\n"
756 "    background-image: url('tab_b.png');\n"
757 "    line-height: 36px;\n"
758 "    list-style: none;\n"
759 "}\n"
760 "\n"
761 ".tablist a {\n"
762 "    display: block;\n"
763 "    padding: 0 20px;\n"
764 "    font-weight: bold;\n"
765 "    background-image:url('tab_s.png');\n"
766 "    background-repeat:no-repeat;\n"
767 "    background-position:right;\n"
768 "    color: ##30;\n"
769 "    text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);\n"
770 "    text-decoration: none;\n"
771 "    outline: none;\n"
772 "}\n"
773 "\n"
774 ".tabs3 .tablist a {\n"
775 "    padding: 0 10px;\n"
776 "}\n"
777 "\n"
778 ".tablist a:hover {\n"
779 "    background-image: url('tab_h.png');\n"
780 "    background-repeat:repeat-x;\n"
781 "    color: #fff;\n"
782 "    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
783 "    text-decoration: none;\n"
784 "}\n"
785 "\n"
786 ".tablist li.current a {\n"
787 "    background-image: url('tab_a.png');\n"
788 "    background-repeat:repeat-x;\n"
789 "    color: #fff;\n"
790 "    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);\n"
791 "}\n"
792 ;
793
794 struct img_data_item
795 {
796   const char *name;
797   unsigned char *content;
798   unsigned int len;
799 };
800
801
802 static void writeImgData(const char *dir,img_data_item *data)
803 {
804   while (data->name)
805   {
806     QCString fileName;
807     fileName=(QCString)dir+"/"+data->name;
808     QFile f(fileName);
809     if (f.open(IO_WriteOnly))
810     {
811       f.writeBlock((char*)data->content,
812                     data->len>0 ? data->len : qstrlen((char*)data->content));
813     }
814     else
815     {
816       fprintf(stderr,"Warning: Cannot open file %s for writing\n",data->name);
817     }
818     Doxygen::indexList->addImageFile(QCString("/search/")+data->name);
819     data++;
820   }
821 }
822
823 static ColoredImgDataItem colored_tab_data[] =
824 {
825   // file_name      W   H  luma_data        alpha_data
826   { "tab_a.png",    1, 36, tab_a_png,       0 },
827   { "tab_b.png",    1, 36, tab_b_png,       0 },
828   { "tab_h.png",    1, 36, tab_h_png,       0 },
829   { "tab_s.png",    1, 36, tab_s_png,       0 },
830   { "nav_h.png",    1, 12, header_png,      0 },
831   { "nav_f.png",    1, 56, func_header_png, 0 },
832   { "bc_s.png",     8, 30, bc_s_png,        bc_s_a_png },
833   { "doxygen.png", 104,31, doxygen_png,     doxygen_a_png },
834   { "closed.png",   9,  9, closed_png,      closed_a_png },
835   { "open.png",     9,  9, open_png,        open_a_png },
836   { "bdwn.png",     7,  8, bdwn_png,        bdwn_a_png },
837   { "sync_on.png", 24, 24, sync_on_png,     sync_a_png },
838   { "sync_off.png",24, 24, sync_off_png,    sync_a_png },
839   { 0, 0, 0, 0, 0 }
840 };
841
842 static img_data_item search_client_data[] =
843 {
844   // file_name          raw_data          num bytes
845   { "mag_sel.png",      mag_sel_png,      mag_sel_png_len  },
846   { "search_l.png",     search_l_png,     search_l_png_len },
847   { "search_m.png",     search_m_png,     search_m_png_len },
848   { "search_r.png",     search_r_png,     search_r_png_len },
849   { "close.png",        close_png,        close_png_len    },
850   { 0, 0, 0 }
851 };
852
853 static img_data_item search_server_data[] =
854 {
855   // file_name          raw_data          num bytes
856   { "mag.png",          mag_png,          mag_png_len      },
857   { "search_l.png",     search_l_png,     search_l_png_len },
858   { "search_m.png",     search_m_png,     search_m_png_len },
859   { "search_r.png",     search_r_png,     search_r_png_len },
860   { 0, 0, 0 }
861 };
862
863 //------------------------------------------------------------------------
864
865 static void writeClientSearchBox(FTextStream &t,const char *relPath)
866 {
867   t << "        <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
868   t << "        <span class=\"left\">\n";
869   t << "          <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
870   t << "               onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
871   t << "               onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
872   t << "               alt=\"\"/>\n";
873   t << "          <input type=\"text\" id=\"MSearchField\" value=\"" 
874     << theTranslator->trSearch() << "\" accesskey=\"S\"\n";
875   t << "               onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
876   t << "               onblur=\"searchBox.OnSearchFieldFocus(false)\" \n";
877   t << "               onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
878   t << "          </span><span class=\"right\">\n";
879   t << "            <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
880     << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
881   t << "          </span>\n";
882   t << "        </div>\n";
883 }
884
885 static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlightSearch)
886 {
887   static bool externalSearch = Config_getBool("EXTERNAL_SEARCH");
888   t << "        <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
889   t << "          <div class=\"left\">\n";
890   t << "            <form id=\"FSearchBox\" action=\"" << relPath;
891   if (externalSearch)
892   {
893     t << "search" << Doxygen::htmlFileExtension;
894   }
895   else
896   {
897     t << "search.php";
898   }
899   t << "\" method=\"get\">\n";
900   t << "              <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
901   if (!highlightSearch)
902   {
903     t << "              <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
904       << theTranslator->trSearch() << "\" size=\"20\" accesskey=\"S\" \n";
905     t << "                     onfocus=\"searchBox.OnSearchFieldFocus(true)\" \n";
906     t << "                     onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
907     t << "            </form>\n";
908     t << "          </div><div class=\"right\"></div>\n";
909     t << "        </div>\n";
910   }
911 }
912
913 //------------------------------------------------------------------------
914
915 /// substitute all occurrences of \a src in \a s by \a dst
916 QCString substitute(const char *s,const char *src,const char *dst)
917 {
918   if (s==0 || src==0) return s;
919   const char *p, *q;
920   int srcLen = qstrlen(src);
921   int dstLen = dst ? qstrlen(dst) : 0;
922   int resLen;
923   if (srcLen!=dstLen)
924   {
925     int count;
926     for (count=0, p=s; (q=strstr(p,src))!=0; p=q+srcLen) count++;
927     resLen = (int)(p-s)+qstrlen(p)+count*(dstLen-srcLen);
928   }
929   else // result has same size as s
930   {
931     resLen = qstrlen(s);
932   }
933   QCString result(resLen+1);
934   char *r;
935   for (r=result.data(), p=s; (q=strstr(p,src))!=0; p=q+srcLen)
936   {
937     int l = (int)(q-p);
938     memcpy(r,p,l);
939     r+=l;
940     if (dst) memcpy(r,dst,dstLen);
941     r+=dstLen;
942   }
943   qstrcpy(r,p);
944   //printf("substitute(%s,%s,%s)->%s\n",s,src,dst,result.data());
945   return result;
946 }
947 //----------------------------------------------------------------------
948
949 /// Clear a text block \a s from \a begin to \a end markers
950 QCString clearBlock(const char *s,const char *begin,const char *end)
951 {
952   if (s==0 || begin==0 || end==0) return s;
953   const char *p, *q;
954   int beginLen = qstrlen(begin);
955   int endLen = qstrlen(end);
956   int resLen = 0;
957   for (p=s; (q=strstr(p,begin))!=0; p=q+endLen)
958   {
959     resLen+=(int)(q-p);
960     p=q+beginLen;
961     if ((q=strstr(p,end))==0)
962     {
963       resLen+=beginLen;
964       break;
965     }
966   }
967   resLen+=qstrlen(p);
968   // resLen is the length of the string without the marked block
969
970   QCString result(resLen+1);
971   char *r;
972   for (r=result.data(), p=s; (q=strstr(p,begin))!=0; p=q+endLen)
973   {
974     int l = (int)(q-p);
975     memcpy(r,p,l);
976     r+=l;
977     p=q+beginLen;
978     if ((q=strstr(p,end))==0)
979     {
980       memcpy(r,begin,beginLen);
981       r+=beginLen;
982       break;
983     }
984   }
985   qstrcpy(r,p);
986   return result;
987 }
988 //----------------------------------------------------------------------
989
990 QCString selectBlock(const QCString& s,const QCString &name,bool enable)
991 {
992   const QCString begin = "<!--BEGIN " + name + "-->";
993   const QCString end = "<!--END " + name + "-->";
994   const QCString nobegin = "<!--BEGIN !" + name + "-->";
995   const QCString noend = "<!--END !" + name + "-->";
996
997   QCString result = s;
998   if (enable)
999   {
1000     result = substitute(result, begin, "");
1001     result = substitute(result, end, "");
1002     result = clearBlock(result, nobegin, noend);
1003   }
1004   else
1005   {
1006     result = substitute(result, nobegin, "");
1007     result = substitute(result, noend, "");
1008     result = clearBlock(result, begin, end);
1009   }
1010
1011   return result;
1012 }
1013
1014 static QCString getSearchBox(bool serverSide, QCString relPath, bool highlightSearch)
1015 {
1016   QGString result;
1017   FTextStream t(&result);
1018   if (serverSide) {
1019     writeServerSearchBox(t, relPath, highlightSearch);
1020   }
1021   else {
1022      writeClientSearchBox(t, relPath);
1023   }
1024   return QCString(result);
1025 }
1026
1027 static QCString removeEmptyLines(const QCString &s)
1028 {
1029   BufStr out(s.length()+1);
1030   char *p=s.data();
1031   if (p)
1032   {
1033     char c;
1034     while ((c=*p++))
1035     {
1036       if (c=='\n')
1037       {
1038         char *e = p;
1039         while (*e==' ' || *e=='\t') e++;
1040         if (*e=='\n') 
1041         {
1042           p=e;
1043         }
1044         else out.addChar(c);
1045       }
1046       else
1047       {
1048         out.addChar(c);
1049       }
1050     }
1051   }
1052   out.addChar('\0');
1053   //printf("removeEmptyLines(%s)=%s\n",s.data(),out.data());
1054   return out.data();
1055 }
1056
1057 static QCString substituteHtmlKeywords(const QCString &s,
1058                                        const QCString &title,
1059                                        const QCString &relPath,
1060                                        const QCString &navPath=QCString())
1061 {
1062   // Build CSS/Javascript tags depending on treeview, search engine settings
1063   QCString cssFile;
1064   QCString extraCssFile;
1065   QCString generatedBy;
1066   QCString treeViewCssJs;
1067   QCString searchCssJs;
1068   QCString searchBox;
1069   QCString mathJaxJs;
1070   QCString extraCssText;
1071
1072   static QCString projectName = Config_getString("PROJECT_NAME");
1073   static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
1074   static bool treeView = Config_getBool("GENERATE_TREEVIEW");
1075   static bool searchEngine = Config_getBool("SEARCHENGINE");
1076   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
1077   static bool mathJax = Config_getBool("USE_MATHJAX");
1078   static QCString mathJaxFormat = Config_getEnum("MATHJAX_FORMAT");
1079   static bool disableIndex = Config_getBool("DISABLE_INDEX");
1080   static bool hasProjectName = !projectName.isEmpty();
1081   static bool hasProjectNumber = !Config_getString("PROJECT_NUMBER").isEmpty();
1082   static bool hasProjectBrief = !Config_getString("PROJECT_BRIEF").isEmpty();
1083   static bool hasProjectLogo = !Config_getString("PROJECT_LOGO").isEmpty();
1084   static bool titleArea = (hasProjectName || hasProjectBrief || hasProjectLogo || (disableIndex && searchEngine));
1085
1086   cssFile = Config_getString("HTML_STYLESHEET");
1087   if (cssFile.isEmpty())
1088   {
1089     cssFile = "doxygen.css";
1090   }
1091   else
1092   {
1093     QFileInfo cssfi(cssFile);
1094     if (cssfi.exists())
1095     {
1096       cssFile = cssfi.fileName().utf8();
1097     }
1098     else
1099     {
1100       cssFile = "doxygen.css";
1101     }
1102   }
1103   extraCssFile = Config_getString("HTML_EXTRA_STYLESHEET");
1104   if (!extraCssFile.isEmpty())
1105   {
1106     extraCssText = "<link href=\"$relpath^"+stripPath(extraCssFile)+"\" rel=\"stylesheet\" type=\"text/css\"/>\n";
1107   }
1108
1109   if (timeStamp) 
1110   {
1111     generatedBy = theTranslator->trGeneratedAt(dateToString(TRUE), convertToHtml(Config_getString("PROJECT_NAME")));
1112   }
1113   else 
1114   {
1115     generatedBy = theTranslator->trGeneratedBy();
1116   }
1117
1118   if (treeView)
1119   {
1120     treeViewCssJs = "<link href=\"$relpath^navtree.css\" rel=\"stylesheet\" type=\"text/css\"/>\n"
1121                     "<script type=\"text/javascript\" src=\"$relpath^resize.js\"></script>\n"
1122                     "<script type=\"text/javascript\" src=\"$relpath^navtree.js\"></script>\n"
1123                     "<script type=\"text/javascript\">\n"
1124                     "  $(document).ready(initResizable);\n"
1125                     "  $(window).load(resizeHeight);\n"
1126                     "</script>";
1127   }
1128
1129   if (searchEngine)
1130   {
1131     searchCssJs = "<link href=\"$relpath^search/search.css\" rel=\"stylesheet\" type=\"text/css\"/>\n";
1132     searchCssJs += "<script type=\"text/javascript\" src=\"$relpath^search/search.js\"></script>\n";
1133
1134     if (!serverBasedSearch) 
1135     {
1136       searchCssJs += "<script type=\"text/javascript\">\n"
1137                      "  $(document).ready(function() { searchBox.OnSelectItem(0); });\n"
1138                      "</script>";
1139     }
1140     else 
1141     {
1142       searchCssJs += "<script type=\"text/javascript\">\n"
1143                      "  $(document).ready(function() {\n"
1144                      "    if ($('.searchresults').length > 0) { searchBox.DOMSearchField().focus(); }\n"
1145                      "  });\n"
1146                      "</script>\n";
1147
1148       // OPENSEARCH_PROVIDER {
1149       searchCssJs += "<link rel=\"search\" href=\"" + relPath +
1150                      "search-opensearch.php?v=opensearch.xml\" "
1151                      "type=\"application/opensearchdescription+xml\" title=\"" +
1152                      (hasProjectName ? projectName : QCString("Doxygen")) + 
1153                      "\"/>";
1154       // OPENSEARCH_PROVIDER }
1155     }
1156     searchBox = getSearchBox(serverBasedSearch, relPath, FALSE);
1157   }
1158
1159   if (mathJax)
1160   {
1161     QCString path = Config_getString("MATHJAX_RELPATH");  
1162     if (!path.isEmpty() && path.at(path.length()-1)!='/')  
1163     {   
1164       path+="/";   
1165     }   
1166     if (path.isEmpty() || path.left(2)=="..") // relative path  
1167     {  
1168       path.prepend(relPath);   
1169     }  
1170     mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
1171                 "  MathJax.Hub.Config({\n"
1172                 "    extensions: [\"tex2jax.js\"";
1173     QStrList &mathJaxExtensions = Config_getList("MATHJAX_EXTENSIONS");
1174     const char *s = mathJaxExtensions.first();
1175     while (s)
1176     {
1177       mathJaxJs+= ", \""+QCString(s)+".js\"";
1178       s = mathJaxExtensions.next();
1179     }
1180     if (mathJaxFormat.isEmpty())
1181     {
1182       mathJaxFormat = "HTML-CSS";
1183     }
1184     mathJaxJs += "],\n"
1185                  "    jax: [\"input/TeX\",\"output/"+mathJaxFormat+"\"],\n"
1186                  "});\n";
1187     if (!g_mathjax_code.isEmpty())
1188     {
1189       mathJaxJs += g_mathjax_code;
1190       mathJaxJs += "\n";
1191     }
1192     mathJaxJs += "</script>";
1193     mathJaxJs += "<script src=\"" + path + "MathJax.js\"></script>\n";
1194   }
1195
1196   // first substitute generic keywords
1197   QCString result = substituteKeywords(s,title,
1198         convertToHtml(Config_getString("PROJECT_NAME")),
1199         convertToHtml(Config_getString("PROJECT_NUMBER")),
1200         convertToHtml(Config_getString("PROJECT_BRIEF")));
1201
1202   // additional HTML only keywords
1203   result = substitute(result,"$navpath",navPath);
1204   result = substitute(result,"$stylesheet",cssFile);
1205   result = substitute(result,"$treeview",treeViewCssJs);
1206   result = substitute(result,"$searchbox",searchBox);
1207   result = substitute(result,"$search",searchCssJs);
1208   result = substitute(result,"$mathjax",mathJaxJs);
1209   result = substitute(result,"$generatedby",generatedBy);
1210   result = substitute(result,"$extrastylesheet",extraCssText);
1211   result = substitute(result,"$relpath$",relPath); //<-- obsolete: for backwards compatibility only
1212   result = substitute(result,"$relpath^",relPath); //<-- must be last
1213   
1214   // additional HTML only conditional blocks
1215   result = selectBlock(result,"DISABLE_INDEX",disableIndex);
1216   result = selectBlock(result,"GENERATE_TREEVIEW",treeView);
1217   result = selectBlock(result,"SEARCHENGINE",searchEngine);
1218   result = selectBlock(result,"TITLEAREA",titleArea);
1219   result = selectBlock(result,"PROJECT_NAME",hasProjectName);
1220   result = selectBlock(result,"PROJECT_NUMBER",hasProjectNumber);
1221   result = selectBlock(result,"PROJECT_BRIEF",hasProjectBrief);
1222   result = selectBlock(result,"PROJECT_LOGO",hasProjectLogo);
1223
1224   result = removeEmptyLines(result);
1225
1226   return result;
1227 }
1228
1229 //--------------------------------------------------------------------------
1230
1231 HtmlCodeGenerator::HtmlCodeGenerator()
1232    : m_streamSet(FALSE), m_col(0)
1233 {
1234 }
1235
1236 HtmlCodeGenerator::HtmlCodeGenerator(FTextStream &t,const QCString &relPath) 
1237    : m_col(0), m_relPath(relPath)
1238 {
1239   setTextStream(t);
1240 }
1241
1242 void HtmlCodeGenerator::setTextStream(FTextStream &t)
1243 {
1244   m_streamSet = t.device()!=0;
1245   m_t.setDevice(t.device());
1246 }
1247
1248 void HtmlCodeGenerator::setRelativePath(const QCString &path)
1249 {
1250   m_relPath = path;
1251 }
1252
1253 void HtmlCodeGenerator::codify(const char *str)
1254 {
1255   static int tabSize = Config_getInt("TAB_SIZE");
1256   if (str && m_streamSet)
1257   { 
1258     const char *p=str;
1259     char c;
1260     int spacesToNextTabStop;
1261     while (*p)
1262     {
1263       c=*p++;
1264       switch(c)
1265       {
1266         case '\t': spacesToNextTabStop = 
1267                          tabSize - (m_col%tabSize); 
1268                    m_t << Doxygen::spaces.left(spacesToNextTabStop); 
1269                    m_col+=spacesToNextTabStop; 
1270                    break; 
1271         case '\n': m_t << "\n"; m_col=0; 
1272                    break;
1273         case '\r': break;
1274         case '<':  m_t << "&lt;"; m_col++; 
1275                    break;
1276         case '>':  m_t << "&gt;"; m_col++; 
1277                    break;
1278         case '&':  m_t << "&amp;"; m_col++; 
1279                    break;
1280         case '\'': m_t << "&#39;"; m_col++; // &apos; is not valid XHTML
1281                    break;
1282         case '"':  m_t << "&quot;"; m_col++;
1283                    break;
1284         case '\\':
1285                    if (*p=='<')
1286                      { m_t << "&lt;"; p++; }
1287                    else if (*p=='>')
1288                      { m_t << "&gt;"; p++; }
1289                    else
1290                      m_t << "\\";
1291                    m_col++;
1292                    break;
1293         default:   p=writeUtf8Char(m_t,p-1);    
1294                    m_col++;                    
1295                    break;
1296       }
1297     }
1298   }
1299 }
1300
1301 void HtmlCodeGenerator::docify(const char *str)
1302 {
1303   if (str && m_streamSet)
1304   {
1305     const char *p=str;
1306     char c;
1307     while (*p)
1308     {
1309       c=*p++;
1310       switch(c)
1311       {
1312         case '<':  m_t << "&lt;"; break;
1313         case '>':  m_t << "&gt;"; break;
1314         case '&':  m_t << "&amp;"; break;
1315         case '"':  m_t << "&quot;"; break;
1316         case '\\':
1317                    if (*p=='<')
1318                      { m_t << "&lt;"; p++; }
1319                    else if (*p=='>')
1320                      { m_t << "&gt;"; p++; }
1321                    else
1322                      m_t << "\\";
1323                    break;
1324         default:   m_t << c; 
1325       }
1326     }
1327   }
1328 }
1329
1330 void HtmlCodeGenerator::writeLineNumber(const char *ref,const char *filename,
1331                                     const char *anchor,int l)
1332 {
1333   if (!m_streamSet) return;
1334   QCString lineNumber,lineAnchor;
1335   lineNumber.sprintf("%5d",l);
1336   lineAnchor.sprintf("l%05d",l);
1337
1338   m_t << "<div class=\"line\">";
1339   m_t << "<a name=\"" << lineAnchor << "\"></a><span class=\"lineno\">"; 
1340   if (filename)
1341   {
1342     _writeCodeLink("line",ref,filename,anchor,lineNumber,0);
1343   }
1344   else
1345   {
1346     codify(lineNumber);
1347   }
1348   m_t << "</span>"; 
1349   m_t << "&#160;";
1350 }
1351
1352 void HtmlCodeGenerator::writeCodeLink(const char *ref,const char *f,
1353                                       const char *anchor, const char *name,
1354                                       const char *tooltip)
1355 {
1356   if (!m_streamSet) return;
1357   //printf("writeCodeLink(ref=%s,f=%s,anchor=%s,name=%s,tooltip=%s)\n",ref,f,anchor,name,tooltip);
1358   _writeCodeLink("code",ref,f,anchor,name,tooltip);
1359 }
1360
1361 void HtmlCodeGenerator::_writeCodeLink(const char *className,
1362                                       const char *ref,const char *f,
1363                                       const char *anchor, const char *name,
1364                                       const char *tooltip)
1365 {
1366   if (ref) 
1367   {
1368     m_t << "<a class=\"" << className << "Ref\" ";
1369     m_t << externalLinkTarget() << externalRef(m_relPath,ref,FALSE);
1370   }
1371   else
1372   {
1373     m_t << "<a class=\"" << className << "\" ";
1374   }
1375   m_t << "href=\"";
1376   m_t << externalRef(m_relPath,ref,TRUE);
1377   if (f) m_t << f << Doxygen::htmlFileExtension;
1378   if (anchor) m_t << "#" << anchor;
1379   m_t << "\"";
1380   if (tooltip) m_t << " title=\"" << tooltip << "\"";
1381   m_t << ">";
1382   docify(name);
1383   m_t << "</a>";
1384   m_col+=qstrlen(name);
1385 }
1386
1387 void HtmlCodeGenerator::writeTooltip(const char *id, const DocLinkInfo &docInfo,
1388                                      const char *decl, const char *desc,
1389                                      const SourceLinkInfo &defInfo,
1390                                      const SourceLinkInfo &declInfo)
1391 {
1392   m_t << "<div class=\"ttc\" id=\"" << id << "\">";
1393   m_t << "<div class=\"ttname\">";
1394   if (!docInfo.url.isEmpty())
1395   {
1396     m_t << "<a href=\"";
1397     m_t << externalRef(m_relPath,docInfo.ref,TRUE);
1398     m_t << docInfo.url << Doxygen::htmlFileExtension;
1399     if (!docInfo.anchor.isEmpty())
1400     {
1401       m_t << "#" << docInfo.anchor;
1402     }
1403     m_t << "\">";
1404   }
1405   docify(docInfo.name);
1406   if (!docInfo.url.isEmpty())
1407   {
1408     m_t << "</a>";
1409   }
1410   m_t << "</div>";
1411   if (decl)
1412   {
1413     m_t << "<div class=\"ttdeci\">";
1414     docify(decl);
1415     m_t << "</div>";
1416   }
1417   if (desc)
1418   {
1419     m_t << "<div class=\"ttdoc\">";
1420     m_t << desc; // desc is already HTML escaped
1421     m_t << "</div>";
1422   }
1423   if (!defInfo.file.isEmpty())
1424   {
1425     m_t << "<div class=\"ttdef\"><b>Definition:</b> ";
1426     if (!defInfo.url.isEmpty())
1427     {
1428       m_t << "<a href=\"";
1429       m_t << externalRef(m_relPath,defInfo.ref,TRUE);
1430       m_t << defInfo.url << Doxygen::htmlFileExtension;
1431       if (!defInfo.anchor.isEmpty())
1432       {
1433         m_t << "#" << defInfo.anchor;
1434       }
1435       m_t << "\">";
1436     }
1437     m_t << defInfo.file << ":" << defInfo.line;
1438     if (!defInfo.url.isEmpty())
1439     {
1440       m_t << "</a>";
1441     }
1442     m_t << "</div>";
1443   }
1444   if (!declInfo.file.isEmpty())
1445   {
1446     m_t << "<div class=\"ttdecl\"><b>Declaration:</b> ";
1447     if (!declInfo.url.isEmpty())
1448     {
1449       m_t << "<a href=\"";
1450       m_t << externalRef(m_relPath,declInfo.ref,TRUE);
1451       m_t << declInfo.url << Doxygen::htmlFileExtension;
1452       if (!declInfo.anchor.isEmpty())
1453       {
1454         m_t << "#" << declInfo.anchor;
1455       }
1456       m_t << "\">";
1457     }
1458     m_t << declInfo.file << ":" << declInfo.line;
1459     if (!declInfo.url.isEmpty())
1460     {
1461       m_t << "</a>";
1462     }
1463     m_t << "</div>";
1464   }
1465   m_t << "</div>" << endl;
1466 }
1467
1468
1469 void HtmlCodeGenerator::startCodeLine(bool hasLineNumbers) 
1470
1471   if (m_streamSet)
1472   {
1473     if (!hasLineNumbers) m_t << "<div class=\"line\">";
1474     m_col=0; 
1475   }
1476 }
1477
1478 void HtmlCodeGenerator::endCodeLine() 
1479
1480   if (m_streamSet) m_t << "</div>\n";
1481 }
1482
1483 void HtmlCodeGenerator::startFontClass(const char *s) 
1484
1485   if (m_streamSet) m_t << "<span class=\"" << s << "\">"; 
1486 }
1487
1488 void HtmlCodeGenerator::endFontClass() 
1489
1490   if (m_streamSet) m_t << "</span>"; 
1491 }
1492
1493 void HtmlCodeGenerator::writeCodeAnchor(const char *anchor) 
1494
1495   if (m_streamSet) m_t << "<a name=\"" << anchor << "\"></a>"; 
1496 }
1497
1498 //--------------------------------------------------------------------------
1499
1500 HtmlGenerator::HtmlGenerator() : OutputGenerator()
1501 {
1502   dir=Config_getString("HTML_OUTPUT");
1503   m_emptySection=FALSE;
1504 }
1505
1506 HtmlGenerator::~HtmlGenerator()
1507 {
1508   //printf("HtmlGenerator::~HtmlGenerator()\n");
1509 }
1510
1511 void HtmlGenerator::init()
1512 {
1513   QCString dname=Config_getString("HTML_OUTPUT");
1514   QDir d(dname);
1515   if (!d.exists() && !d.mkdir(dname))
1516   {
1517     err("Could not create output directory %s\n",dname.data());
1518     exit(1);
1519   }
1520   //writeLogo(dname);
1521   if (!Config_getString("HTML_HEADER").isEmpty()) 
1522   {
1523     g_header=fileToString(Config_getString("HTML_HEADER"));
1524     //printf("g_header='%s'\n",g_header.data());
1525   }
1526   else 
1527   {
1528     g_header = defaultHtmlHeader;
1529   }
1530
1531   if (!Config_getString("HTML_FOOTER").isEmpty()) 
1532   {
1533     g_footer=fileToString(Config_getString("HTML_FOOTER"));
1534     //printf("g_footer='%s'\n",g_footer.data());
1535   }
1536   else 
1537   {
1538     g_footer = defaultHtmlFooter;
1539   }
1540
1541   if (Config_getBool("USE_MATHJAX"))
1542   {
1543     if (!Config_getString("MATHJAX_CODEFILE").isEmpty()) 
1544     {
1545       g_mathjax_code=fileToString(Config_getString("MATHJAX_CODEFILE"));
1546       //printf("g_mathjax_code='%s'\n",g_mathjax_code.data());
1547     }
1548   }
1549   createSubDirs(d);
1550
1551   QCString fileName=dname+"/tabs.css";
1552   QFile f(fileName);
1553   if (f.open(IO_WriteOnly))
1554   {
1555     FTextStream t(&f);
1556     t << replaceColorMarkers(tabs_css);
1557   }
1558   else
1559   {
1560     fprintf(stderr,"Warning: Cannot open file %s for writing\n",fileName.data());
1561   }
1562
1563   {
1564     QFile f(dname+"/jquery.js");
1565     if (f.open(IO_WriteOnly))
1566     {
1567       FTextStream t(&f);
1568       t << search_jquery_script1 << search_jquery_script2 << search_jquery_script3;
1569       if (Config_getBool("GENERATE_TREEVIEW"))
1570       {
1571         t << search_jquery_script4 << search_jquery_script5;
1572       }
1573       if (Config_getBool("SOURCE_BROWSER"))
1574       {
1575         t << search_jquery_script6;
1576       }
1577     }
1578   }
1579
1580   if (Config_getBool("INTERACTIVE_SVG"))
1581   {
1582     QFile f(dname+"/svgpan.js");
1583     if (f.open(IO_WriteOnly))
1584     {
1585       FTextStream t(&f);
1586       t << svgpan_script;
1587     }
1588   }
1589
1590   {
1591     QFile f(dname+"/dynsections.js");
1592     if (f.open(IO_WriteOnly))
1593     {
1594       FTextStream t(&f);
1595       t << dynsections_script;
1596       if (Config_getBool("SOURCE_BROWSER") && Config_getBool("SOURCE_TOOLTIPS"))
1597       {
1598         t << endl << 
1599           "$(document).ready(function() {\n"
1600           "  $('.code,.codeRef').each(function() {\n"
1601           "    $(this).data('powertip',$('#'+$(this).attr('href').replace(/.*\\//,'').replace(/[^a-z_A-Z0-9]/g,'_')).html());\n"
1602           "    $(this).powerTip({ placement: 's', smartPlacement: true, mouseOnToPopup: true });\n"
1603           "  });\n"
1604           "});\n";
1605       }
1606     }
1607   }
1608 }
1609
1610 /// Additional initialization after indices have been created
1611 void HtmlGenerator::writeTabData()
1612 {
1613   Doxygen::indexList->addStyleSheetFile("tabs.css");
1614   QCString dname=Config_getString("HTML_OUTPUT");
1615   writeColoredImgData(dname,colored_tab_data);
1616
1617   {
1618     unsigned char shadow[6] = { 5, 5, 5, 5, 5, 5 };
1619     unsigned char shadow_alpha[6]  = { 80, 60, 40, 20, 10, 0 };
1620     ColoredImage img(1,6,shadow,shadow_alpha,0,0,100);
1621     img.save(dname+"/nav_g.png");
1622   }
1623 }
1624
1625 void HtmlGenerator::writeSearchData(const char *dir)
1626 {
1627   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
1628   writeImgData(dir,serverBasedSearch ? search_server_data : search_client_data);
1629   QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
1630   QFile f(searchDirName+"/search.css");
1631   if (f.open(IO_WriteOnly))
1632   {
1633     FTextStream t(&f);
1634     QCString searchCss = replaceColorMarkers(search_styleSheet);
1635     searchCss = substitute(searchCss,"$doxygenversion",versionString);
1636     if (Config_getBool("DISABLE_INDEX"))
1637     {
1638       // move up the search box if there are no tabs
1639       searchCss = substitute(searchCss,"margin-top: 8px;","margin-top: 0px;");
1640     }
1641     t << searchCss;
1642   }
1643   Doxygen::indexList->addStyleSheetFile("search/search.css");
1644 }
1645
1646 void HtmlGenerator::writeStyleSheetFile(QFile &file)
1647 {
1648   FTextStream t(&file);
1649   t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
1650 }
1651
1652 void HtmlGenerator::writeHeaderFile(QFile &file, const char * /*cssname*/)
1653 {
1654   FTextStream t(&file);
1655   t << "<!-- HTML header for doxygen " << versionString << "-->" << endl;
1656   QCString contents(defaultHtmlHeader);
1657   t << contents;
1658 }
1659
1660 void HtmlGenerator::writeFooterFile(QFile &file)
1661 {
1662   FTextStream t(&file);
1663   t << "<!-- HTML footer for doxygen " << versionString << "-->" <<  endl;
1664   QCString contents(defaultHtmlFooter);
1665   t << contents;
1666 }
1667
1668 void HtmlGenerator::startFile(const char *name,const char *,
1669                               const char *title)
1670 {
1671   //printf("HtmlGenerator::startFile(%s)\n",name);
1672   QCString fileName=name;
1673   lastTitle=title;
1674   relPath = relativePathToRoot(fileName);
1675
1676   if (fileName.right(Doxygen::htmlFileExtension.length())!=Doxygen::htmlFileExtension) 
1677   {
1678     fileName+=Doxygen::htmlFileExtension;
1679   }
1680   startPlainFile(fileName);
1681   m_codeGen.setTextStream(t);
1682   m_codeGen.setRelativePath(relPath);
1683   Doxygen::indexList->addIndexFile(fileName);
1684   
1685   lastFile = fileName;
1686   t << substituteHtmlKeywords(g_header,convertToHtml(filterTitle(title)),relPath);
1687
1688   t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
1689     << versionString << " -->" << endl;
1690   //static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1691   static bool searchEngine = Config_getBool("SEARCHENGINE");
1692   if (searchEngine /*&& !generateTreeView*/)
1693   {
1694     t << "<script type=\"text/javascript\">\n";
1695     t << "var searchBox = new SearchBox(\"searchBox\", \""
1696       << relPath<< "search\",false,'" << theTranslator->trSearch() << "');\n";
1697     t << "</script>\n";
1698   }
1699   //generateDynamicSections(t,relPath);
1700   m_sectionCount=0;
1701 }
1702
1703 void HtmlGenerator::writeSearchInfo(FTextStream &t,const QCString &relPath)
1704 {
1705   static bool searchEngine      = Config_getBool("SEARCHENGINE");
1706   static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
1707   if (searchEngine && !serverBasedSearch)
1708   {
1709     (void)relPath;
1710     t << "<!-- window showing the filter options -->\n";
1711     t << "<div id=\"MSearchSelectWindow\"\n";
1712     t << "     onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
1713     t << "     onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
1714     t << "     onkeydown=\"return searchBox.OnSearchSelectKey(event)\">\n";
1715     writeSearchCategories(t);
1716     t << "</div>\n";
1717     t << "\n";
1718     t << "<!-- iframe showing the search results (closed by default) -->\n";
1719     t << "<div id=\"MSearchResultsWindow\">\n";
1720     t << "<iframe src=\"javascript:void(0)\" frameborder=\"0\" \n";
1721     t << "        name=\"MSearchResults\" id=\"MSearchResults\">\n";
1722     t << "</iframe>\n";
1723     t << "</div>\n";
1724     t << "\n";
1725   }
1726 }
1727
1728 void HtmlGenerator::writeSearchInfo()
1729 {
1730   writeSearchInfo(t,relPath);
1731 }
1732
1733
1734 QCString HtmlGenerator::writeLogoAsString(const char *path)
1735 {
1736   static bool timeStamp = Config_getBool("HTML_TIMESTAMP");
1737   QCString result;
1738   if (timeStamp)
1739   {
1740     result += theTranslator->trGeneratedAt(
1741                dateToString(TRUE),
1742                Config_getString("PROJECT_NAME")
1743               );
1744   }
1745   else
1746   {
1747     result += theTranslator->trGeneratedBy();
1748   }
1749   result += "&#160;\n<a href=\"http://www.doxygen.org/index.html\">\n"
1750             "<img class=\"footer\" src=\"";
1751   result += path;
1752   result += "doxygen.png\" alt=\"doxygen\"/></a> ";
1753   result += versionString;
1754   result += " ";
1755   return result;
1756 }
1757
1758 void HtmlGenerator::writeLogo()
1759 {
1760   t << writeLogoAsString(relPath);
1761 }
1762
1763 void HtmlGenerator::writePageFooter(FTextStream &t,const QCString &lastTitle,
1764                               const QCString &relPath,const QCString &navPath)
1765 {
1766   t << substituteHtmlKeywords(g_footer,convertToHtml(lastTitle),relPath,navPath);
1767 }
1768
1769 void HtmlGenerator::writeFooter(const char *navPath)
1770 {
1771   writePageFooter(t,lastTitle,relPath,navPath);
1772 }
1773
1774 void HtmlGenerator::endFile()
1775 {
1776   endPlainFile();
1777 }
1778
1779 void HtmlGenerator::startProjectNumber()
1780 {
1781   t << "<h3 class=\"version\">";
1782 }
1783
1784 void HtmlGenerator::endProjectNumber()
1785 {
1786   t << "</h3>";
1787 }
1788
1789 void HtmlGenerator::writeStyleInfo(int part)
1790 {
1791   //printf("writeStyleInfo(%d)\n",part);
1792   if (part==0)
1793   {
1794     if (Config_getString("HTML_STYLESHEET").isEmpty()) // write default style sheet
1795     {
1796       //printf("write doxygen.css\n");
1797       startPlainFile("doxygen.css"); 
1798       
1799       // alternative, cooler looking titles
1800       //t << "H1 { text-align: center; border-width: thin none thin none;" << endl;
1801       //t << "     border-style : double; border-color : blue; padding-left : 1em; padding-right : 1em }" << endl;
1802
1803       t << replaceColorMarkers(substitute(defaultStyleSheet,"$doxygenversion",versionString));
1804       endPlainFile();
1805       Doxygen::indexList->addStyleSheetFile("doxygen.css");
1806     }
1807     else // write user defined style sheet
1808     {
1809       QCString cssname=Config_getString("HTML_STYLESHEET");
1810       QFileInfo cssfi(cssname);
1811       if (!cssfi.exists() || !cssfi.isFile() || !cssfi.isReadable())
1812       {
1813         err("style sheet %s does not exist or is not readable!", Config_getString("HTML_STYLESHEET").data());
1814       }
1815       else
1816       {
1817         // convert style sheet to string
1818         QCString fileStr = fileToString(cssname);
1819         // write the string into the output dir
1820         startPlainFile(cssfi.fileName().utf8());
1821         t << fileStr;
1822         endPlainFile();
1823       }
1824       Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
1825     }
1826     static QCString extraCssFile = Config_getString("HTML_EXTRA_STYLESHEET");
1827     if (!extraCssFile.isEmpty())
1828     {
1829       QFileInfo fi(extraCssFile);
1830       if (fi.exists())
1831       {
1832         Doxygen::indexList->addStyleSheetFile(fi.fileName().utf8());
1833       }
1834     }
1835   }
1836 }
1837
1838 void HtmlGenerator::startDoxyAnchor(const char *,const char *,
1839                                     const char *anchor, const char *,
1840                                     const char *)
1841 {
1842   t << "<a class=\"anchor\" id=\"" << anchor << "\"></a>";
1843 }
1844
1845 void HtmlGenerator::endDoxyAnchor(const char *,const char *)
1846 {
1847 }
1848
1849 //void HtmlGenerator::newParagraph()
1850 //{
1851 //  t << endl << "<p>" << endl;
1852 //}
1853
1854 void HtmlGenerator::startParagraph()
1855 {
1856   t << endl << "<p>";
1857 }
1858
1859 void HtmlGenerator::endParagraph()
1860 {
1861   t << "</p>" << endl;
1862 }
1863
1864 void HtmlGenerator::writeString(const char *text)
1865 {
1866   t << text;
1867 }
1868
1869 void HtmlGenerator::startIndexListItem()
1870 {
1871   t << "<li>";
1872 }
1873
1874 void HtmlGenerator::endIndexListItem()
1875 {
1876   t << "</li>" << endl;
1877 }
1878
1879 void HtmlGenerator::startIndexItem(const char *ref,const char *f)
1880 {
1881   //printf("HtmlGenerator::startIndexItem(%s,%s)\n",ref,f);
1882   if (ref || f)
1883   {
1884     if (ref) 
1885     {
1886       t << "<a class=\"elRef\" ";
1887       t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1888     }
1889     else
1890     {
1891       t << "<a class=\"el\" ";
1892     }
1893     t << "href=\"";
1894     t << externalRef(relPath,ref,TRUE);
1895     if (f) t << f << Doxygen::htmlFileExtension << "\">";
1896   }
1897   else
1898   {
1899     t << "<b>";
1900   }
1901 }
1902
1903 void HtmlGenerator::endIndexItem(const char *ref,const char *f)
1904 {
1905   //printf("HtmlGenerator::endIndexItem(%s,%s,%s)\n",ref,f,name);
1906   if (ref || f)
1907   {
1908     t << "</a>";
1909   }
1910   else
1911   {
1912     t << "</b>";
1913   }
1914 }
1915
1916 void HtmlGenerator::writeStartAnnoItem(const char *,const char *f,
1917                                        const char *path,const char *name)
1918 {
1919   t << "<li>";
1920   if (path) docify(path);
1921   t << "<a class=\"el\" href=\"" << f << Doxygen::htmlFileExtension << "\">";
1922   docify(name);
1923   t << "</a> ";
1924 }
1925
1926 void HtmlGenerator::writeObjectLink(const char *ref,const char *f,
1927                                     const char *anchor, const char *name)
1928 {
1929   if (ref) 
1930   {
1931     t << "<a class=\"elRef\" ";
1932     t << externalLinkTarget() << externalRef(relPath,ref,FALSE);
1933   }
1934   else
1935   {
1936     t << "<a class=\"el\" ";
1937   }
1938   t << "href=\"";
1939   t << externalRef(relPath,ref,TRUE);
1940   if (f) t << f << Doxygen::htmlFileExtension;
1941   if (anchor) t << "#" << anchor;
1942   t << "\">";
1943   docify(name);
1944   t << "</a>";
1945 }
1946
1947 void HtmlGenerator::startTextLink(const char *f,const char *anchor)
1948 {
1949   t << "<a href=\"";
1950   if (f)   t << relPath << f << Doxygen::htmlFileExtension;
1951   if (anchor) t << "#" << anchor;
1952   t << "\">"; 
1953 }
1954
1955 void HtmlGenerator::endTextLink()
1956 {
1957   t << "</a>";
1958 }
1959
1960 void HtmlGenerator::startHtmlLink(const char *url)
1961 {
1962   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1963   t << "<a ";
1964   if (generateTreeView) t << "target=\"top\" ";
1965   t << "href=\"";
1966   if (url) t << url;
1967   t << "\">"; 
1968 }
1969
1970 void HtmlGenerator::endHtmlLink()
1971 {
1972   t << "</a>";
1973 }
1974
1975 void HtmlGenerator::startGroupHeader(int extraIndentLevel)
1976 {
1977   if (extraIndentLevel==2)
1978   {
1979     t << "<h4 class=\"groupheader\">";
1980   }
1981   else if (extraIndentLevel==1)
1982   {
1983     t << "<h3 class=\"groupheader\">";
1984   }
1985   else // extraIndentLevel==0
1986   {
1987     t << "<h2 class=\"groupheader\">";
1988   }
1989 }
1990
1991 void HtmlGenerator::endGroupHeader(int extraIndentLevel)
1992 {
1993   if (extraIndentLevel==2)
1994   {
1995     t << "</h4>" << endl;
1996   }
1997   else if (extraIndentLevel==1)
1998   {
1999     t << "</h3>" << endl;
2000   }
2001   else
2002   {
2003     t << "</h2>" << endl;
2004   }
2005 }
2006
2007 void HtmlGenerator::startSection(const char *lab,const char *,SectionInfo::SectionType type)
2008 {
2009   switch(type)
2010   {
2011     case SectionInfo::Page:          t << "\n\n<h1>"; break;
2012     case SectionInfo::Section:       t << "\n\n<h2>"; break;
2013     case SectionInfo::Subsection:    t << "\n\n<h3>"; break;
2014     case SectionInfo::Subsubsection: t << "\n\n<h4>"; break;
2015     case SectionInfo::Paragraph:     t << "\n\n<h5>"; break;
2016     default: ASSERT(0); break;
2017   }
2018   t << "<a class=\"anchor\" id=\"" << lab << "\"></a>";
2019 }
2020
2021 void HtmlGenerator::endSection(const char *,SectionInfo::SectionType type)
2022 {
2023   switch(type)
2024   {
2025     case SectionInfo::Page:          t << "</h1>"; break;
2026     case SectionInfo::Section:       t << "</h2>"; break;
2027     case SectionInfo::Subsection:    t << "</h3>"; break;
2028     case SectionInfo::Subsubsection: t << "</h4>"; break;
2029     case SectionInfo::Paragraph:     t << "</h5>"; break;
2030     default: ASSERT(0); break;
2031   }
2032 }
2033
2034 void HtmlGenerator::docify(const char *str)
2035 {
2036   docify(str,FALSE);
2037 }
2038
2039 void HtmlGenerator::docify(const char *str,bool inHtmlComment)
2040 {
2041   if (str)
2042   {
2043     const char *p=str;
2044     char c;
2045     while (*p)
2046     {
2047       c=*p++;
2048       switch(c)
2049       {
2050         case '<':  t << "&lt;"; break;
2051         case '>':  t << "&gt;"; break;
2052         case '&':  t << "&amp;"; break;
2053         case '"':  t << "&quot;"; break;
2054         case '-':  if (inHtmlComment) t << "&#45;"; else t << "-"; break;
2055         case '\\':
2056                    if (*p=='<')
2057                      { t << "&lt;"; p++; }
2058                    else if (*p=='>')
2059                      { t << "&gt;"; p++; }
2060                    else
2061                      t << "\\";
2062                    break;
2063         default:   t << c; 
2064       }
2065     }
2066   }
2067 }
2068
2069 void HtmlGenerator::writeChar(char c)
2070 {
2071   char cs[2];
2072   cs[0]=c;
2073   cs[1]=0;
2074   docify(cs);
2075 }
2076
2077 //--- helper function for dynamic sections -------------------------
2078
2079 static void startSectionHeader(FTextStream &t,
2080                                const QCString &relPath,int sectionCount)
2081 {
2082   //t << "<!-- startSectionHeader -->";
2083   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2084   if (dynamicSections)
2085   {
2086     t << "<div id=\"dynsection-" << sectionCount << "\" "
2087          "onclick=\"return toggleVisibility(this)\" "
2088          "class=\"dynheader closed\" "
2089          "style=\"cursor:pointer;\">" << endl;
2090     t << "  <img id=\"dynsection-" << sectionCount << "-trigger\" src=\"" 
2091       << relPath << "closed.png\" alt=\"+\"/> ";
2092   }
2093   else
2094   {
2095     t << "<div class=\"dynheader\">" << endl;
2096   }
2097 }
2098
2099 static void endSectionHeader(FTextStream &t)
2100 {
2101   //t << "<!-- endSectionHeader -->";
2102   t << "</div>" << endl;
2103 }
2104
2105 static void startSectionSummary(FTextStream &t,int sectionCount)
2106 {
2107   //t << "<!-- startSectionSummary -->";
2108   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2109   if (dynamicSections)
2110   {
2111     t << "<div id=\"dynsection-" << sectionCount << "-summary\" "
2112          "class=\"dynsummary\" "
2113          "style=\"display:block;\">" << endl;
2114   }
2115 }
2116
2117 static void endSectionSummary(FTextStream &t)
2118 {
2119   //t << "<!-- endSectionSummary -->";
2120   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2121   if (dynamicSections)
2122   {
2123     t << "</div>" << endl;
2124   }
2125 }
2126
2127 static void startSectionContent(FTextStream &t,int sectionCount)
2128 {
2129   //t << "<!-- startSectionContent -->";
2130   static bool dynamicSections = Config_getBool("HTML_DYNAMIC_SECTIONS");
2131   if (dynamicSections)
2132   {
2133     t << "<div id=\"dynsection-" << sectionCount << "-content\" "
2134          "class=\"dyncontent\" "
2135          "style=\"display:none;\">" << endl;
2136   }
2137   else
2138   {
2139     t << "<div class=\"dyncontent\">" << endl;
2140   }
2141 }
2142
2143 static void endSectionContent(FTextStream &t)
2144 {
2145   //t << "<!-- endSectionContent -->";
2146   t << "</div>" << endl;
2147 }
2148
2149 //----------------------------
2150
2151 void HtmlGenerator::startClassDiagram()
2152 {
2153   startSectionHeader(t,relPath,m_sectionCount);
2154 }
2155
2156 void HtmlGenerator::endClassDiagram(const ClassDiagram &d,
2157                                 const char *fileName,const char *name)
2158 {
2159   endSectionHeader(t);
2160   startSectionSummary(t,m_sectionCount);
2161   endSectionSummary(t);
2162   startSectionContent(t,m_sectionCount);
2163   t << " <div class=\"center\">" << endl;
2164   t << "  <img src=\"";
2165   t << relPath << fileName << ".png\" usemap=\"#";
2166   docify(name);
2167   t << "_map\" alt=\"\"/>" << endl;
2168   t << "  <map id=\"";
2169   docify(name);
2170   t << "_map\" name=\"";
2171   docify(name);
2172   t << "_map\">" << endl;
2173
2174   d.writeImage(t,dir,relPath,fileName);
2175   t << " </div>";
2176   endSectionContent(t);
2177   m_sectionCount++;
2178 }
2179
2180
2181 void HtmlGenerator::startMemberList()  
2182
2183   DBG_HTML(t << "<!-- startMemberList -->" << endl)
2184 }
2185
2186 void HtmlGenerator::endMemberList()    
2187
2188   DBG_HTML(t << "<!-- endMemberList -->" << endl)
2189 }
2190
2191 // anonymous type:
2192 //  0 = single column right aligned
2193 //  1 = double column left aligned
2194 //  2 = single column left aligned
2195 void HtmlGenerator::startMemberItem(const char *anchor,int annoType,const char *inheritId) 
2196
2197   DBG_HTML(t << "<!-- startMemberItem() -->" << endl)
2198   if (m_emptySection)
2199   {
2200     t << "<table class=\"memberdecls\">" << endl;
2201     m_emptySection=FALSE;
2202   }
2203   t << "<tr class=\"memitem:" << anchor;
2204   if (inheritId)
2205   {
2206     t << " inherit " << inheritId;
2207   }
2208   t << "\">";
2209   switch(annoType)
2210   {
2211     case 0:  t << "<td class=\"memItemLeft\" align=\"right\" valign=\"top\">"; break;
2212     case 1:  t << "<td class=\"memItemLeft\" >"; break;
2213     case 2:  t << "<td class=\"memItemLeft\" valign=\"top\">"; break;
2214     default: t << "<td class=\"memTemplParams\" colspan=\"2\">"; break;
2215   }
2216 }
2217
2218 void HtmlGenerator::endMemberItem() 
2219
2220   t << "</td></tr>"; 
2221   t << endl; 
2222 }
2223
2224 void HtmlGenerator::startMemberTemplateParams()
2225 {
2226 }
2227
2228 void HtmlGenerator::endMemberTemplateParams(const char *anchor,const char *inheritId)
2229 {
2230   t << "</td></tr>" << endl;
2231   t << "<tr class=\"memitem:" << anchor;
2232   if (inheritId)
2233   {
2234     t << " inherit " << inheritId;
2235   }
2236   t << "\"><td class=\"memTemplItemLeft\" align=\"right\" valign=\"top\">";
2237 }
2238
2239
2240 void HtmlGenerator::insertMemberAlign(bool templ) 
2241
2242   DBG_HTML(t << "<!-- insertMemberAlign -->" << endl)
2243   QCString className = templ ? "memTemplItemRight" : "memItemRight";
2244   t << "&#160;</td><td class=\"" << className << "\" valign=\"bottom\">"; 
2245 }
2246
2247 void HtmlGenerator::startMemberDescription(const char *anchor,const char *inheritId) 
2248
2249   DBG_HTML(t << "<!-- startMemberDescription -->" << endl)
2250     if (m_emptySection)
2251     {
2252       t << "<table class=\"memberdecls\">" << endl;
2253       m_emptySection=FALSE;
2254     }
2255   t << "<tr class=\"memdesc:" << anchor;
2256   if (inheritId)
2257   {
2258     t << " inherit " << inheritId;
2259   }
2260   t << "\"><td class=\"mdescLeft\">&#160;</td><td class=\"mdescRight\">"; 
2261 }
2262
2263 void HtmlGenerator::endMemberDescription()   
2264
2265   DBG_HTML(t << "<!-- endMemberDescription -->" << endl)
2266   t << "<br /></td></tr>" << endl; 
2267 }
2268
2269 void HtmlGenerator::startMemberSections()
2270 {
2271   DBG_HTML(t << "<!-- startMemberSections -->" << endl)
2272   m_emptySection=TRUE; // we postpone writing <table> until we actually
2273                        // write a row to prevent empty tables, which 
2274                        // are not valid XHTML!
2275 }
2276
2277 void HtmlGenerator::endMemberSections()
2278 {
2279   DBG_HTML(t << "<!-- endMemberSections -->" << endl)
2280   if (!m_emptySection)
2281   {
2282     t << "</table>" << endl;
2283   }
2284 }
2285
2286 void HtmlGenerator::startMemberHeader(const char *anchor)
2287 {
2288   DBG_HTML(t << "<!-- startMemberHeader -->" << endl)
2289   if (!m_emptySection)
2290   {
2291     t << "</table>";
2292     m_emptySection=TRUE;
2293   }
2294   if (m_emptySection)
2295   {
2296     t << "<table class=\"memberdecls\">" << endl;
2297     m_emptySection=FALSE;
2298   }
2299   t << "<tr class=\"heading\"><td colspan=\"2\"><h2 class=\"groupheader\">";
2300   if (anchor)
2301   {
2302     t << "<a name=\"" << anchor << "\"></a>" << endl;
2303   }
2304 }
2305
2306 void HtmlGenerator::endMemberHeader()
2307 {
2308   DBG_HTML(t << "<!-- endMemberHeader -->" << endl)
2309   t << "</h2></td></tr>" << endl;
2310 }
2311
2312 void HtmlGenerator::startMemberSubtitle()
2313 {
2314   DBG_HTML(t << "<!-- startMemberSubtitle -->" << endl)
2315   t << "<tr><td class=\"ititle\" colspan=\"2\">";
2316 }
2317
2318 void HtmlGenerator::endMemberSubtitle()
2319 {
2320   DBG_HTML(t << "<!-- endMemberSubtitle -->" << endl)
2321   t << "</td></tr>" << endl;
2322 }
2323
2324 void HtmlGenerator::startIndexList() 
2325
2326   t << "<table>"  << endl; 
2327 }
2328
2329 void HtmlGenerator::endIndexList()
2330 {
2331   t << "</table>" << endl;
2332 }
2333
2334 void HtmlGenerator::startIndexKey() 
2335
2336   // inserted 'class = ...', 02 jan 2002, jh
2337   t << "  <tr><td class=\"indexkey\">"; 
2338 }
2339
2340 void HtmlGenerator::endIndexKey()
2341 {
2342   t << "</td>";
2343 }
2344
2345 void HtmlGenerator::startIndexValue(bool) 
2346
2347   // inserted 'class = ...', 02 jan 2002, jh
2348   t << "<td class=\"indexvalue\">"; 
2349 }
2350
2351 void HtmlGenerator::endIndexValue(const char *,bool)
2352 {
2353   t << "</td></tr>" << endl;
2354 }
2355
2356 void HtmlGenerator::startMemberDocList()
2357 {
2358   DBG_HTML(t << "<!-- startMemberDocList -->" << endl;)
2359 }
2360
2361 void HtmlGenerator::endMemberDocList()
2362 {
2363   DBG_HTML(t << "<!-- endMemberDocList -->" << endl;)
2364 }
2365
2366 void HtmlGenerator::startMemberDoc(const char *,const char *,const char *,const char *,bool) 
2367
2368   DBG_HTML(t << "<!-- startMemberDoc -->" << endl;)
2369  
2370   t << "\n<div class=\"memitem\">" << endl;
2371   t << "<div class=\"memproto\">" << endl;
2372 }
2373
2374 void HtmlGenerator::startMemberDocPrefixItem()
2375 {
2376   DBG_HTML(t << "<!-- startMemberDocPrefixItem -->" << endl;)
2377   t << "<div class=\"memtemplate\">" << endl;
2378 }
2379
2380 void HtmlGenerator::endMemberDocPrefixItem()
2381 {
2382   DBG_HTML(t << "<!-- endMemberDocPrefixItem -->" << endl;)
2383   t << "</div>" << endl;
2384 }
2385
2386 void HtmlGenerator::startMemberDocName(bool /*align*/)
2387 {
2388   DBG_HTML(t << "<!-- startMemberDocName -->" << endl;)
2389
2390   t << "      <table class=\"memname\">" << endl;
2391     
2392   t << "        <tr>" << endl;
2393   t << "          <td class=\"memname\">";
2394 }
2395
2396 void HtmlGenerator::endMemberDocName()
2397 {
2398   DBG_HTML(t << "<!-- endMemberDocName -->" << endl;)
2399   t << "</td>" << endl;
2400 }
2401
2402 void HtmlGenerator::startParameterList(bool openBracket)
2403 {
2404   DBG_HTML(t << "<!-- startParameterList -->" << endl;)
2405   t << "          <td>";
2406   if (openBracket) t << "(";
2407   t << "</td>" << endl;
2408 }
2409
2410 void HtmlGenerator::startParameterType(bool first,const char *key)
2411 {
2412   if (first)
2413   {
2414     DBG_HTML(t << "<!-- startFirstParameterType -->" << endl;)
2415     t << "          <td class=\"paramtype\">";
2416   }
2417   else
2418   {
2419     DBG_HTML(t << "<!-- startParameterType -->" << endl;)
2420     t << "        <tr>" << endl;
2421     t << "          <td class=\"paramkey\">";
2422     if (key) t << key;
2423     t << "</td>" << endl;
2424     t << "          <td></td>" << endl;
2425     t << "          <td class=\"paramtype\">";
2426   }
2427 }
2428
2429 void HtmlGenerator::endParameterType()
2430 {
2431   DBG_HTML(t << "<!-- endParameterType -->" << endl;)
2432   t << "&#160;</td>" << endl;
2433 }
2434
2435 void HtmlGenerator::startParameterName(bool /*oneArgOnly*/)
2436 {
2437   DBG_HTML(t << "<!-- startParameterName -->" << endl;)
2438   t << "          <td class=\"paramname\">";
2439 }
2440
2441 void HtmlGenerator::endParameterName(bool last,bool emptyList,bool closeBracket)
2442 {
2443   DBG_HTML(t << "<!-- endParameterName -->" << endl;)
2444   if (last)
2445   {
2446     if (emptyList)
2447     {
2448       if (closeBracket) t << "</td><td>)";
2449       t << "</td>" << endl;
2450       t << "          <td>";
2451     }
2452     else
2453     {
2454       t << "&#160;</td>" << endl;
2455       t << "        </tr>" << endl;
2456       t << "        <tr>" << endl;
2457       t << "          <td></td>" << endl;
2458       t << "          <td>";
2459       if (closeBracket) t << ")";
2460       t << "</td>" << endl;
2461       t << "          <td></td><td>";
2462     }
2463   }
2464   else
2465   {
2466     t << "</td>" << endl;
2467     t << "        </tr>" << endl;
2468   }
2469 }
2470
2471 void HtmlGenerator::endParameterList()
2472 {
2473   DBG_HTML(t << "<!-- endParameterList -->" << endl;)
2474   t << "</td>" << endl;
2475   t << "        </tr>" << endl;
2476 }
2477
2478 void HtmlGenerator::exceptionEntry(const char* prefix,bool closeBracket)
2479 {
2480   DBG_HTML(t << "<!-- exceptionEntry -->" << endl;)
2481   t << "</td>" << endl;
2482   t << "        </tr>" << endl;
2483   t << "        <tr>" << endl;
2484   t << "          <td align=\"right\">";
2485   // colspan 2 so it gets both parameter type and parameter name columns
2486   if (prefix)
2487     t << prefix << "</td><td>(</td><td colspan=\"2\">";
2488   else if (closeBracket)
2489     t << "</td><td>)</td><td></td><td>";
2490   else
2491     t << "</td><td></td><td colspan=\"2\">";
2492 }
2493
2494 void HtmlGenerator::endMemberDoc(bool hasArgs)     
2495
2496   DBG_HTML(t << "<!-- endMemberDoc -->" << endl;)
2497   if (!hasArgs)
2498   {
2499     t << "        </tr>" << endl;
2500   }
2501   t << "      </table>" << endl;
2502  // t << "</div>" << endl;
2503 }
2504
2505 void HtmlGenerator::startDotGraph()
2506 {
2507   startSectionHeader(t,relPath,m_sectionCount);
2508 }
2509
2510 void HtmlGenerator::endDotGraph(const DotClassGraph &g)
2511 {
2512   bool generateLegend = Config_getBool("GENERATE_LEGEND");
2513   bool umlLook = Config_getBool("UML_LOOK");
2514   endSectionHeader(t);
2515   startSectionSummary(t,m_sectionCount);
2516   endSectionSummary(t);
2517   startSectionContent(t,m_sectionCount);
2518
2519   g.writeGraph(t,BITMAP,dir,fileName,relPath,TRUE,TRUE,m_sectionCount);
2520   if (generateLegend && !umlLook)
2521   {
2522     t << "<center><span class=\"legend\">[";
2523     startHtmlLink(relPath+"graph_legend"+Doxygen::htmlFileExtension);
2524     t << theTranslator->trLegend();
2525     endHtmlLink();
2526     t << "]</span></center>";
2527   }
2528
2529   endSectionContent(t);
2530   m_sectionCount++;
2531 }
2532
2533 void HtmlGenerator::startInclDepGraph()
2534 {
2535   startSectionHeader(t,relPath,m_sectionCount);
2536 }
2537
2538 void HtmlGenerator::endInclDepGraph(const DotInclDepGraph &g)
2539 {
2540   endSectionHeader(t);
2541   startSectionSummary(t,m_sectionCount);
2542   endSectionSummary(t);
2543   startSectionContent(t,m_sectionCount);
2544
2545   g.writeGraph(t,BITMAP,dir,fileName,relPath,TRUE,m_sectionCount);
2546
2547   endSectionContent(t);
2548   m_sectionCount++;
2549 }
2550
2551 void HtmlGenerator::startGroupCollaboration()
2552 {
2553   startSectionHeader(t,relPath,m_sectionCount);
2554 }
2555
2556 void HtmlGenerator::endGroupCollaboration(const DotGroupCollaboration &g)
2557 {
2558   endSectionHeader(t);
2559   startSectionSummary(t,m_sectionCount);
2560   endSectionSummary(t);
2561   startSectionContent(t,m_sectionCount);
2562
2563   g.writeGraph(t,BITMAP,dir,fileName,relPath,TRUE,m_sectionCount);
2564
2565   endSectionContent(t);
2566   m_sectionCount++;
2567 }
2568
2569 void HtmlGenerator::startCallGraph()
2570 {
2571   startSectionHeader(t,relPath,m_sectionCount);
2572 }
2573
2574 void HtmlGenerator::endCallGraph(const DotCallGraph &g)
2575 {
2576   endSectionHeader(t);
2577   startSectionSummary(t,m_sectionCount);
2578   endSectionSummary(t);
2579   startSectionContent(t,m_sectionCount);
2580
2581   g.writeGraph(t,BITMAP,dir,fileName,relPath,TRUE,m_sectionCount);
2582
2583   endSectionContent(t);
2584   m_sectionCount++;
2585 }
2586
2587 void HtmlGenerator::startDirDepGraph()
2588 {
2589   startSectionHeader(t,relPath,m_sectionCount);
2590 }
2591
2592 void HtmlGenerator::endDirDepGraph(const DotDirDeps &g)
2593 {
2594   endSectionHeader(t);
2595   startSectionSummary(t,m_sectionCount);
2596   endSectionSummary(t);
2597   startSectionContent(t,m_sectionCount);
2598
2599   g.writeGraph(t,BITMAP,dir,fileName,relPath,TRUE,m_sectionCount);
2600
2601   endSectionContent(t);
2602   m_sectionCount++;
2603 }
2604
2605 void HtmlGenerator::writeGraphicalHierarchy(const DotGfxHierarchyTable &g)
2606 {
2607   g.writeGraph(t,dir,fileName);
2608 }
2609
2610 void HtmlGenerator::startMemberGroupHeader(bool)
2611 {
2612   t << "<tr><td colspan=\"2\"><div class=\"groupHeader\">";
2613 }
2614
2615 void HtmlGenerator::endMemberGroupHeader()
2616 {
2617   t << "</div></td></tr>" << endl;
2618 }
2619
2620 void HtmlGenerator::startMemberGroupDocs()
2621 {
2622   t << "<tr><td colspan=\"2\"><div class=\"groupText\">";
2623 }
2624
2625 void HtmlGenerator::endMemberGroupDocs()
2626 {
2627   t << "</div></td></tr>" << endl;
2628 }
2629
2630 void HtmlGenerator::startMemberGroup()
2631 {
2632 }
2633
2634 void HtmlGenerator::endMemberGroup(bool)
2635 {
2636 }
2637
2638 void HtmlGenerator::startIndent()        
2639
2640   DBG_HTML(t << "<!-- startIndent -->" << endl;)
2641
2642   t << "<div class=\"memdoc\">\n";
2643 }
2644
2645 void HtmlGenerator::endIndent()          
2646
2647   DBG_HTML(t << "<!-- endIndent -->" << endl;)
2648   t << endl << "</div>" << endl << "</div>" << endl; 
2649 }
2650
2651 void HtmlGenerator::addIndexItem(const char *,const char *)
2652 {
2653 }
2654
2655 void HtmlGenerator::writeNonBreakableSpace(int n)
2656 {
2657   int i;
2658   for (i=0;i<n;i++)
2659   {
2660     t << "&#160;";
2661   }
2662 }
2663
2664 void HtmlGenerator::startSimpleSect(SectionTypes,
2665                                 const char *filename,const char *anchor,
2666                                 const char *title)
2667 {
2668   t << "<dl><dt><b>";
2669   if (filename)
2670   {
2671     writeObjectLink(0,filename,anchor,title);
2672   }
2673   else
2674   {
2675     docify(title);
2676   }
2677   t << "</b></dt>";
2678 }
2679
2680 void HtmlGenerator::endSimpleSect()
2681 {
2682   t << "</dl>"; 
2683 }
2684
2685 void HtmlGenerator::startParamList(ParamListTypes,
2686                                 const char *title)
2687 {
2688   t << "<dl><dt><b>";
2689   docify(title);
2690   t << "</b></dt>";
2691 }
2692
2693 void HtmlGenerator::endParamList()
2694 {
2695   t << "</dl>"; 
2696 }
2697
2698 void HtmlGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
2699 {
2700   HtmlDocVisitor *visitor = new HtmlDocVisitor(t,m_codeGen,ctx);
2701   n->accept(visitor);
2702   delete visitor; 
2703 }
2704
2705 //---------------- helpers for index generation -----------------------------
2706
2707 static void startQuickIndexList(FTextStream &t,bool compact,bool topLevel=TRUE)
2708 {
2709   if (compact) 
2710   {
2711     if (topLevel)
2712     {
2713       t << "  <div id=\"navrow1\" class=\"tabs\">\n";
2714     }
2715     else
2716     {
2717       t << "  <div id=\"navrow2\" class=\"tabs2\">\n";
2718     }
2719     t << "    <ul class=\"tablist\">\n"; 
2720   }
2721   else 
2722   {
2723     t << "<ul>";
2724   }
2725 }
2726
2727 static void endQuickIndexList(FTextStream &t,bool compact)
2728 {
2729   if (compact) 
2730   {
2731     t << "    </ul>\n";
2732     t << "  </div>\n";
2733   }
2734   else 
2735   {
2736     t << "</ul>\n";
2737   }
2738 }
2739
2740 static void startQuickIndexItem(FTextStream &t,const char *l,
2741                                 bool hl,bool /*compact*/,
2742                                 const QCString &relPath)
2743 {
2744   t << "      <li"; 
2745   if (hl) 
2746   {
2747     t << " class=\"current\"";
2748   }
2749   t << ">";
2750   if (l) t << "<a href=\"" << correctURL(l,relPath) << "\">";
2751   t << "<span>";
2752 }
2753
2754 static void endQuickIndexItem(FTextStream &t,const char *l)
2755 {
2756   t << "</span>";
2757   if (l) t << "</a>";
2758   t << "</li>\n";
2759 }
2760
2761 static QCString fixSpaces(const QCString &s)
2762 {
2763   return substitute(s," ","&#160;");
2764 }
2765
2766 static bool quickLinkVisible(LayoutNavEntry::Kind kind)
2767 {
2768   static bool showFiles = Config_getBool("SHOW_FILES");
2769   static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
2770   switch (kind)
2771   {
2772     case LayoutNavEntry::MainPage:         return TRUE; 
2773     case LayoutNavEntry::User:             return TRUE;                                           
2774     case LayoutNavEntry::UserGroup:        return TRUE;                                           
2775     case LayoutNavEntry::Pages:            return indexedPages>0;
2776     case LayoutNavEntry::Modules:          return documentedGroups>0;
2777     case LayoutNavEntry::Namespaces:       return documentedNamespaces>0 && showNamespaces;
2778     case LayoutNavEntry::NamespaceList:    return documentedNamespaces>0 && showNamespaces;
2779     case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0;
2780     case LayoutNavEntry::Classes:          return annotatedClasses>0;
2781     case LayoutNavEntry::ClassList:        return annotatedClasses>0; 
2782     case LayoutNavEntry::ClassIndex:       return annotatedClasses>0; 
2783     case LayoutNavEntry::ClassHierarchy:   return hierarchyClasses>0;
2784     case LayoutNavEntry::ClassMembers:     return documentedClassMembers[CMHL_All]>0;
2785     case LayoutNavEntry::Files:            return documentedHtmlFiles>0 && showFiles;
2786     case LayoutNavEntry::FileList:         return documentedHtmlFiles>0 && showFiles;
2787     case LayoutNavEntry::FileGlobals:      return documentedFileMembers[FMHL_All]>0;
2788     //case LayoutNavEntry::Dirs:             return documentedDirs>0;
2789     case LayoutNavEntry::Examples:         return Doxygen::exampleSDict->count()>0;
2790   }
2791   return FALSE;
2792 }
2793
2794 static void renderQuickLinksAsTree(FTextStream &t,const QCString &relPath,LayoutNavEntry *root)
2795
2796 {
2797   QListIterator<LayoutNavEntry> li(root->children());
2798   LayoutNavEntry *entry;
2799   int count=0;
2800   for (li.toFirst();(entry=li.current());++li)
2801   {
2802     if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2803   }
2804   if (count>0) // at least one item is visible
2805   {
2806     startQuickIndexList(t,FALSE);
2807     for (li.toFirst();(entry=li.current());++li)
2808     {
2809       if (entry->visible() && quickLinkVisible(entry->kind()))
2810       {
2811         QCString url = entry->url();
2812         t << "<li><a href=\"" << relPath << url << "\"><span>";
2813         t << fixSpaces(entry->title());
2814         t << "</span></a>\n";
2815         // recursive into child list
2816         renderQuickLinksAsTree(t,relPath,entry);
2817         t << "</li>";
2818       }
2819     }
2820     endQuickIndexList(t,FALSE);
2821   }
2822 }
2823
2824
2825 static void renderQuickLinksAsTabs(FTextStream &t,const QCString &relPath,
2826                              LayoutNavEntry *hlEntry,LayoutNavEntry::Kind kind,
2827                              bool highlightParent,bool highlightSearch)
2828 {
2829   if (hlEntry->parent()) // first draw the tabs for the parent of hlEntry
2830   {
2831     renderQuickLinksAsTabs(t,relPath,hlEntry->parent(),kind,highlightParent,highlightSearch);
2832   }
2833   if (hlEntry->parent() && hlEntry->parent()->children().count()>0) // draw tabs for row containing hlEntry
2834   {
2835     bool topLevel = hlEntry->parent()->parent()==0;
2836     QListIterator<LayoutNavEntry> li(hlEntry->parent()->children());
2837     LayoutNavEntry *entry;
2838
2839     int count=0;
2840     for (li.toFirst();(entry=li.current());++li)
2841     {
2842       if (entry->visible() && quickLinkVisible(entry->kind())) count++;
2843     }
2844     if (count>0) // at least one item is visible
2845     {
2846       startQuickIndexList(t,TRUE,topLevel);
2847       for (li.toFirst();(entry=li.current());++li)
2848       {
2849         if (entry->visible() && quickLinkVisible(entry->kind()))
2850         {
2851           QCString url = entry->url();
2852           startQuickIndexItem(t,url,
2853               entry==hlEntry  && 
2854               (entry->children().count()>0 || 
2855                (entry->kind()==kind && !highlightParent)
2856               ),
2857               TRUE,relPath);
2858           t << fixSpaces(entry->title());
2859           endQuickIndexItem(t,url);
2860         }
2861       }
2862       if (hlEntry->parent()==LayoutDocManager::instance().rootNavEntry()) // first row is special as it contains the search box
2863       {
2864         static bool searchEngine      = Config_getBool("SEARCHENGINE");
2865         static bool serverBasedSearch = Config_getBool("SERVER_BASED_SEARCH");
2866         if (searchEngine)
2867         {
2868           t << "      <li>\n";
2869           if (!serverBasedSearch) // pure client side search
2870           {
2871             writeClientSearchBox(t,relPath);
2872             t << "      </li>\n";
2873           }
2874           else // server based search
2875           {
2876             writeServerSearchBox(t,relPath,highlightSearch);
2877             if (!highlightSearch)
2878             {
2879               t << "      </li>\n";
2880             }
2881           }
2882         }
2883         if (!highlightSearch) // on the search page the index will be ended by the
2884           // page itself
2885         {
2886           endQuickIndexList(t,TRUE);
2887         }
2888       }
2889       else // normal case for other rows than first one
2890       {
2891         endQuickIndexList(t,TRUE);
2892       }
2893     }
2894   }
2895 }
2896
2897 static void writeDefaultQuickLinks(FTextStream &t,bool compact,
2898                                    HighlightedItem hli,
2899                                    const char *file,
2900                                    const QCString &relPath)
2901 {
2902   LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry();
2903   LayoutNavEntry::Kind kind = (LayoutNavEntry::Kind)-1;
2904   LayoutNavEntry::Kind altKind = (LayoutNavEntry::Kind)-1; // fall back for the old layout file
2905   bool highlightParent=FALSE;
2906   switch (hli) // map HLI enums to LayoutNavEntry::Kind enums
2907   {
2908     case HLI_Main:             kind = LayoutNavEntry::MainPage;         break;
2909     case HLI_Modules:          kind = LayoutNavEntry::Modules;          break;
2910     //case HLI_Directories:      kind = LayoutNavEntry::Dirs;             break;
2911     case HLI_Namespaces:       kind = LayoutNavEntry::NamespaceList;    altKind = LayoutNavEntry::Namespaces;  break;
2912     case HLI_Hierarchy:        kind = LayoutNavEntry::ClassHierarchy;   break;
2913     case HLI_Classes:          kind = LayoutNavEntry::ClassIndex;       altKind = LayoutNavEntry::Classes;     break;
2914     case HLI_Annotated:        kind = LayoutNavEntry::ClassList;        altKind = LayoutNavEntry::Classes;     break;
2915     case HLI_Files:            kind = LayoutNavEntry::FileList;         altKind = LayoutNavEntry::Files;       break;
2916     case HLI_NamespaceMembers: kind = LayoutNavEntry::NamespaceMembers; break;
2917     case HLI_Functions:        kind = LayoutNavEntry::ClassMembers;     break;
2918     case HLI_Globals:          kind = LayoutNavEntry::FileGlobals;      break;
2919     case HLI_Pages:            kind = LayoutNavEntry::Pages;            break;
2920     case HLI_Examples:         kind = LayoutNavEntry::Examples;         break;
2921     case HLI_UserGroup:        kind = LayoutNavEntry::UserGroup;        break;
2922     case HLI_ClassVisible:     kind = LayoutNavEntry::ClassList;        altKind = LayoutNavEntry::Classes;          
2923                                highlightParent = TRUE; break;
2924     case HLI_NamespaceVisible: kind = LayoutNavEntry::NamespaceList;    altKind = LayoutNavEntry::Namespaces;       
2925                                highlightParent = TRUE; break;
2926     case HLI_FileVisible:      kind = LayoutNavEntry::FileList;         altKind = LayoutNavEntry::Files;            
2927                                highlightParent = TRUE; break;
2928     case HLI_None:   break;
2929     case HLI_Search: break;
2930   }
2931   
2932   if (compact)
2933   {
2934     // find highlighted index item
2935     LayoutNavEntry *hlEntry = root->find(kind,kind==LayoutNavEntry::UserGroup ? file : 0);
2936     if (!hlEntry && altKind!=(LayoutNavEntry::Kind)-1) { hlEntry=root->find(altKind); kind=altKind; }
2937     if (!hlEntry) // highlighted item not found in the index! -> just show the level 1 index...
2938     {
2939       highlightParent=TRUE;
2940       hlEntry = root->children().getFirst();
2941       if (hlEntry==0) 
2942       {
2943         return; // argl, empty index!
2944       }
2945     }
2946     if (kind==LayoutNavEntry::UserGroup)
2947     {
2948       LayoutNavEntry *e = hlEntry->children().getFirst();
2949       if (e)
2950       {
2951         hlEntry = e; 
2952       }
2953     }
2954     renderQuickLinksAsTabs(t,relPath,hlEntry,kind,highlightParent,hli==HLI_Search);
2955   }
2956   else
2957   {
2958     renderQuickLinksAsTree(t,relPath,root);
2959   }
2960 }
2961
2962 void HtmlGenerator::endQuickIndices()
2963 {
2964   t << "</div><!-- top -->" << endl;
2965 }
2966
2967 QCString HtmlGenerator::writeSplitBarAsString(const char *name,const char *relpath)
2968 {
2969   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2970   QCString result;
2971   // write split bar
2972   if (generateTreeView)
2973   {
2974     result = QCString(
2975     "<div id=\"side-nav\" class=\"ui-resizable side-nav-resizable\">\n"
2976     "  <div id=\"nav-tree\">\n"
2977     "    <div id=\"nav-tree-contents\">\n"
2978     "      <div id=\"nav-sync\" class=\"sync\"></div>\n"
2979     "    </div>\n"
2980     "  </div>\n"
2981     "  <div id=\"splitbar\" style=\"-moz-user-select:none;\" \n"
2982     "       class=\"ui-resizable-handle\">\n"
2983     "  </div>\n"
2984     "</div>\n"
2985     "<script type=\"text/javascript\">\n"
2986     "$(document).ready(function(){initNavTree('") + 
2987     QCString(name) + Doxygen::htmlFileExtension + 
2988     QCString("','") + relpath +
2989     QCString("');});\n"
2990     "</script>\n"
2991     "<div id=\"doc-content\">\n");
2992   }
2993   return result;
2994 }
2995
2996 void HtmlGenerator::writeSplitBar(const char *name)
2997 {
2998   t << writeSplitBarAsString(name,relPath);
2999 }
3000
3001 void HtmlGenerator::writeNavigationPath(const char *s)
3002 {
3003   t << substitute(s,"$relpath^",relPath);
3004 }
3005
3006 void HtmlGenerator::startContents()
3007 {
3008   t << "<div class=\"contents\">" << endl;
3009 }
3010
3011 void HtmlGenerator::endContents()
3012 {
3013   t << "</div><!-- contents -->" << endl;
3014 }
3015
3016 void HtmlGenerator::writeQuickLinks(bool compact,HighlightedItem hli,const char *file)
3017 {
3018   writeDefaultQuickLinks(t,compact,hli,file,relPath);
3019 }
3020
3021 // PHP based search script
3022 void HtmlGenerator::writeSearchPage()
3023 {
3024   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
3025   static bool disableIndex = Config_getBool("DISABLE_INDEX");
3026   static QCString projectName = Config_getString("PROJECT_NAME");
3027
3028   // OPENSEARCH_PROVIDER {
3029   QCString configFileName = Config_getString("HTML_OUTPUT")+"/search-config.php";
3030   QFile cf(configFileName);
3031   if (cf.open(IO_WriteOnly))
3032   {
3033     FTextStream t(&cf);
3034     t << "<script language=\"php\">\n\n";
3035     t << "$config = array(\n";
3036     t << "  'PROJECT_NAME' => \"" << convertToHtml(projectName) << "\",\n";
3037     t << "  'GENERATE_TREEVIEW' => " << (generateTreeView?"true":"false") << ",\n";
3038     t << "  'DISABLE_INDEX' => " << (disableIndex?"true":"false") << ",\n";
3039     t << ");\n\n";
3040     t << "$translator = array(\n";
3041     t << "  'search_results_title' => \"" << theTranslator->trSearchResultsTitle() << "\",\n";
3042     t << "  'search_results' => array(\n";  
3043     t << "    0 => \"" << theTranslator->trSearchResults(0) << "\",\n";     
3044     t << "    1 => \"" << theTranslator->trSearchResults(1) << "\",\n";     
3045     t << "    2 => \"" << substitute(theTranslator->trSearchResults(2), "$", "\\$") << "\",\n";     
3046     t << "  ),\n";
3047     t << "  'search_matches' => \"" << theTranslator->trSearchMatches() << "\",\n";
3048     t << "  'search' => \"" << theTranslator->trSearch() << "\",\n";
3049     t << "  'split_bar' => \"" << substitute(substitute(writeSplitBarAsString("search",""), "\"","\\\""), "\n","\\n") << "\",\n";
3050     t << "  'logo' => \"" << substitute(substitute(writeLogoAsString(""), "\"","\\\""), "\n","\\n") << "\",\n";
3051     t << ");\n\n";
3052     t << "</script>\n";
3053   }
3054
3055   QCString functionsFileName = Config_getString("HTML_OUTPUT")+"/search-functions.php";
3056   QFile ff(functionsFileName);
3057   if (ff.open(IO_WriteOnly))
3058   {
3059     FTextStream t(&ff);
3060     // Write stuff from search_functions.php source file...
3061     t << search_functions_script;
3062   }
3063
3064   QCString opensearchFileName = Config_getString("HTML_OUTPUT")+"/search-opensearch.php";
3065   QFile of(opensearchFileName);
3066   if (of.open(IO_WriteOnly))
3067   {
3068     FTextStream t(&of);
3069     // Write stuff from search_opensearch.php source file...
3070     t << search_opensearch_script;
3071   }
3072   // OPENSEARCH_PROVIDER }
3073
3074   QCString fileName = Config_getString("HTML_OUTPUT")+"/search.php";
3075   QFile f(fileName);
3076   if (f.open(IO_WriteOnly))
3077   {
3078     FTextStream t(&f);
3079     t << substituteHtmlKeywords(g_header,"Search","");
3080
3081     t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
3082       << versionString << " -->" << endl;
3083     t << "<script type=\"text/javascript\">\n";
3084     t << "var searchBox = new SearchBox(\"searchBox\", \""
3085       << "search\",false,'" << theTranslator->trSearch() << "');\n";
3086     t << "</script>\n";
3087     if (!Config_getBool("DISABLE_INDEX"))
3088     {
3089       writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
3090     }
3091     else
3092     {
3093       t << "</div>" << endl;
3094     }
3095
3096     t << "<script language=\"php\">\n";
3097     t << "require_once \"search-functions.php\";\n";
3098     t << "main();\n";
3099     t << "</script>\n";
3100
3101     // Write empty navigation path, to make footer connect properly
3102     if (generateTreeView)
3103     {
3104       t << "</div><!-- doc-contents -->\n";
3105       //t << "<div id=\"nav-path\" class=\"navpath\">\n";
3106       //t << "  <ul>\n";
3107     }
3108
3109     writePageFooter(t,"Search","","");
3110   }
3111   QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
3112   QFile sf(scriptName);
3113   if (sf.open(IO_WriteOnly))
3114   {
3115     FTextStream t(&sf);
3116     t << extsearch_script;
3117   }
3118   else
3119   {
3120      err("Failed to open file '%s' for writing...\n",scriptName.data());
3121   }
3122 }
3123
3124 void HtmlGenerator::writeExternalSearchPage()
3125 {
3126   static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
3127   QCString fileName = Config_getString("HTML_OUTPUT")+"/search"+Doxygen::htmlFileExtension;
3128   QFile f(fileName);
3129   if (f.open(IO_WriteOnly))
3130   {
3131     FTextStream t(&f);
3132     t << substituteHtmlKeywords(g_header,"Search","");
3133
3134     t << "<!-- " << theTranslator->trGeneratedBy() << " Doxygen " 
3135       << versionString << " -->" << endl;
3136     t << "<script type=\"text/javascript\">\n";
3137     t << "var searchBox = new SearchBox(\"searchBox\", \""
3138       << "search\",false,'" << theTranslator->trSearch() << "');\n";
3139     t << "</script>\n";
3140     if (!Config_getBool("DISABLE_INDEX"))
3141     {
3142       writeDefaultQuickLinks(t,TRUE,HLI_Search,0,"");
3143       t << "            <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n";
3144       t << "            </form>\n";
3145       t << "          </div><div class=\"right\"></div>\n";
3146       t << "        </div>\n";
3147       t << "      </li>\n";
3148       t << "    </ul>\n";
3149       t << "  </div>\n";
3150       t << "</div>\n";
3151     }
3152     else
3153     {
3154       t << "</div>" << endl;
3155     }
3156     t << writeSplitBarAsString("search","");
3157     t << "<div class=\"header\">" << endl;
3158     t << "  <div class=\"headertitle\">" << endl;
3159     t << "    <div class=\"title\">" << theTranslator->trSearchResultsTitle() << "</div>" << endl;
3160     t << "  </div>" << endl;
3161     t << "</div>" << endl;
3162     t << "<div class=\"contents\">" << endl;
3163
3164     t << "<div id=\"searchresults\"></div>" << endl;
3165     t << "</div>" << endl;
3166
3167     if (generateTreeView)
3168     {
3169       t << "</div><!-- doc-contents -->" << endl;
3170     }
3171
3172     writePageFooter(t,"Search","","");
3173   }
3174   QCString scriptName = Config_getString("HTML_OUTPUT")+"/search/search.js";
3175   QFile sf(scriptName);
3176   if (sf.open(IO_WriteOnly))
3177   {
3178     FTextStream t(&sf);
3179     t << "var searchResultsText=["
3180       << "\"" << theTranslator->trSearchResults(0) << "\","
3181       << "\"" << theTranslator->trSearchResults(1) << "\","
3182       << "\"" << theTranslator->trSearchResults(2) << "\"];" << endl;
3183     t << "var serverUrl=\"" << Config_getString("SEARCHENGINE_URL") << "\";" << endl;
3184     t << "var tagMap = {" << endl;
3185     bool first=TRUE;
3186     // add search mappings
3187     QStrList &extraSearchMappings = Config_getList("EXTRA_SEARCH_MAPPINGS");
3188     char *ml=extraSearchMappings.first();
3189     while (ml)
3190     {
3191       QCString mapLine = ml;
3192       int eqPos = mapLine.find('=');
3193       if (eqPos!=-1) // tag command contains a destination
3194       {
3195         QCString tagName = mapLine.left(eqPos).stripWhiteSpace();
3196         QCString destName = mapLine.right(mapLine.length()-eqPos-1).stripWhiteSpace();
3197         if (!tagName.isEmpty())
3198         {
3199           if (!first) t << "," << endl;
3200           t << "  \"" << tagName << "\": \"" << destName << "\"";
3201           first=FALSE;
3202         }
3203       }
3204       ml=extraSearchMappings.next();
3205     }
3206     if (!first) t << endl;
3207     t << "};" << endl << endl;
3208     t << extsearch_script;
3209     t << endl;
3210     t << "$(document).ready(function() {" << endl;
3211     t << "  var query = trim(getURLParameter('query'));" << endl;
3212     t << "  if (query) {" << endl;
3213     t << "    searchFor(query,0,20);" << endl;
3214     t << "  } else {" << endl;
3215     t << "    var results = $('#results');" << endl;
3216     t << "    results.html('<p>" << theTranslator->trSearchResults(0) << "</p>');" << endl;
3217     t << "  }" << endl;
3218     t << "});" << endl;
3219   }
3220   else
3221   {
3222      err("Failed to open file '%s' for writing...\n",scriptName.data());
3223   }
3224 }
3225
3226 void HtmlGenerator::startConstraintList(const char *header)
3227 {
3228   t << "<div class=\"typeconstraint\">" << endl;
3229   t << "<dl><dt><b>" << header << "</b></dt><dd>" << endl;
3230   t << "<table border=\"0\" cellspacing=\"2\" cellpadding=\"0\">" << endl;
3231 }
3232
3233 void HtmlGenerator::startConstraintParam()
3234 {
3235   t << "<tr><td valign=\"top\"><em>";
3236 }
3237
3238 void HtmlGenerator::endConstraintParam()
3239 {
3240   t << "</em></td>";
3241 }
3242
3243 void HtmlGenerator::startConstraintType()
3244 {
3245   t << "<td>&#160;:</td><td valign=\"top\"><em>";
3246 }
3247
3248 void HtmlGenerator::endConstraintType()
3249 {
3250   t << "</em></td>";
3251 }
3252
3253 void HtmlGenerator::startConstraintDocs()
3254 {
3255   t << "<td>&#160;";
3256 }
3257
3258 void HtmlGenerator::endConstraintDocs()
3259 {
3260   t << "</td></tr>" << endl;
3261 }
3262
3263 void HtmlGenerator::endConstraintList()
3264 {
3265   t << "</table>" << endl;
3266   t << "</dl>" << endl;
3267   t << "</div>" << endl;
3268 }
3269
3270 void HtmlGenerator::lineBreak(const char *style)
3271 {
3272   if (style)
3273   {
3274     t << "<br class=\"" << style << "\" />" << endl;
3275   }
3276   else
3277   {
3278     t << "<br />" << endl;
3279   }
3280 }
3281
3282 void HtmlGenerator::startHeaderSection()
3283 {
3284   t << "<div class=\"header\">" << endl;
3285 }
3286
3287 void HtmlGenerator::startTitleHead(const char *) 
3288
3289   t << "  <div class=\"headertitle\">" << endl;
3290   startTitle(); 
3291 }
3292
3293 void HtmlGenerator::endTitleHead(const char *,const char *) 
3294
3295   endTitle(); 
3296   t << "  </div>" << endl;
3297 }
3298
3299 void HtmlGenerator::endHeaderSection()
3300 {
3301   t << "</div><!--header-->" << endl;
3302 }
3303
3304 void HtmlGenerator::startInlineHeader()
3305 {
3306   if (m_emptySection)
3307   {
3308     t << "<table class=\"memberdecls\">" << endl;
3309     m_emptySection=FALSE;
3310   }
3311   t << "<tr><td colspan=\"2\"><h3>";
3312 }
3313
3314 void HtmlGenerator::endInlineHeader()
3315 {
3316   t << "</h3></td></tr>" << endl;
3317 }
3318
3319 void HtmlGenerator::startMemberDocSimple()
3320 {
3321   DBG_HTML(t << "<!-- startMemberDocSimple -->" << endl;)
3322   t << "<table class=\"fieldtable\">" << endl;
3323   t << "<tr><th colspan=\"3\">" << theTranslator->trCompoundMembers() << "</th></tr>" << endl;
3324 }
3325
3326 void HtmlGenerator::endMemberDocSimple()
3327 {
3328   DBG_HTML(t << "<!-- endMemberDocSimple -->" << endl;)
3329   t << "</table>" << endl;
3330 }
3331
3332 void HtmlGenerator::startInlineMemberType()
3333 {
3334   DBG_HTML(t << "<!-- startInlineMemberType -->" << endl;)
3335   t << "<tr><td class=\"fieldtype\">" << endl;
3336 }
3337
3338 void HtmlGenerator::endInlineMemberType()
3339 {
3340   DBG_HTML(t << "<!-- endInlineMemberType -->" << endl;)
3341   t << "</td>" << endl;
3342 }
3343
3344 void HtmlGenerator::startInlineMemberName()
3345 {
3346   DBG_HTML(t << "<!-- startInlineMemberName -->" << endl;)
3347   t << "<td class=\"fieldname\">" << endl;
3348 }
3349
3350 void HtmlGenerator::endInlineMemberName()
3351 {
3352   DBG_HTML(t << "<!-- endInlineMemberName -->" << endl;)
3353   t << "</td>" << endl;
3354 }
3355
3356 void HtmlGenerator::startInlineMemberDoc()
3357 {
3358   DBG_HTML(t << "<!-- startInlineMemberDoc -->" << endl;)
3359   t << "<td class=\"fielddoc\">" << endl;
3360 }
3361
3362 void HtmlGenerator::endInlineMemberDoc()
3363 {
3364   DBG_HTML(t << "<!-- endInlineMemberDoc -->" << endl;)
3365   t << "</td></tr>" << endl;
3366 }
3367
3368 void HtmlGenerator::startLabels()
3369 {
3370   DBG_HTML(t << "<!-- startLabels -->" << endl;)
3371   t << "<span class=\"mlabels\">";
3372 }
3373
3374 void HtmlGenerator::writeLabel(const char *l,bool /*isLast*/)
3375 {
3376   DBG_HTML(t << "<!-- writeLabel(" << l << ") -->" << endl;)
3377   //t << "<tt>[" << l << "]</tt>";
3378   //if (!isLast) t << ", ";
3379   t << "<span class=\"mlabel\">" << l << "</span>";
3380 }
3381
3382 void HtmlGenerator::endLabels()
3383 {
3384   DBG_HTML(t << "<!-- endLabels -->" << endl;)
3385   t << "</span>";
3386 }
3387
3388 void HtmlGenerator::writeInheritedSectionTitle(
3389                   const char *id,    const char *ref, 
3390                   const char *file,  const char *anchor,
3391                   const char *title, const char *name)
3392 {
3393   DBG_HTML(t << "<!-- writeInheritedSectionTitle -->" << endl;)
3394   QCString a = anchor;
3395   if (!a.isEmpty()) a.prepend("#");
3396   QCString classLink = QCString("<a class=\"el\" href=\"");
3397   if (ref)
3398   {
3399     classLink+= externalLinkTarget() + externalRef(relPath,ref,TRUE);
3400   }
3401   else
3402   {
3403     classLink+=relPath;
3404   }
3405   classLink+=file+Doxygen::htmlFileExtension+a;
3406   classLink+=QCString("\">")+convertToHtml(name,FALSE)+"</a>";
3407   t << "<tr class=\"inherit_header " << id << "\">"
3408     << "<td colspan=\"2\" onclick=\"javascript:toggleInherit('" << id << "')\">"
3409     << "<img src=\"" << relPath << "closed.png\" alt=\"-\"/>&#160;" 
3410     << theTranslator->trInheritedFrom(convertToHtml(title,FALSE),classLink)
3411     << "</td></tr>" << endl;
3412 }
3413
3414 void HtmlGenerator::writeSummaryLink(const char *file,const char *anchor,const char *title,bool first)
3415 {
3416   if (first)
3417   {
3418     t << "  <div class=\"summary\">\n";
3419   }
3420   else
3421   {
3422     t << " &#124;\n";
3423   }
3424   t << "<a href=\"";
3425   if (file)
3426   {
3427     t << relPath << file;
3428     t << Doxygen::htmlFileExtension;
3429   }
3430   else
3431   {
3432     t << "#";
3433     t << anchor;
3434   }
3435   t << "\">";
3436   t << title;
3437   t << "</a>";
3438 }
3439
3440 void HtmlGenerator::endMemberDeclaration(const char *anchor,const char *inheritId)
3441 {
3442   t << "<tr class=\"separator:" << anchor;
3443   if (inheritId)
3444   {
3445     t << " inherit " << inheritId;
3446   }
3447   t << "\"><td class=\"memSeparator\" colspan=\"2\">&#160;</td></tr>\n";
3448 }
3449
3450 void HtmlGenerator::setCurrentDoc(Definition *context,const char *anchor,bool isSourceFile)
3451 {
3452   if (Doxygen::searchIndex)
3453   {
3454     Doxygen::searchIndex->setCurrentDoc(context,anchor,isSourceFile);
3455   }
3456 }
3457
3458 void HtmlGenerator::addWord(const char *word,bool hiPriority)
3459 {
3460   if (Doxygen::searchIndex)
3461   {
3462     Doxygen::searchIndex->addWord(word,hiPriority);
3463   }
3464 }
3465