]> git.saurik.com Git - wxWidgets.git/blobdiff - src/html/m_pre.cpp
support underlined text in wxCairoContext (Marcin's patch) (closes #9846)
[wxWidgets.git] / src / html / m_pre.cpp
index f87983853ada3af0d784f7ff50efc79d371ef491..1a0ef36813be6f8df7a8f25c64c5aa332cc04cb9 100644 (file)
@@ -1,25 +1,21 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        m_pre.cpp
+// Name:        src/html/m_pre.cpp
 // Purpose:     wxHtml module for <PRE> ... </PRE> tag (code citation)
 // Author:      Vaclav Slavik
 // RCS-ID:      $Id$
 // Copyright:   (c) 1999 Vaclav Slavik
-// Licence:     wxWindows Licence
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation
-#endif
-
 #include "wx/wxprec.h"
 
-#include "wx/defs.h"
-#if wxUSE_HTML && wxUSE_STREAMS
-#ifdef __BORDLANDC__
-#pragma hdrstop
+#ifdef __BORLANDC__
+    #pragma hdrstop
 #endif
 
-#ifndef WXPRECOMP
+#if wxUSE_HTML && wxUSE_STREAMS
+
+#ifndef WX_PRECOMP
 #endif
 
 #include "wx/html/forcelnk.h"
 
 FORCE_LINK_ME(m_pre)
 
+// replaces '\t', ' ' and '\n' with HTML markup:
+static wxString LINKAGEMODE HtmlizeLinebreaks(const wxString& str)
+{
+    wxString out;
+    out.reserve(str.length()); // we'll certainly need at least that
+
+    const wxString::const_iterator end = str.end();
+    for ( wxString::const_iterator i = str.begin(); i != end; ++i )
+    {
+        switch ( (*i).GetValue() )
+        {
+            case '<':
+                while ( i != end && *i != '>' )
+                {
+                    out << *i++;
+                }
+                out << '>';
+                if ( i == end )
+                    return out;
+                break;
+
+            // We need to translate any line break into exactly one <br>.
+            // Quoting HTML spec: "A line break is defined to be a carriage
+            // return (&#x000D;), a line feed (&#x000A;), or a carriage
+            // return/line feed pair."
+            case '\r':
+                {
+                    wxString::const_iterator j(i + 1);
+                    if ( j != end && *j == '\n' )
+                        i = j;
+                }
+                // fall through
+            case '\n':
+                out << "<br>";
+                break;
+
+            default:
+                out << *i;
+                break;
+        }
+    }
+
+    return out;
+}
+
+
 //-----------------------------------------------------------------------------
 // The list handler:
 //-----------------------------------------------------------------------------
 
 
 TAG_HANDLER_BEGIN(PRE, "PRE")
+    TAG_HANDLER_CONSTR(PRE) { }
 
     TAG_HANDLER_PROC(tag)
     {
         wxHtmlContainerCell *c;
 
-        int fixed = m_WParser->GetFontFixed(),
-            italic = m_WParser->GetFontItalic(),
-            underlined = m_WParser->GetFontUnderlined(),
-            bold = m_WParser->GetFontBold(),
-            fsize = m_WParser->GetFontSize();
+        const int fixed = m_WParser->GetFontFixed();
+        const int italic = m_WParser->GetFontItalic();
+        const int underlined = m_WParser->GetFontUnderlined();
+        const int bold = m_WParser->GetFontBold();
+        const int fsize = m_WParser->GetFontSize();
+        const wxHtmlWinParser::WhitespaceMode whitespace =
+            m_WParser->GetWhitespaceMode();
 
         c = m_WParser->GetContainer();
-        m_WParser->SetFontUnderlined(FALSE);
-        m_WParser->SetFontBold(FALSE);
-        m_WParser->SetFontItalic(FALSE);
-        m_WParser->SetFontFixed(TRUE);
+        m_WParser->SetWhitespaceMode(wxHtmlWinParser::Whitespace_Pre);
+        m_WParser->SetFontUnderlined(false);
+        m_WParser->SetFontBold(false);
+        m_WParser->SetFontItalic(false);
+        m_WParser->SetFontFixed(true);
         m_WParser->SetFontSize(3);
         c->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
 
         m_WParser->CloseContainer();
         c = m_WParser->OpenContainer();
+        c->SetWidthFloat(tag);
+        c = m_WParser->OpenContainer();
         c->SetAlignHor(wxHTML_ALIGN_LEFT);
+        c->SetIndent(m_WParser->GetCharHeight(), wxHTML_INDENT_TOP);
 
-        wxString src, srcMid;
-
-        src = *m_WParser->GetSource();
-        srcMid = src.Mid(tag.GetBeginPos(),
-                         tag.GetEndPos1() - tag.GetBeginPos());
-        srcMid.Replace(wxT("\t"), wxT("        "));
-        srcMid.Replace(wxT(" "), wxT("&nbsp;"));
-        srcMid.Replace(wxT("\n"), wxT("<br>"));
+        wxString srcMid = m_WParser->GetInnerSource(tag);
 
-        // It is safe to temporarily change the source being parsed,
-        // provided we restore the state back after parsing
-        m_Parser->SetSource(srcMid);
-        m_Parser->DoParsing();
-        m_Parser->SetSource(src);
+        // setting Whitespace_Pre mode takes care of spaces and TABs, but
+        // not linebreaks, so we have to translate them into <br> by
+        // calling HtmlizeLinebreaks() here
+        ParseInnerSource(HtmlizeLinebreaks(srcMid));
 
+        m_WParser->CloseContainer();
         m_WParser->CloseContainer();
         c = m_WParser->OpenContainer();
 
+        m_WParser->SetWhitespaceMode(whitespace);
         m_WParser->SetFontUnderlined(underlined);
         m_WParser->SetFontBold(bold);
         m_WParser->SetFontItalic(italic);
@@ -85,7 +128,7 @@ TAG_HANDLER_BEGIN(PRE, "PRE")
         m_WParser->SetFontSize(fsize);
         c->InsertCell(new wxHtmlFontCell(m_WParser->CreateCurrentFont()));
 
-        return TRUE;
+        return true;
     }
 
 TAG_HANDLER_END(PRE)