home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / html / winpars.cpp < prev   
C/C++ Source or Header  |  2002-07-01  |  14KB  |  474 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        winpars.cpp
  3. // Purpose:     wxHtmlParser class (generic parser)
  4. // Author:      Vaclav Slavik
  5. // RCS-ID:      $Id: winpars.cpp,v 1.35 2002/06/26 19:11:32 VS Exp $
  6. // Copyright:   (c) 1999 Vaclav Slavik
  7. // Licence:     wxWindows Licence
  8. /////////////////////////////////////////////////////////////////////////////
  9.  
  10.  
  11. #ifdef __GNUG__
  12. #pragma implementation "winpars.h"
  13. #endif
  14.  
  15. #include "wx/wxprec.h"
  16.  
  17. #include "wx/defs.h"
  18. #if wxUSE_HTML && wxUSE_STREAMS
  19.  
  20. #ifdef __BORDLANDC__
  21. #pragma hdrstop
  22. #endif
  23.  
  24. #ifndef WXPRECOMP
  25.     #include "wx/intl.h"
  26.     #include "wx/dc.h"
  27. #endif
  28.  
  29. #include "wx/html/htmldefs.h"
  30. #include "wx/html/winpars.h"
  31. #include "wx/html/htmlwin.h"
  32. #include "wx/fontmap.h"
  33. #include "wx/log.h"
  34.  
  35.  
  36. //-----------------------------------------------------------------------------
  37. // wxHtmlWinParser
  38. //-----------------------------------------------------------------------------
  39.  
  40.  
  41. wxList wxHtmlWinParser::m_Modules;
  42.  
  43. wxHtmlWinParser::wxHtmlWinParser(wxHtmlWindow *wnd) : wxHtmlParser()
  44. {
  45.     m_tmpStrBuf = NULL;
  46.     m_tmpStrBufSize = 0;
  47.     m_Window = wnd;
  48.     m_Container = NULL;
  49.     m_DC = NULL;
  50.     m_CharHeight = m_CharWidth = 0;
  51.     m_UseLink = FALSE;
  52.     m_EncConv = NULL;
  53.     m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
  54.  
  55.     {
  56.         int i, j, k, l, m;
  57.         for (i = 0; i < 2; i++)
  58.             for (j = 0; j < 2; j++)
  59.                 for (k = 0; k < 2; k++)
  60.                     for (l = 0; l < 2; l++)
  61.                         for (m = 0; m < 7; m++)
  62.                         {
  63.                             m_FontsTable[i][j][k][l][m] = NULL;
  64.                             m_FontsFacesTable[i][j][k][l][m] = wxEmptyString;
  65.                             m_FontsEncTable[i][j][k][l][m] = wxFONTENCODING_DEFAULT;
  66.                         }
  67. #ifdef __WXMSW__
  68.         static int default_sizes[7] = {7, 8, 10, 12, 16, 22, 30};
  69. #elif defined(__WXMAC__)
  70.         static int default_sizes[7] = {9, 12, 14, 18, 24, 30, 36};
  71. #else
  72.         static int default_sizes[7] = {10, 12, 14, 16, 19, 24, 32};
  73. #endif
  74.         SetFonts("", "", default_sizes);
  75.     }
  76.  
  77.     // fill in wxHtmlParser's tables:
  78.     wxNode *node = m_Modules.GetFirst();
  79.     while (node)
  80.     {
  81.         wxHtmlTagsModule *mod = (wxHtmlTagsModule*) node->GetData();
  82.         mod->FillHandlersTable(this);
  83.         node = node->GetNext();
  84.     }
  85. }
  86.  
  87. wxHtmlWinParser::~wxHtmlWinParser()
  88. {
  89.     int i, j, k, l, m;
  90.  
  91.     for (i = 0; i < 2; i++)
  92.         for (j = 0; j < 2; j++)
  93.             for (k = 0; k < 2; k++)
  94.                 for (l = 0; l < 2; l++)
  95.                     for (m = 0; m < 7; m++)
  96.                     {
  97.                         if (m_FontsTable[i][j][k][l][m] != NULL)
  98.                             delete m_FontsTable[i][j][k][l][m];
  99.                     }
  100.     delete m_EncConv;
  101.     delete[] m_tmpStrBuf;
  102. }
  103.  
  104. void wxHtmlWinParser::AddModule(wxHtmlTagsModule *module)
  105. {
  106.     m_Modules.Append(module);
  107. }
  108.  
  109. void wxHtmlWinParser::RemoveModule(wxHtmlTagsModule *module)
  110. {
  111.     m_Modules.DeleteObject(module);
  112. }
  113.  
  114. void wxHtmlWinParser::SetFonts(wxString normal_face, wxString fixed_face, const int *sizes)
  115. {
  116.     int i, j, k, l, m;
  117.  
  118.     for (i = 0; i < 7; i++) m_FontsSizes[i] = sizes[i];
  119.     m_FontFaceFixed = fixed_face;
  120.     m_FontFaceNormal = normal_face;
  121.  
  122.     SetInputEncoding(m_InputEnc);
  123.  
  124.     for (i = 0; i < 2; i++)
  125.         for (j = 0; j < 2; j++)
  126.             for (k = 0; k < 2; k++)
  127.                 for (l = 0; l < 2; l++)
  128.                     for (m = 0; m < 7; m++) {
  129.                         if (m_FontsTable[i][j][k][l][m] != NULL)
  130.                         {
  131.                             delete m_FontsTable[i][j][k][l][m];
  132.                             m_FontsTable[i][j][k][l][m] = NULL;
  133.                         }
  134.                     }
  135. }
  136.  
  137. void wxHtmlWinParser::InitParser(const wxString& source)
  138. {
  139.     wxHtmlParser::InitParser(source);
  140.     wxASSERT_MSG(m_DC != NULL, _T("no DC assigned to wxHtmlWinParser!!"));
  141.  
  142.     m_FontBold = m_FontItalic = m_FontUnderlined = m_FontFixed = FALSE;
  143.     m_FontSize = 3; //default one
  144.     CreateCurrentFont();           // we're selecting default font into
  145.     m_DC->GetTextExtent("H", &m_CharWidth, &m_CharHeight);
  146.                 /* NOTE : we're not using GetCharWidth/Height() because
  147.                    of differences under X and win
  148.                  */
  149.  
  150.     m_UseLink = FALSE;
  151.     m_Link = wxHtmlLinkInfo("", "");
  152.     m_LinkColor.Set(0, 0, 0xFF);
  153.     m_ActualColor.Set(0, 0, 0);
  154.     m_Align = wxHTML_ALIGN_LEFT;
  155.     m_tmpLastWasSpace = FALSE;
  156.  
  157.     OpenContainer();
  158.  
  159.     OpenContainer();
  160.     m_Container->InsertCell(new wxHtmlColourCell(m_ActualColor));
  161.     m_Container->InsertCell(new wxHtmlFontCell(CreateCurrentFont()));
  162. }
  163.  
  164. void wxHtmlWinParser::DoneParser()
  165. {
  166.     m_Container = NULL;
  167.     SetInputEncoding(wxFONTENCODING_DEFAULT); // for next call
  168.     wxHtmlParser::DoneParser();
  169. }
  170.  
  171. wxObject* wxHtmlWinParser::GetProduct()
  172. {
  173.     wxHtmlContainerCell *top;
  174.  
  175.     CloseContainer();
  176.     OpenContainer();
  177.  
  178.     top = m_Container;
  179.     while (top->GetParent()) top = top->GetParent();
  180.     return top;
  181. }
  182.  
  183. wxFSFile *wxHtmlWinParser::OpenURL(wxHtmlURLType type,
  184.                                    const wxString& url) const
  185. {
  186.     // FIXME - normalize the URL to full path before passing to
  187.     //         OnOpeningURL!!
  188.     if ( m_Window )
  189.     {
  190.         wxString myurl(url);
  191.         wxHtmlOpeningStatus status;
  192.         for (;;)
  193.         {
  194.             wxString redirect;
  195.             status = m_Window->OnOpeningURL(type, myurl, &redirect);
  196.             if ( status != wxHTML_REDIRECT )
  197.                 break;
  198.  
  199.             myurl = redirect;
  200.         }
  201.  
  202.         if ( status == wxHTML_BLOCK )
  203.             return NULL;
  204.  
  205.         return GetFS()->OpenFile(myurl);
  206.     }
  207.  
  208.     return wxHtmlParser::OpenURL(type, url);
  209. }
  210.  
  211. void wxHtmlWinParser::AddText(const wxChar* txt)
  212. {
  213.     wxHtmlCell *c;
  214.     size_t i = 0,
  215.            x,
  216.            lng = wxStrlen(txt);
  217.     register wxChar d;
  218.     int templen = 0;
  219.     wxChar nbsp = GetEntitiesParser()->GetCharForCode(160 /* nbsp */);
  220.  
  221.     if (lng+1 > m_tmpStrBufSize)
  222.     {
  223.         delete[] m_tmpStrBuf;
  224.         m_tmpStrBuf = new wxChar[lng+1];
  225.         m_tmpStrBufSize = lng+1;
  226.     }
  227.     wxChar *temp = m_tmpStrBuf;
  228.  
  229.     if (m_tmpLastWasSpace)
  230.     {
  231.         while ((i < lng) &&
  232.                ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) || (txt[i] == wxT(' ')) ||
  233.                 (txt[i] == wxT('\t')))) i++;
  234.     }
  235.  
  236.     while (i < lng)
  237.     {
  238.         x = 0;
  239.         d = temp[templen++] = txt[i];
  240.         if ((d == wxT('\n')) || (d == wxT('\r')) || (d == wxT(' ')) || (d == wxT('\t')))
  241.         {
  242.             i++, x++;
  243.             while ((i < lng) && ((txt[i] == wxT('\n')) || (txt[i] == wxT('\r')) ||
  244.                                  (txt[i] == wxT(' ')) || (txt[i] == wxT('\t')))) i++, x++;
  245.         }
  246.         else i++;
  247.  
  248.         if (x)
  249.         {
  250.             temp[templen-1] = wxT(' ');
  251.             temp[templen] = 0;
  252. #if 0 // VS - WHY was this here?!
  253.             if (templen == 1) continue;
  254. #endif
  255.             templen = 0;
  256.             if (m_EncConv)
  257.                 m_EncConv->Convert(temp);
  258.             size_t len = wxStrlen(temp);
  259.             for (size_t j = 0; j < len; j++)
  260.                 if (temp[j] == nbsp)
  261.                     temp[j] = wxT(' ');
  262.             c = new wxHtmlWordCell(temp, *(GetDC()));
  263.             if (m_UseLink)
  264.                 c->SetLink(m_Link);
  265.             m_Container->InsertCell(c);
  266.             m_tmpLastWasSpace = TRUE;
  267.         }
  268.     }
  269.  
  270.     if (templen && (templen > 1 || temp[0] != wxT(' ')))
  271.     {
  272.         temp[templen] = 0;
  273.         if (m_EncConv)
  274.             m_EncConv->Convert(temp);
  275.         size_t len = wxStrlen(temp);
  276.         for (size_t j = 0; j < len; j++)
  277.             if (temp[j] == nbsp)
  278.                 temp[j] = wxT(' ');
  279.         c = new wxHtmlWordCell(temp, *(GetDC()));
  280.         if (m_UseLink)
  281.             c->SetLink(m_Link);
  282.         m_Container->InsertCell(c);
  283.         m_tmpLastWasSpace = FALSE;
  284.     }
  285. }
  286.  
  287.  
  288.  
  289. wxHtmlContainerCell* wxHtmlWinParser::OpenContainer()
  290. {
  291.     m_Container = new wxHtmlContainerCell(m_Container);
  292.     m_Container->SetAlignHor(m_Align);
  293.     m_tmpLastWasSpace = TRUE;
  294.         /* to avoid space being first character in paragraph */
  295.     return m_Container;
  296. }
  297.  
  298.  
  299.  
  300. wxHtmlContainerCell* wxHtmlWinParser::SetContainer(wxHtmlContainerCell *c)
  301. {
  302.     m_tmpLastWasSpace = TRUE;
  303.         /* to avoid space being first character in paragraph */
  304.     return m_Container = c;
  305. }
  306.  
  307.  
  308.  
  309. wxHtmlContainerCell* wxHtmlWinParser::CloseContainer()
  310. {
  311.     m_Container = m_Container->GetParent();
  312.     return m_Container;
  313. }
  314.  
  315.  
  316. void wxHtmlWinParser::SetFontSize(int s)
  317. {
  318.     if (s < 1) s = 1;
  319.     else if (s > 7) s = 7;
  320.     m_FontSize = s;
  321. }
  322.  
  323.  
  324.  
  325. wxFont* wxHtmlWinParser::CreateCurrentFont()
  326. {
  327.     int fb = GetFontBold(),
  328.         fi = GetFontItalic(),
  329.         fu = GetFontUnderlined(),
  330.         ff = GetFontFixed(),
  331.         fs = GetFontSize() - 1 /*remap from <1;7> to <0;6>*/ ;
  332.  
  333.     wxString face = ff ? m_FontFaceFixed : m_FontFaceNormal;
  334.     wxString *faceptr = &(m_FontsFacesTable[fb][fi][fu][ff][fs]);
  335.     wxFont **fontptr = &(m_FontsTable[fb][fi][fu][ff][fs]);
  336.     wxFontEncoding *encptr = &(m_FontsEncTable[fb][fi][fu][ff][fs]);
  337.  
  338.     if (*fontptr != NULL && (*faceptr != face || *encptr != m_OutputEnc))
  339.     {
  340.         delete *fontptr;
  341.         *fontptr = NULL;
  342.     }
  343.  
  344.     if (*fontptr == NULL)
  345.     {
  346.         *faceptr = face;
  347.         *encptr = m_OutputEnc;
  348.         *fontptr = new wxFont(
  349.                        (int) (m_FontsSizes[fs] * m_PixelScale),
  350.                        ff ? wxMODERN : wxSWISS,
  351.                        fi ? wxITALIC : wxNORMAL,
  352.                        fb ? wxBOLD : wxNORMAL,
  353.                        fu ? TRUE : FALSE, face,
  354.                        m_OutputEnc);
  355.     }
  356.     m_DC->SetFont(**fontptr);
  357.     return (*fontptr);
  358. }
  359.  
  360.  
  361.  
  362. void wxHtmlWinParser::SetLink(const wxHtmlLinkInfo& link)
  363. {
  364.     m_Link = link;
  365.     m_UseLink = (link.GetHref() != wxEmptyString);
  366. }
  367.  
  368.  
  369. void wxHtmlWinParser::SetFontFace(const wxString& face)
  370. {
  371.     if (GetFontFixed()) m_FontFaceFixed = face;
  372.     else m_FontFaceNormal = face;
  373.  
  374.     if (m_InputEnc != wxFONTENCODING_DEFAULT)
  375.         SetInputEncoding(m_InputEnc);
  376. }
  377.  
  378.  
  379.  
  380. void wxHtmlWinParser::SetInputEncoding(wxFontEncoding enc)
  381. {
  382.     m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
  383.     if (m_EncConv)
  384.     {
  385.         delete m_EncConv;
  386.         m_EncConv = NULL;
  387.     }
  388.  
  389.     if (enc == wxFONTENCODING_DEFAULT) return;
  390.  
  391.     wxFontEncoding altfix, altnorm;
  392.     bool availfix, availnorm;
  393.  
  394.     // exact match?
  395.     availnorm = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceNormal);
  396.     availfix = wxFontMapper::Get()->IsEncodingAvailable(enc, m_FontFaceFixed);
  397.     if (availnorm && availfix)
  398.         m_OutputEnc = enc;
  399.  
  400.     // alternatives?
  401.     else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE) &&
  402.              wxFontMapper::Get()->GetAltForEncoding(enc, &altfix, m_FontFaceFixed, FALSE) &&
  403.              altnorm == altfix)
  404.         m_OutputEnc = altnorm;
  405.  
  406.     // at least normal face?
  407.     else if (availnorm)
  408.         m_OutputEnc = enc;
  409.     else if (wxFontMapper::Get()->GetAltForEncoding(enc, &altnorm, m_FontFaceNormal, FALSE))
  410.         m_OutputEnc = altnorm;
  411.  
  412.     // okay, let convert to ISO_8859-1, available always
  413.     else
  414.         m_OutputEnc = wxFONTENCODING_DEFAULT;
  415.  
  416.     m_InputEnc = enc;
  417.     if (m_OutputEnc == wxFONTENCODING_DEFAULT)
  418.         GetEntitiesParser()->SetEncoding(wxFONTENCODING_SYSTEM);
  419.     else
  420.         GetEntitiesParser()->SetEncoding(m_OutputEnc);
  421.  
  422.     if (m_InputEnc == m_OutputEnc) return;
  423.  
  424.     m_EncConv = new wxEncodingConverter();
  425.     if (!m_EncConv->Init(m_InputEnc,
  426.                            (m_OutputEnc == wxFONTENCODING_DEFAULT) ?
  427.                                       wxFONTENCODING_ISO8859_1 : m_OutputEnc,
  428.                            wxCONVERT_SUBSTITUTE))
  429.     { // total failture :-(
  430.         wxLogError(_("Failed to display HTML document in %s encoding"),
  431.                    wxFontMapper::GetEncodingName(enc).c_str());
  432.         m_InputEnc = m_OutputEnc = wxFONTENCODING_DEFAULT;
  433.         delete m_EncConv;
  434.         m_EncConv = NULL;
  435.     }
  436. }
  437.  
  438.  
  439.  
  440.  
  441.  
  442. //-----------------------------------------------------------------------------
  443. // wxHtmlWinTagHandler
  444. //-----------------------------------------------------------------------------
  445.  
  446. IMPLEMENT_ABSTRACT_CLASS(wxHtmlWinTagHandler, wxHtmlTagHandler)
  447.  
  448. //-----------------------------------------------------------------------------
  449. // wxHtmlTagsModule
  450. //-----------------------------------------------------------------------------
  451.  
  452. // NB: This is *NOT* winpars.cpp's initialization and shutdown code!!
  453. //     This module is an ancestor for tag handlers modules defined
  454. //     in m_*.cpp files with TAGS_MODULE_BEGIN...TAGS_MODULE_END construct.
  455. //
  456. //     Do not add any winpars.cpp shutdown or initialization code to it,
  457. //     create a new module instead!
  458.  
  459. IMPLEMENT_DYNAMIC_CLASS(wxHtmlTagsModule, wxModule)
  460.  
  461. bool wxHtmlTagsModule::OnInit()
  462. {
  463.     wxHtmlWinParser::AddModule(this);
  464.     return TRUE;
  465. }
  466.  
  467. void wxHtmlTagsModule::OnExit()
  468. {
  469.     wxHtmlWinParser::RemoveModule(this);
  470. }
  471.  
  472. #endif
  473.  
  474.