]> git.saurik.com Git - wxWidgets.git/blame - src/html/winpars.cpp
Highly experimental, unstable code (for determining the
[wxWidgets.git] / src / html / winpars.cpp
CommitLineData
5526e819 1/////////////////////////////////////////////////////////////////////////////
69941f05 2// Name: winpars.cpp
5526e819
VS
3// Purpose: wxHtmlParser class (generic parser)
4// Author: Vaclav Slavik
69941f05 5// RCS-ID: $Id$
5526e819
VS
6// Copyright: (c) 1999 Vaclav Slavik
7// Licence: wxWindows Licence
8/////////////////////////////////////////////////////////////////////////////
9
10
11#ifdef __GNUG__
12#pragma implementation
13#endif
14
3096bd2f 15#include "wx/wxprec.h"
5526e819
VS
16
17#include "wx/defs.h"
18#if wxUSE_HTML
19
20#ifdef __BORDLANDC__
21#pragma hdrstop
22#endif
23
24#ifndef WXPRECOMP
3096bd2f 25#include "wx/wx.h"
5526e819
VS
26#endif
27
69941f05
VS
28#include "wx/html/htmldefs.h"
29#include "wx/html/winpars.h"
30#include "wx/html/htmlwin.h"
b250d384 31#include "wx/fontmap.h"
f3c82859 32#include "wx/log.h"
5526e819
VS
33
34
35//-----------------------------------------------------------------------------
36// wxHtmlWinParser
37//-----------------------------------------------------------------------------
38
5526e819
VS
39
40wxList wxHtmlWinParser::m_Modules;
41
42wxHtmlWinParser::wxHtmlWinParser(wxWindow *wnd) : wxHtmlParser()
43{
44 m_Window = wnd;
45 m_Container = NULL;
46 m_DC = NULL;
47 m_CharHeight = m_CharWidth = 0;
48 m_UseLink = FALSE;
b250d384
VS
49 m_EncConv = NULL;
50 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
5526e819
VS
51
52 {
53 int i, j, k, l, m;
54 for (i = 0; i < 2; i++)
55 for (j = 0; j < 2; j++)
56 for (k = 0; k < 2; k++)
57 for (l = 0; l < 2; l++)
f1ad10f3 58 for (m = 0; m < 7; m++) {
5526e819 59 m_FontsTable[i][j][k][l][m] = NULL;
f1ad10f3 60 m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
b250d384 61 m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
f1ad10f3 62 }
5526e819 63#ifdef __WXMSW__
1bb27b0c 64 static int default_sizes[7] = {7, 8, 10, 12, 16, 22, 30};
cc638fc6
VS
65#elif defined(__WXMAC__)
66 static int default_sizes[7] = {9, 12, 14, 18, 24, 30, 36};
5526e819 67#else
1bb27b0c 68 static int default_sizes[7] = {10, 12, 14, 16, 19, 24, 32};
5526e819 69#endif
8eb2940f 70 SetFonts("", "", default_sizes);
5526e819
VS
71 }
72
73 // fill in wxHtmlParser's tables:
74 wxNode *node = m_Modules.GetFirst();
c9f56e70 75 while (node) {
5526e819
VS
76 wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node -> GetData();
77 mod -> FillHandlersTable(this);
78 node = node -> GetNext();
79 }
80}
81
82
b250d384
VS
83wxHtmlWinParser::~wxHtmlWinParser()
84{
85 int i, j, k, l, m;
86
87 for (i = 0; i < 2; i++)
88 for (j = 0; j < 2; j++)
89 for (k = 0; k < 2; k++)
90 for (l = 0; l < 2; l++)
91 for (m = 0; m < 7; m++) {
92 if (m_FontsTable[i][j][k][l][m] != NULL)
93 delete m_FontsTable[i][j][k][l][m];
94 }
95 if (m_EncConv) delete m_EncConv;
96}
97
5526e819
VS
98
99void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
100{
101 m_Modules.Append(module);
102}
103
104
105
8eb2940f 106void wxHtmlWinParser::SetFonts(wxString normal_face, wxString fixed_face, const int *sizes)
5526e819 107{
c9f56e70
VS
108 int i, j, k, l, m;
109
110 for (i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
5526e819
VS
111 m_FontFaceFixed = fixed_face;
112 m_FontFaceNormal = normal_face;
b250d384
VS
113
114 SetInputEncoding(m_InputEnc);
c9f56e70
VS
115
116 for (i = 0; i < 2; i++)
117 for (j = 0; j < 2; j++)
118 for (k = 0; k < 2; k++)
119 for (l = 0; l < 2; l++)
120 for (m = 0; m < 7; m++) {
121 if (m_FontsTable[i][j][k][l][m] != NULL) {
122 delete m_FontsTable[i][j][k][l][m];
123 m_FontsTable[i][j][k][l][m] = NULL;
124 }
125 }
5526e819
VS
126}
127
128
129
130void wxHtmlWinParser::InitParser(const wxString& source)
131{
132 wxHtmlParser::InitParser(source);
0e8c8233 133 wxASSERT_MSG(m_DC != NULL, _T("no DC assigned to wxHtmlWinParser!!"));
5526e819
VS
134
135 m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
f2c2fa4d 136 m_FontSize = 3; //default one
5526e819
VS
137 CreateCurrentFont(); // we're selecting default font into
138 m_DC -> GetTextExtent("H", &m_CharWidth, &m_CharHeight);
139 /* NOTE : we're not using GetCharWidth/Height() because
0e8c8233 140 of differences under X and win
5526e819
VS
141 */
142
f2c2fa4d
VS
143 m_UseLink = FALSE;
144 m_Link = wxHtmlLinkInfo("", "");
5526e819
VS
145 m_LinkColor.Set(0, 0, 0xFF);
146 m_ActualColor.Set(0, 0, 0);
efba2b89 147 m_Align = wxHTML_ALIGN_LEFT;
5526e819
VS
148 m_tmpLastWasSpace = FALSE;
149
150 OpenContainer();
151
152 OpenContainer();
153 m_Container -> InsertCell(new wxHtmlColourCell(m_ActualColor));
154 m_Container -> InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
155}
156
157
158
159void wxHtmlWinParser::DoneParser()
160{
161 m_Container = NULL;
b250d384 162 SetInputEncoding(wxFONTENCODING_DEFAULT); // for next call
5526e819
VS
163 wxHtmlParser::DoneParser();
164}
165
166
167
168wxObject* wxHtmlWinParser::GetProduct()
169{
170 wxHtmlContainerCell *top;
171
172 CloseContainer();
173 OpenContainer();
67cfebc2 174
5526e819
VS
175 top = m_Container;
176 while (top -> GetParent()) top = top -> GetParent();
177 return top;
178}
179
180
181
5526e819
VS
182void wxHtmlWinParser::AddText(const char* txt)
183{
184 wxHtmlCell *c;
185 int i = 0, x, lng = strlen(txt);
efba2b89 186 char temp[wxHTML_BUFLEN];
5526e819
VS
187 register char d;
188 int templen = 0;
189
190 if (m_tmpLastWasSpace) {
191 while ((i < lng) && ((txt[i] == '\n') || (txt[i] == '\r') || (txt[i] == ' ') || (txt[i] == '\t'))) i++;
192 }
193
194 while (i < lng) {
195 x = 0;
196 d = temp[templen++] = txt[i];
197 if ((d == '\n') || (d == '\r') || (d == ' ') || (d == '\t')) {
198 i++, x++;
199 while ((i < lng) && ((txt[i] == '\n') || (txt[i] == '\r') || (txt[i] == ' ') || (txt[i] == '\t'))) i++, x++;
200 }
201 else i++;
202
203 if (x) {
204 temp[templen-1] = ' ';
205 temp[templen] = 0;
206 templen = 0;
b250d384 207 if (m_EncConv) m_EncConv -> Convert(temp);
5526e819
VS
208 c = new wxHtmlWordCell(temp, *(GetDC()));
209 if (m_UseLink) c -> SetLink(m_Link);
210 m_Container -> InsertCell(c);
211 m_tmpLastWasSpace = TRUE;
212 }
213 }
214 if (templen) {
215 temp[templen] = 0;
b250d384 216 if (m_EncConv) m_EncConv -> Convert(temp);
5526e819
VS
217 c = new wxHtmlWordCell(temp, *(GetDC()));
218 if (m_UseLink) c -> SetLink(m_Link);
219 m_Container -> InsertCell(c);
220 m_tmpLastWasSpace = FALSE;
221 }
222}
223
224
225
226wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
227{
228 m_Container = new wxHtmlContainerCell(m_Container);
229 m_Container -> SetAlignHor(m_Align);
230 m_tmpLastWasSpace = TRUE;
231 /* to avoid space being first character in paragraph */
232 return m_Container;
233}
234
235
236
237wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
238{
239 m_tmpLastWasSpace = TRUE;
240 /* to avoid space being first character in paragraph */
241 return m_Container = c;
242}
243
244
245
246wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
247{
248 m_Container = m_Container -> GetParent();
249 return m_Container;
250}
251
252
f2c2fa4d
VS
253void wxHtmlWinParser::SetFontSize(int s)
254{
255 if (s < 1) s = 1;
256 else if (s > 7) s = 7;
257 m_FontSize = s;
258}
259
260
261
5526e819
VS
262wxFont* wxHtmlWinParser::CreateCurrentFont()
263{
264 int fb = GetFontBold(),
265 fi = GetFontItalic(),
266 fu = GetFontUnderlined(),
267 ff = GetFontFixed(),
f2c2fa4d 268 fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
5526e819 269
f1ad10f3
VS
270 wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
271 wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
272 wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
b250d384 273 wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
f1ad10f3 274
b250d384 275 if (*fontptr != NULL && (*faceptr != face || *encptr != m_OutputEnc)) {
f1ad10f3
VS
276 delete *fontptr;
277 *fontptr = NULL;
278 }
279
280 if (*fontptr == NULL) {
281 *faceptr = face;
b250d384 282 *encptr = m_OutputEnc;
f1ad10f3
VS
283 *fontptr = new wxFont(
284 m_FontsSizes[fs] * m_PixelScale,
285 ff ? wxMODERN : wxSWISS,
286 fi ? wxITALIC : wxNORMAL,
287 fb ? wxBOLD : wxNORMAL,
b250d384
VS
288 fu ? TRUE : FALSE, face,
289 m_OutputEnc);
5526e819 290 }
f1ad10f3
VS
291 m_DC -> SetFont(**fontptr);
292 return (*fontptr);
5526e819
VS
293}
294
295
296
f2c2fa4d
VS
297void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
298{
299 m_Link = link;
300 m_UseLink = (link.GetHref() != wxEmptyString);
301}
302
303
b250d384
VS
304void wxHtmlWinParser::SetFontFace(const wxString& face)
305{
306 if (GetFontFixed()) m_FontFaceFixed = face;
307 else m_FontFaceNormal = face;
308
309 if (m_InputEnc != wxFONTENCODING_DEFAULT)
310 SetInputEncoding(m_InputEnc);
311}
312
313
314
315void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
316{
317 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
318 if (m_EncConv) {delete m_EncConv; m_EncConv = NULL;}
319
320 if (enc == wxFONTENCODING_DEFAULT) return;
321
322 wxFontEncoding altfix, altnorm;
323 bool availfix, availnorm;
324
325 // exact match?
326 availnorm = wxTheFontMapper -> IsEncodingAvailable(enc, m_FontFaceNormal);
327 availfix = wxTheFontMapper -> IsEncodingAvailable(enc, m_FontFaceFixed);
328 if (availnorm && availfix)
329 m_OutputEnc = enc;
330
331 // alternatives?
332 else if (wxTheFontMapper -> GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE) &&
333 wxTheFontMapper -> GetAltForEncoding(enc, &altfix, m_FontFaceFixed, FALSE) &&
334 altnorm == altfix)
335 m_OutputEnc = altnorm;
336
337 // at least normal face?
338 else if (availnorm)
339 m_OutputEnc = enc;
340 else if (wxTheFontMapper -> GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE))
341 m_OutputEnc = altnorm;
342
343 // okay, let convert to ISO_8859-1, available always
344 else
345 m_OutputEnc = wxFONTENCODING_DEFAULT;
346
347 m_InputEnc = enc;
348
349 if (m_InputEnc == m_OutputEnc) return;
350
351 m_EncConv = new wxEncodingConverter();
352 if (!m_EncConv -> Init(m_InputEnc,
353 (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
354 wxFONTENCODING_ISO8859_1 : m_OutputEnc,
355 wxCONVERT_SUBSTITUTE))
356 { // total failture :-(
f3c82859
VS
357 wxLogError(_("Failed to display HTML document in %s encoding"),
358 wxFontMapper::GetEncodingName(enc).mb_str());
b250d384
VS
359 m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
360 delete m_EncConv;
361 m_EncConv = NULL;
362 }
363}
364
365
366
f2c2fa4d 367
5526e819
VS
368
369//-----------------------------------------------------------------------------
370// wxHtmlWinTagHandler
371//-----------------------------------------------------------------------------
372
373IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
374
375
376
377//-----------------------------------------------------------------------------
378// wxHtmlTagsModule
379//-----------------------------------------------------------------------------
380
381
382IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
383
384
385bool wxHtmlTagsModule::OnInit()
386{
387 wxHtmlWinParser::AddModule(this);
388 return TRUE;
389}
390
391
392
393void wxHtmlTagsModule::OnExit()
394{
395}
223d09f6 396#endif
5526e819 397