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