From c27126c7bca4ff702f6a185bb2cfba303ae20a62 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 27 Feb 2011 12:48:21 +0000 Subject: [PATCH] Add generic wxMarkupText class implementing handling of markup. wxMarkupText is a private class that implements generic handling of markup strings, i.e. can measure them and render them onto a wxDC. This class will be used for markup support in wxMSW wxButton. Also add wxMarkupParserAttrOutput which will be useful for other wxMarkupText implementations. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67064 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 20 ++ build/bakefiles/files.bkl | 1 + build/msw/makefile.bcc | 28 +++ build/msw/makefile.gcc | 28 +++ build/msw/makefile.vc | 28 +++ build/msw/makefile.wat | 28 +++ build/msw/wx_core.dsp | 4 + build/msw/wx_vc7_core.vcproj | 3 + build/msw/wx_vc8_core.vcproj | 4 + build/msw/wx_vc9_core.vcproj | 4 + include/wx/generic/private/markuptext.h | 78 ++++++++ include/wx/private/markupparser.h | 4 + include/wx/private/markupparserattr.h | 222 +++++++++++++++++++++ src/generic/markuptext.cpp | 253 ++++++++++++++++++++++++ 14 files changed, 705 insertions(+) create mode 100644 include/wx/generic/private/markuptext.h create mode 100644 include/wx/private/markupparserattr.h create mode 100644 src/generic/markuptext.cpp diff --git a/Makefile.in b/Makefile.in index 82cd930de3..9c1aef16f3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4612,6 +4612,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS = \ monodll_generic_infobar.o \ monodll_listbkg.o \ monodll_logg.o \ + monodll_markuptext.o \ monodll_msgdlgg.o \ monodll_numdlgg.o \ monodll_panelg.o \ @@ -4827,6 +4828,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS = \ monodll_generic_infobar.o \ monodll_listbkg.o \ monodll_logg.o \ + monodll_markuptext.o \ monodll_msgdlgg.o \ monodll_numdlgg.o \ monodll_panelg.o \ @@ -6528,6 +6530,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_1 = \ monolib_generic_infobar.o \ monolib_listbkg.o \ monolib_logg.o \ + monolib_markuptext.o \ monolib_msgdlgg.o \ monolib_numdlgg.o \ monolib_panelg.o \ @@ -6743,6 +6746,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_1 = \ monolib_generic_infobar.o \ monolib_listbkg.o \ monolib_logg.o \ + monolib_markuptext.o \ monolib_msgdlgg.o \ monolib_numdlgg.o \ monolib_panelg.o \ @@ -8628,6 +8632,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_2 = \ coredll_generic_infobar.o \ coredll_listbkg.o \ coredll_logg.o \ + coredll_markuptext.o \ coredll_msgdlgg.o \ coredll_numdlgg.o \ coredll_panelg.o \ @@ -8843,6 +8848,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_2 = \ coredll_generic_infobar.o \ coredll_listbkg.o \ coredll_logg.o \ + coredll_markuptext.o \ coredll_msgdlgg.o \ coredll_numdlgg.o \ coredll_panelg.o \ @@ -10206,6 +10212,7 @@ COND_USE_GUI_1_WXUNIV_0___CORE_SRC_OBJECTS_3 = \ corelib_generic_infobar.o \ corelib_listbkg.o \ corelib_logg.o \ + corelib_markuptext.o \ corelib_msgdlgg.o \ corelib_numdlgg.o \ corelib_panelg.o \ @@ -10421,6 +10428,7 @@ COND_USE_GUI_1_WXUNIV_1___CORE_SRC_OBJECTS_3 = \ corelib_generic_infobar.o \ corelib_listbkg.o \ corelib_logg.o \ + corelib_markuptext.o \ corelib_msgdlgg.o \ corelib_numdlgg.o \ corelib_panelg.o \ @@ -20141,6 +20149,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@monodll_logg.o: $(srcdir)/src/generic/logg.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/logg.cpp +@COND_USE_GUI_1@monodll_markuptext.o: $(srcdir)/src/generic/markuptext.cpp $(MONODLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/markuptext.cpp + @COND_USE_GUI_1@monodll_msgdlgg.o: $(srcdir)/src/generic/msgdlgg.cpp $(MONODLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/msgdlgg.cpp @@ -25427,6 +25438,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@monolib_logg.o: $(srcdir)/src/generic/logg.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/logg.cpp +@COND_USE_GUI_1@monolib_markuptext.o: $(srcdir)/src/generic/markuptext.cpp $(MONOLIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/markuptext.cpp + @COND_USE_GUI_1@monolib_msgdlgg.o: $(srcdir)/src/generic/msgdlgg.cpp $(MONOLIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/msgdlgg.cpp @@ -30893,6 +30907,9 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@coredll_logg.o: $(srcdir)/src/generic/logg.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/logg.cpp +@COND_USE_GUI_1@coredll_markuptext.o: $(srcdir)/src/generic/markuptext.cpp $(COREDLL_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/markuptext.cpp + @COND_USE_GUI_1@coredll_msgdlgg.o: $(srcdir)/src/generic/msgdlgg.cpp $(COREDLL_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/msgdlgg.cpp @@ -34862,6 +34879,9 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@corelib_logg.o: $(srcdir)/src/generic/logg.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/logg.cpp +@COND_USE_GUI_1@corelib_markuptext.o: $(srcdir)/src/generic/markuptext.cpp $(CORELIB_ODEP) +@COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/markuptext.cpp + @COND_USE_GUI_1@corelib_msgdlgg.o: $(srcdir)/src/generic/msgdlgg.cpp $(CORELIB_ODEP) @COND_USE_GUI_1@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/msgdlgg.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 041a497f3b..1d6c020d17 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -785,6 +785,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/infobar.cpp src/generic/listbkg.cpp src/generic/logg.cpp + src/generic/markuptext.cpp src/generic/msgdlgg.cpp src/generic/numdlgg.cpp src/generic/panelg.cpp diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index 5b4b295f0c..c0249b8827 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -1924,6 +1924,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_infobar.obj \ $(OBJS)\monodll_listbkg.obj \ $(OBJS)\monodll_logg.obj \ + $(OBJS)\monodll_markuptext.obj \ $(OBJS)\monodll_msgdlgg.obj \ $(OBJS)\monodll_numdlgg.obj \ $(OBJS)\monodll_panelg.obj \ @@ -2188,6 +2189,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_infobar.obj \ $(OBJS)\monodll_listbkg.obj \ $(OBJS)\monodll_logg.obj \ + $(OBJS)\monodll_markuptext.obj \ $(OBJS)\monodll_msgdlgg.obj \ $(OBJS)\monodll_numdlgg.obj \ $(OBJS)\monodll_panelg.obj \ @@ -2683,6 +2685,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_infobar.obj \ $(OBJS)\monolib_listbkg.obj \ $(OBJS)\monolib_logg.obj \ + $(OBJS)\monolib_markuptext.obj \ $(OBJS)\monolib_msgdlgg.obj \ $(OBJS)\monolib_numdlgg.obj \ $(OBJS)\monolib_panelg.obj \ @@ -2947,6 +2950,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_infobar.obj \ $(OBJS)\monolib_listbkg.obj \ $(OBJS)\monolib_logg.obj \ + $(OBJS)\monolib_markuptext.obj \ $(OBJS)\monolib_msgdlgg.obj \ $(OBJS)\monolib_numdlgg.obj \ $(OBJS)\monolib_panelg.obj \ @@ -3330,6 +3334,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_infobar.obj \ $(OBJS)\coredll_listbkg.obj \ $(OBJS)\coredll_logg.obj \ + $(OBJS)\coredll_markuptext.obj \ $(OBJS)\coredll_msgdlgg.obj \ $(OBJS)\coredll_numdlgg.obj \ $(OBJS)\coredll_panelg.obj \ @@ -3594,6 +3599,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_infobar.obj \ $(OBJS)\coredll_listbkg.obj \ $(OBJS)\coredll_logg.obj \ + $(OBJS)\coredll_markuptext.obj \ $(OBJS)\coredll_msgdlgg.obj \ $(OBJS)\coredll_numdlgg.obj \ $(OBJS)\coredll_panelg.obj \ @@ -3866,6 +3872,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_infobar.obj \ $(OBJS)\corelib_listbkg.obj \ $(OBJS)\corelib_logg.obj \ + $(OBJS)\corelib_markuptext.obj \ $(OBJS)\corelib_msgdlgg.obj \ $(OBJS)\corelib_numdlgg.obj \ $(OBJS)\corelib_panelg.obj \ @@ -4130,6 +4137,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_infobar.obj \ $(OBJS)\corelib_listbkg.obj \ $(OBJS)\corelib_logg.obj \ + $(OBJS)\corelib_markuptext.obj \ $(OBJS)\corelib_msgdlgg.obj \ $(OBJS)\corelib_numdlgg.obj \ $(OBJS)\corelib_panelg.obj \ @@ -7933,6 +7941,11 @@ $(OBJS)\monodll_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\monodll_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\monodll_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif @@ -10270,6 +10283,11 @@ $(OBJS)\monolib_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\monolib_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\monolib_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif @@ -12601,6 +12619,11 @@ $(OBJS)\coredll_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\coredll_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\coredll_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif @@ -13993,6 +14016,11 @@ $(OBJS)\corelib_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\corelib_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\corelib_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 789e3105d7..90a939b6ac 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1935,6 +1935,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_infobar.o \ $(OBJS)\monodll_listbkg.o \ $(OBJS)\monodll_logg.o \ + $(OBJS)\monodll_markuptext.o \ $(OBJS)\monodll_msgdlgg.o \ $(OBJS)\monodll_numdlgg.o \ $(OBJS)\monodll_panelg.o \ @@ -2201,6 +2202,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_infobar.o \ $(OBJS)\monodll_listbkg.o \ $(OBJS)\monodll_logg.o \ + $(OBJS)\monodll_markuptext.o \ $(OBJS)\monodll_msgdlgg.o \ $(OBJS)\monodll_numdlgg.o \ $(OBJS)\monodll_panelg.o \ @@ -2700,6 +2702,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_infobar.o \ $(OBJS)\monolib_listbkg.o \ $(OBJS)\monolib_logg.o \ + $(OBJS)\monolib_markuptext.o \ $(OBJS)\monolib_msgdlgg.o \ $(OBJS)\monolib_numdlgg.o \ $(OBJS)\monolib_panelg.o \ @@ -2966,6 +2969,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_infobar.o \ $(OBJS)\monolib_listbkg.o \ $(OBJS)\monolib_logg.o \ + $(OBJS)\monolib_markuptext.o \ $(OBJS)\monolib_msgdlgg.o \ $(OBJS)\monolib_numdlgg.o \ $(OBJS)\monolib_panelg.o \ @@ -3363,6 +3367,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_infobar.o \ $(OBJS)\coredll_listbkg.o \ $(OBJS)\coredll_logg.o \ + $(OBJS)\coredll_markuptext.o \ $(OBJS)\coredll_msgdlgg.o \ $(OBJS)\coredll_numdlgg.o \ $(OBJS)\coredll_panelg.o \ @@ -3629,6 +3634,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_infobar.o \ $(OBJS)\coredll_listbkg.o \ $(OBJS)\coredll_logg.o \ + $(OBJS)\coredll_markuptext.o \ $(OBJS)\coredll_msgdlgg.o \ $(OBJS)\coredll_numdlgg.o \ $(OBJS)\coredll_panelg.o \ @@ -3907,6 +3913,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_infobar.o \ $(OBJS)\corelib_listbkg.o \ $(OBJS)\corelib_logg.o \ + $(OBJS)\corelib_markuptext.o \ $(OBJS)\corelib_msgdlgg.o \ $(OBJS)\corelib_numdlgg.o \ $(OBJS)\corelib_panelg.o \ @@ -4173,6 +4180,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_infobar.o \ $(OBJS)\corelib_listbkg.o \ $(OBJS)\corelib_logg.o \ + $(OBJS)\corelib_markuptext.o \ $(OBJS)\corelib_msgdlgg.o \ $(OBJS)\corelib_numdlgg.o \ $(OBJS)\corelib_panelg.o \ @@ -8083,6 +8091,11 @@ $(OBJS)\monodll_logg.o: ../../src/generic/logg.cpp endif ifeq ($(USE_GUI),1) +$(OBJS)\monodll_markuptext.o: ../../src/generic/markuptext.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +endif + +ifeq ($(USE_GUI),1) $(OBJS)\monodll_msgdlgg.o: ../../src/generic/msgdlgg.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< endif @@ -10420,6 +10433,11 @@ $(OBJS)\monolib_logg.o: ../../src/generic/logg.cpp endif ifeq ($(USE_GUI),1) +$(OBJS)\monolib_markuptext.o: ../../src/generic/markuptext.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +endif + +ifeq ($(USE_GUI),1) $(OBJS)\monolib_msgdlgg.o: ../../src/generic/msgdlgg.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< endif @@ -12751,6 +12769,11 @@ $(OBJS)\coredll_logg.o: ../../src/generic/logg.cpp endif ifeq ($(USE_GUI),1) +$(OBJS)\coredll_markuptext.o: ../../src/generic/markuptext.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +endif + +ifeq ($(USE_GUI),1) $(OBJS)\coredll_msgdlgg.o: ../../src/generic/msgdlgg.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< endif @@ -14143,6 +14166,11 @@ $(OBJS)\corelib_logg.o: ../../src/generic/logg.cpp endif ifeq ($(USE_GUI),1) +$(OBJS)\corelib_markuptext.o: ../../src/generic/markuptext.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +endif + +ifeq ($(USE_GUI),1) $(OBJS)\corelib_msgdlgg.o: ../../src/generic/msgdlgg.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< endif diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 888543651a..4d6f1e7e99 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -2132,6 +2132,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_infobar.obj \ $(OBJS)\monodll_listbkg.obj \ $(OBJS)\monodll_logg.obj \ + $(OBJS)\monodll_markuptext.obj \ $(OBJS)\monodll_msgdlgg.obj \ $(OBJS)\monodll_numdlgg.obj \ $(OBJS)\monodll_panelg.obj \ @@ -2396,6 +2397,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_infobar.obj \ $(OBJS)\monodll_listbkg.obj \ $(OBJS)\monodll_logg.obj \ + $(OBJS)\monodll_markuptext.obj \ $(OBJS)\monodll_msgdlgg.obj \ $(OBJS)\monodll_numdlgg.obj \ $(OBJS)\monodll_panelg.obj \ @@ -2897,6 +2899,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_infobar.obj \ $(OBJS)\monolib_listbkg.obj \ $(OBJS)\monolib_logg.obj \ + $(OBJS)\monolib_markuptext.obj \ $(OBJS)\monolib_msgdlgg.obj \ $(OBJS)\monolib_numdlgg.obj \ $(OBJS)\monolib_panelg.obj \ @@ -3161,6 +3164,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_infobar.obj \ $(OBJS)\monolib_listbkg.obj \ $(OBJS)\monolib_logg.obj \ + $(OBJS)\monolib_markuptext.obj \ $(OBJS)\monolib_msgdlgg.obj \ $(OBJS)\monolib_numdlgg.obj \ $(OBJS)\monolib_panelg.obj \ @@ -3610,6 +3614,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_infobar.obj \ $(OBJS)\coredll_listbkg.obj \ $(OBJS)\coredll_logg.obj \ + $(OBJS)\coredll_markuptext.obj \ $(OBJS)\coredll_msgdlgg.obj \ $(OBJS)\coredll_numdlgg.obj \ $(OBJS)\coredll_panelg.obj \ @@ -3874,6 +3879,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_infobar.obj \ $(OBJS)\coredll_listbkg.obj \ $(OBJS)\coredll_logg.obj \ + $(OBJS)\coredll_markuptext.obj \ $(OBJS)\coredll_msgdlgg.obj \ $(OBJS)\coredll_numdlgg.obj \ $(OBJS)\coredll_panelg.obj \ @@ -4152,6 +4158,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_infobar.obj \ $(OBJS)\corelib_listbkg.obj \ $(OBJS)\corelib_logg.obj \ + $(OBJS)\corelib_markuptext.obj \ $(OBJS)\corelib_msgdlgg.obj \ $(OBJS)\corelib_numdlgg.obj \ $(OBJS)\corelib_panelg.obj \ @@ -4416,6 +4423,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_infobar.obj \ $(OBJS)\corelib_listbkg.obj \ $(OBJS)\corelib_logg.obj \ + $(OBJS)\corelib_markuptext.obj \ $(OBJS)\corelib_msgdlgg.obj \ $(OBJS)\corelib_numdlgg.obj \ $(OBJS)\corelib_panelg.obj \ @@ -8513,6 +8521,11 @@ $(OBJS)\monodll_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\monodll_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\monodll_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif @@ -10850,6 +10863,11 @@ $(OBJS)\monolib_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\monolib_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\monolib_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif @@ -13181,6 +13199,11 @@ $(OBJS)\coredll_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\coredll_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\coredll_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif @@ -14573,6 +14596,11 @@ $(OBJS)\corelib_logg.obj: ..\..\src\generic\logg.cpp !endif !if "$(USE_GUI)" == "1" +$(OBJS)\corelib_markuptext.obj: ..\..\src\generic\markuptext.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\markuptext.cpp +!endif + +!if "$(USE_GUI)" == "1" $(OBJS)\corelib_msgdlgg.obj: ..\..\src\generic\msgdlgg.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\generic\msgdlgg.cpp !endif diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index 0f9c1c8c8a..cb5d9c2d50 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -486,6 +486,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_infobar.obj & $(OBJS)\monodll_listbkg.obj & $(OBJS)\monodll_logg.obj & + $(OBJS)\monodll_markuptext.obj & $(OBJS)\monodll_msgdlgg.obj & $(OBJS)\monodll_numdlgg.obj & $(OBJS)\monodll_panelg.obj & @@ -752,6 +753,7 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_infobar.obj & $(OBJS)\monodll_listbkg.obj & $(OBJS)\monodll_logg.obj & + $(OBJS)\monodll_markuptext.obj & $(OBJS)\monodll_msgdlgg.obj & $(OBJS)\monodll_numdlgg.obj & $(OBJS)\monodll_panelg.obj & @@ -1256,6 +1258,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_infobar.obj & $(OBJS)\monolib_listbkg.obj & $(OBJS)\monolib_logg.obj & + $(OBJS)\monolib_markuptext.obj & $(OBJS)\monolib_msgdlgg.obj & $(OBJS)\monolib_numdlgg.obj & $(OBJS)\monolib_panelg.obj & @@ -1522,6 +1525,7 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_infobar.obj & $(OBJS)\monolib_listbkg.obj & $(OBJS)\monolib_logg.obj & + $(OBJS)\monolib_markuptext.obj & $(OBJS)\monolib_msgdlgg.obj & $(OBJS)\monolib_numdlgg.obj & $(OBJS)\monolib_panelg.obj & @@ -1930,6 +1934,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_infobar.obj & $(OBJS)\coredll_listbkg.obj & $(OBJS)\coredll_logg.obj & + $(OBJS)\coredll_markuptext.obj & $(OBJS)\coredll_msgdlgg.obj & $(OBJS)\coredll_numdlgg.obj & $(OBJS)\coredll_panelg.obj & @@ -2196,6 +2201,7 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_infobar.obj & $(OBJS)\coredll_listbkg.obj & $(OBJS)\coredll_logg.obj & + $(OBJS)\coredll_markuptext.obj & $(OBJS)\coredll_msgdlgg.obj & $(OBJS)\coredll_numdlgg.obj & $(OBJS)\coredll_panelg.obj & @@ -2476,6 +2482,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_infobar.obj & $(OBJS)\corelib_listbkg.obj & $(OBJS)\corelib_logg.obj & + $(OBJS)\corelib_markuptext.obj & $(OBJS)\corelib_msgdlgg.obj & $(OBJS)\corelib_numdlgg.obj & $(OBJS)\corelib_panelg.obj & @@ -2742,6 +2749,7 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_infobar.obj & $(OBJS)\corelib_listbkg.obj & $(OBJS)\corelib_logg.obj & + $(OBJS)\corelib_markuptext.obj & $(OBJS)\corelib_msgdlgg.obj & $(OBJS)\corelib_numdlgg.obj & $(OBJS)\corelib_panelg.obj & @@ -8342,6 +8350,11 @@ $(OBJS)\monodll_logg.obj : .AUTODEPEND ..\..\src\generic\logg.cpp !endif !ifeq USE_GUI 1 +$(OBJS)\monodll_markuptext.obj : .AUTODEPEND ..\..\src\generic\markuptext.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +!endif + +!ifeq USE_GUI 1 $(OBJS)\monodll_msgdlgg.obj : .AUTODEPEND ..\..\src\generic\msgdlgg.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< !endif @@ -10679,6 +10692,11 @@ $(OBJS)\monolib_logg.obj : .AUTODEPEND ..\..\src\generic\logg.cpp !endif !ifeq USE_GUI 1 +$(OBJS)\monolib_markuptext.obj : .AUTODEPEND ..\..\src\generic\markuptext.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +!endif + +!ifeq USE_GUI 1 $(OBJS)\monolib_msgdlgg.obj : .AUTODEPEND ..\..\src\generic\msgdlgg.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< !endif @@ -13010,6 +13028,11 @@ $(OBJS)\coredll_logg.obj : .AUTODEPEND ..\..\src\generic\logg.cpp !endif !ifeq USE_GUI 1 +$(OBJS)\coredll_markuptext.obj : .AUTODEPEND ..\..\src\generic\markuptext.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< +!endif + +!ifeq USE_GUI 1 $(OBJS)\coredll_msgdlgg.obj : .AUTODEPEND ..\..\src\generic\msgdlgg.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< !endif @@ -14402,6 +14425,11 @@ $(OBJS)\corelib_logg.obj : .AUTODEPEND ..\..\src\generic\logg.cpp !endif !ifeq USE_GUI 1 +$(OBJS)\corelib_markuptext.obj : .AUTODEPEND ..\..\src\generic\markuptext.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< +!endif + +!ifeq USE_GUI 1 $(OBJS)\corelib_msgdlgg.obj : .AUTODEPEND ..\..\src\generic\msgdlgg.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< !endif diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index ed7f043b32..ac645061b9 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -3119,6 +3119,10 @@ SOURCE=..\..\src\generic\logg.cpp # End Source File # Begin Source File +SOURCE=..\..\src\generic\markuptext.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\generic\mdig.cpp !IF "$(CFG)" == "core - Win32 DLL Universal Release" diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index cfed66795e..e246c2db20 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -2790,6 +2790,9 @@ RelativePath="..\..\src\generic\logg.cpp"> + + + + + + +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_GENERIC_PRIVATE_MARKUPTEXT_H_ +#define _WX_GENERIC_PRIVATE_MARKUPTEXT_H_ + +#include "wx/defs.h" + +class WXDLLIMPEXP_FWD_CORE wxDC; +class WXDLLIMPEXP_FWD_CORE wxRect; + +// ---------------------------------------------------------------------------- +// wxMarkupText: allows to measure and draw the text containing markup. +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxMarkupText +{ +public: + // Constants for Render() flags. + enum + { + Render_Default = 0, // Don't show mnemonics visually. + Render_ShowAccels = 1 // Underline mnemonics. + }; + + + // Initialize with the given string containing markup (which is supposed to + // be valid, the caller must check for it before constructing this object). + // + // Notice that the usual rules for mnemonics apply to the markup text: if + // it contains any '&' characters they must be escaped by doubling them, + // otherwise they indicate that the next character is the mnemonic for this + // field. + // + // TODO-MULTILINE-MARKUP: Currently only single line labels are supported, + // search for other occurrences of this comment to find the places which + // need to be updated to support multiline labels with markup. + wxMarkupText(const wxString& markup) + : m_markup(markup) + { + } + + // Default copy ctor, assignment operator and dtor are ok. + + // Update the markup string. + // + // The same rules for mnemonics as in the ctor apply to this string. + void SetMarkup(const wxString& markup) { m_markup = markup; } + + + // Return the width and height required by the given string and optionally + // the height of the visible part above the baseline (i.e. ascent minus + // internal leading). + // + // The font currently selected into the DC is used for measuring (notice + // that it is changed by this function but normally -- i.e. if markup is + // valid -- restored to its original value when it returns). + wxSize Measure(wxDC& dc, int *visibleHeight = NULL) const; + + // Render the markup string into the given DC in the specified rectangle. + // + // Notice that while the function uses the provided rectangle for alignment + // (it centers the text in it), no clipping is done by it so use Measure() + // and set the clipping region before rendering if necessary. + void Render(wxDC& dc, const wxRect& rect, int flags); + +private: + wxString m_markup; +}; + +#endif // _WX_GENERIC_PRIVATE_MARKUPTEXT_H_ diff --git a/include/wx/private/markupparser.h b/include/wx/private/markupparser.h index 400cbe9d3c..751c9d67f7 100644 --- a/include/wx/private/markupparser.h +++ b/include/wx/private/markupparser.h @@ -70,6 +70,10 @@ struct wxMarkupSpanAttributes // wxMarkupParserOutput: gathers the results of parsing markup. // ---------------------------------------------------------------------------- +// A class deriving directly from this one needs to implement all the pure +// virtual functions below but as the handling of all simple tags (bold, italic +// &c) is often very similar, it is usually more convenient to inherit from +// wxMarkupParserFontOutput defined in wx/private/markupparserfont.h instead. class wxMarkupParserOutput { public: diff --git a/include/wx/private/markupparserattr.h b/include/wx/private/markupparserattr.h new file mode 100644 index 0000000000..8f078efb7d --- /dev/null +++ b/include/wx/private/markupparserattr.h @@ -0,0 +1,222 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/private/markupparserattr.h +// Purpose: Classes mapping markup attributes to wxFont/wxColour. +// Author: Vadim Zeitlin +// Created: 2011-02-18 +// RCS-ID: $Id: wxhead.h,v 1.12 2010-04-22 12:44:51 zeitlin Exp $ +// Copyright: (c) 2011 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_MARKUPPARSERATTR_H_ +#define _WX_PRIVATE_MARKUPPARSERATTR_H_ + +#include "wx/private/markupparser.h" + +#include "wx/stack.h" + +#include "wx/colour.h" +#include "wx/font.h" + +// ---------------------------------------------------------------------------- +// wxMarkupParserAttrOutput: simplified wxFont-using version of the above. +// ---------------------------------------------------------------------------- + +// This class assumes that wxFont and wxColour are used to perform all the +// markup tags and implements the base class virtual functions in terms of +// OnAttr{Start,End}() only. +// +// Notice that you still must implement OnText() inherited from the base class +// when deriving from this one. +class wxMarkupParserAttrOutput : public wxMarkupParserOutput +{ +public: + // A simple container of font and colours. + struct Attr + { + Attr(const wxFont& font_, + const wxColour& foreground_ = wxColour(), + const wxColour& background_ = wxColour()) + : font(font_), foreground(foreground_), background(background_) + { + } + + wxFont font; + wxColour foreground, + background; + }; + + + // This object must be initialized with the font and colours to use + // initially, i.e. the ones used before any tags in the string. + wxMarkupParserAttrOutput(const wxFont& font, + const wxColour& foreground, + const wxColour& background) + { + m_attrs.push(Attr(font, foreground, background)); + } + + // Indicates the change of the font and/or colours used. Any of the + // fields of the argument may be invalid indicating that the corresponding + // attribute didn't actually change. + virtual void OnAttrStart(const Attr& attr) = 0; + + // Indicates the end of the region affected by the given attributes + // (the same ones that were passed to the matching OnAttrStart(), use + // GetAttr() to get the ones that will be used from now on). + virtual void OnAttrEnd(const Attr& attr) = 0; + + + // Implement all pure virtual methods inherited from the base class in + // terms of our own ones. + virtual void OnBoldStart() { DoChangeFont(&wxFont::Bold); } + virtual void OnBoldEnd() { DoEndAttr(); } + + virtual void OnItalicStart() { DoChangeFont(&wxFont::Italic); } + virtual void OnItalicEnd() { DoEndAttr(); } + + virtual void OnUnderlinedStart() { DoChangeFont(&wxFont::Underlined); } + virtual void OnUnderlinedEnd() { DoEndAttr(); } + + virtual void OnStrikethroughStart() { } // TODO: No support in wxFont yet. + virtual void OnStrikethroughEnd() { } + + virtual void OnBigStart() { DoChangeFont(&wxFont::Larger); } + virtual void OnBigEnd() { DoEndAttr(); } + + virtual void OnSmallStart() { DoChangeFont(&wxFont::Smaller); } + virtual void OnSmallEnd() { DoEndAttr(); } + + virtual void OnTeletypeStart() + { + wxFont font(GetFont()); + font.SetFamily(wxFONTFAMILY_TELETYPE); + DoSetFont(font); + } + virtual void OnTeletypeEnd() { DoEndAttr(); } + + virtual void OnSpanStart(const wxMarkupSpanAttributes& spanAttr) + { + wxFont font(GetFont()); + if ( !spanAttr.m_fontFace.empty() ) + font.SetFaceName(spanAttr.m_fontFace); + + DoApplyToFont(spanAttr.m_isBold, font, &wxFont::SetWeight, + wxFONTWEIGHT_NORMAL, wxFONTWEIGHT_BOLD); + + DoApplyToFont(spanAttr.m_isItalic, font, &wxFont::SetStyle, + wxFONTSTYLE_NORMAL, wxFONTSTYLE_ITALIC); + + DoApplyToFont(spanAttr.m_isUnderlined, font, &wxFont::SetUnderlined, + false, true); + + // TODO: No support for strike-through yet. + + switch ( spanAttr.m_sizeKind ) + { + case wxMarkupSpanAttributes::Size_Unspecified: + break; + + case wxMarkupSpanAttributes::Size_Relative: + if ( spanAttr.m_fontSize > 0 ) + font.MakeLarger(); + else + font.MakeSmaller(); + break; + + case wxMarkupSpanAttributes::Size_Symbolic: + // The values of font size intentionally coincide with the + // values of wxFontSymbolicSize enum elements so simply cast + // one to the other. + font.SetSymbolicSize( + static_cast(spanAttr.m_fontSize) + ); + break; + + case wxMarkupSpanAttributes::Size_PointParts: + font.SetPointSize((spanAttr.m_fontSize + 1023)/1024); + break; + } + + + const Attr attr(font, spanAttr.m_fgCol, spanAttr.m_bgCol); + OnAttrStart(attr); + + m_attrs.push(attr); + } + + virtual void OnSpanEnd(const wxMarkupSpanAttributes& WXUNUSED(spanAttr)) + { + DoEndAttr(); + } + +protected: + // Get the current attributes, i.e. the ones that should be used for + // rendering (or measuring or whatever) the text at the current position in + // the string. + // + // It may be called from OnAttrStart() to get the old attributes used + // before and from OnAttrEnd() to get the new attributes that will be used + // from now on but is mostly meant to be used from overridden OnText() + // implementations. + const Attr& GetAttr() const { return m_attrs.top(); } + + // A shortcut for accessing the font of the current attribute. + const wxFont& GetFont() const { return GetAttr().font; } + +private: + // Change only the font to the given one. Call OnAttrStart() to notify + // about the change and update the attributes stack. + void DoSetFont(const wxFont& font) + { + const Attr attr(font); + + OnAttrStart(attr); + + m_attrs.push(attr); + } + + // Apply the given function to the font currently on top of the font stack, + // push the new font on the stack and call OnAttrStart() with it. + void DoChangeFont(wxFont (wxFont::*func)() const) + { + DoSetFont((GetFont().*func)()); + } + + void DoEndAttr() + { + const Attr attr(m_attrs.top()); + m_attrs.pop(); + + OnAttrEnd(attr); + } + + template + void + DoApplyToFont(wxMarkupSpanAttributes::OptionalBool isIt, + wxFont& font, + void (wxFont::*func)(T), + T noValue, + T yesValue) + { + switch ( isIt ) + { + case wxMarkupSpanAttributes::Unspecified: + break; + + case wxMarkupSpanAttributes::No: + (font.*func)(noValue); + break; + + case wxMarkupSpanAttributes::Yes: + (font.*func)(yesValue); + break; + } + } + + wxStack m_attrs; + + wxDECLARE_NO_COPY_CLASS(wxMarkupParserAttrOutput); +}; + +#endif // _WX_PRIVATE_MARKUPPARSERATTR_H_ diff --git a/src/generic/markuptext.cpp b/src/generic/markuptext.cpp new file mode 100644 index 0000000000..03068db663 --- /dev/null +++ b/src/generic/markuptext.cpp @@ -0,0 +1,253 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/generic/markuptext.cpp +// Purpose: wxMarkupText implementation +// Author: Vadim Zeitlin +// Created: 2011-02-21 +// RCS-ID: $Id: wxhead.cpp,v 1.11 2010-04-22 12:44:51 zeitlin Exp $ +// Copyright: (c) 2011 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// for compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_MARKUP + +#ifndef WX_PRECOMP + #include "wx/gdicmn.h" + #include "wx/dc.h" +#endif // WX_PRECOMP + +#include "wx/generic/private/markuptext.h" + +#include "wx/private/markupparserattr.h" + +namespace +{ + +// ---------------------------------------------------------------------------- +// wxMarkupParserMeasureOutput: measure the extends of a markup string. +// ---------------------------------------------------------------------------- + +class wxMarkupParserMeasureOutput : public wxMarkupParserAttrOutput +{ +public: + // Initialize the base class with the font to use. As we don't care about + // colours (which don't affect the text measurements), don't bother to + // specify them at all. + wxMarkupParserMeasureOutput(wxDC& dc, int *visibleHeight) + : wxMarkupParserAttrOutput(dc.GetFont(), wxColour(), wxColour()), + m_dc(dc), + m_visibleHeight(visibleHeight) + { + if ( visibleHeight ) + *visibleHeight = 0; + } + + const wxSize& GetSize() const { return m_size; } + + + virtual void OnText(const wxString& text_) + { + const wxString text(wxControl::RemoveMnemonics(text_)); + + // TODO-MULTILINE-MARKUP: Must use GetMultiLineTextExtent(). + const wxSize size = m_dc.GetTextExtent(text); + + m_size.x += size.x; + if ( size.y > m_size.y ) + m_size.y = size.y; + + if ( m_visibleHeight ) + { + wxFontMetrics tm = m_dc.GetFontMetrics(); + int visibleHeight = tm.ascent - tm.internalLeading; + if ( *m_visibleHeight < visibleHeight ) + *m_visibleHeight = visibleHeight; + } + } + + virtual void OnAttrStart(const Attr& attr) + { + m_dc.SetFont(attr.font); + } + + virtual void OnAttrEnd(const Attr& WXUNUSED(attr)) + { + m_dc.SetFont(GetFont()); + } + +private: + wxDC& m_dc; + + // The values that we compute. + wxSize m_size; + int * const m_visibleHeight; // may be NULL + + wxDECLARE_NO_COPY_CLASS(wxMarkupParserMeasureOutput); +}; + +// ---------------------------------------------------------------------------- +// wxMarkupParserRenderOutput: render a markup string. +// ---------------------------------------------------------------------------- + +class wxMarkupParserRenderOutput : public wxMarkupParserAttrOutput +{ +public: + // Notice that the bottom of rectangle passed to our ctor is used as the + // baseline for the text we draw, i.e. it needs to be adjusted to exclude + // descent by the caller. + wxMarkupParserRenderOutput(wxDC& dc, + const wxRect& rect, + int flags) + : wxMarkupParserAttrOutput(dc.GetFont(), + dc.GetTextForeground(), + wxColour()), + m_dc(dc), + m_rect(rect), + m_flags(flags) + { + m_pos = m_rect.x; + + // We don't initialize the base class initial text background colour to + // the valid value because we want to be able to detect when we revert + // to the "absence of background colour" and set the background mode to + // be transparent in OnAttrStart() below. But do remember it to be able + // to restore it there later -- this doesn't affect us as the text + // background isn't used anyhow when the background mode is transparent + // but it might affect the caller if it sets the background mode to + // opaque and draws some text after using us. + m_origTextBackground = dc.GetTextBackground(); + } + + virtual void OnText(const wxString& text_) + { + wxString text; + int indexAccel = wxControl::FindAccelIndex(text_, &text); + if ( !(m_flags & wxMarkupText::Render_ShowAccels) ) + indexAccel = wxNOT_FOUND; + + // Adjust the position (unfortunately we need to do this manually as + // there is no notion of current text position in wx API) rectangle to + // ensure that all text segments use the same baseline (as there is + // nothing equivalent to Windows SetTextAlign(TA_BASELINE) neither). + wxRect rect(m_rect); + rect.x = m_pos; + + int descent; + m_dc.GetTextExtent(text, &rect.width, &rect.height, &descent); + rect.height -= descent; + rect.y += m_rect.height - rect.height; + + wxRect bounds; + m_dc.DrawLabel(text, wxBitmap(), + rect, wxALIGN_LEFT | wxALIGN_TOP, + indexAccel, + &bounds); + + // TODO-MULTILINE-MARKUP: Must update vertical position too. + m_pos += bounds.width; + } + + virtual void OnAttrStart(const Attr& attr) + { + m_dc.SetFont(attr.font); + if ( attr.foreground.IsOk() ) + m_dc.SetTextForeground(attr.foreground); + + if ( attr.background.IsOk() ) + { + // Setting the background colour is not enough, we must also change + // the mode to ensure that it is actually used. + m_dc.SetBackgroundMode(wxSOLID); + m_dc.SetTextBackground(attr.background); + } + } + + virtual void OnAttrEnd(const Attr& attr) + { + // We always restore the font because we always change it... + m_dc.SetFont(GetFont()); + + // ...but we only need to restore the colours if we had changed them. + if ( attr.foreground.IsOk() ) + m_dc.SetTextForeground(GetAttr().foreground); + + if ( attr.background.IsOk() ) + { + wxColour background = GetAttr().background; + if ( !background.IsOk() ) + { + // Invalid background colour indicates that the background + // should actually be made transparent and in this case the + // actual value of background colour doesn't matter but we also + // restore it just in case, see comment in the ctor. + m_dc.SetBackgroundMode(wxTRANSPARENT); + background = m_origTextBackground; + } + + m_dc.SetTextBackground(background); + } + } + +private: + wxDC& m_dc; + const wxRect m_rect; + const int m_flags; + + wxColour m_origTextBackground; + + // Current horizontal text output position. + // + // TODO-MULTILINE-MARKUP: Must keep vertical position too. + int m_pos; + + wxDECLARE_NO_COPY_CLASS(wxMarkupParserRenderOutput); +}; + +} // anonymous namespace + +// ============================================================================ +// wxMarkupText implementation +// ============================================================================ + +wxSize wxMarkupText::Measure(wxDC& dc, int *visibleHeight) const +{ + wxMarkupParserMeasureOutput out(dc, visibleHeight); + wxMarkupParser parser(out); + if ( !parser.Parse(m_markup) ) + { + wxFAIL_MSG( "Invalid markup" ); + return wxDefaultSize; + } + + return out.GetSize(); +} + +void wxMarkupText::Render(wxDC& dc, const wxRect& rect, int flags) +{ + // We want to center the above-baseline parts of the letter vertically, so + // we use the visible height and not the total height (which includes + // descent and internal leading) here. + int visibleHeight; + wxRect rectText(rect.GetPosition(), Measure(dc, &visibleHeight)); + rectText.height = visibleHeight; + + wxMarkupParserRenderOutput out(dc, rectText.CentreIn(rect), flags); + wxMarkupParser parser(out); + parser.Parse(m_markup); +} + +#endif // wxUSE_MARKUP -- 2.47.2