Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLarry Ewing <lewing@microsoft.com>2020-01-29 07:12:08 +0300
committerLarry Ewing <lewing@microsoft.com>2020-01-29 07:17:07 +0300
commitc6e9369de28efedd4271bfcd78409b822c1b71b3 (patch)
tree3af429072fadd46959da9ebb2bff3b9e8d1e99de
parentedfe20ffc74dc1918a8fc3416a37404a9ad3d35b (diff)
parent883162e861c95b7be7c3e830f1d70ff1c8e74fa9 (diff)
Merge remote-tracking branch 'upstream/master' into checkpoint
m---------external/api-snapshot0
m---------external/bockbuild0
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charcode.cs413
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charset.cs157
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetFlags.cs41
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetToCodepage.cs79
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetType.cs28
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/KeysInit.cs3
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Minor.cs3
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Picture.cs16
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/RTF.cs181
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharCode.cs392
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharName.cs411
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/TextMap.cs440
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.csproj8
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms.dll.sources8
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/ContextMenuStrip.cs19
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs39
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/ControlPaint.cs4
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs31
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/Line.cs537
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/LineTag.cs185
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/ListBox.cs2
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/RichTextBox.cs995
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/TabStops.cs258
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/TextBoxBase.cs96
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/TextControl.cs515
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripDropDown.cs51
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs6
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms/TreeView.cs22
-rw-r--r--mcs/class/System.Windows.Forms/System.Windows.Forms_test.dll.sources1
-rw-r--r--mcs/class/System.Windows.Forms/Test/System.Windows.Forms/ContextMenuStripTest.cs166
-rw-r--r--mcs/class/corlib/ReferenceSources/Buffer.cs24
-rw-r--r--mcs/class/corlib/Test/System/BufferTest.cs22
-rw-r--r--sdks/wasm/Mono.WebAssembly.DebuggerProxy/DebugStore.cs21
-rw-r--r--sdks/wasm/Mono.WebAssembly.DebuggerProxy/MonoProxy.cs2
36 files changed, 2689 insertions, 2487 deletions
diff --git a/external/api-snapshot b/external/api-snapshot
-Subproject c58c68d3c0c70ff011912fbc310da665dbd80c6
+Subproject 5b8247e289d17cef9ff645e21d896ea75bfe632
diff --git a/external/bockbuild b/external/bockbuild
-Subproject 839376573f9bac380ee81e8b23c6e2618a779e2
+Subproject 5a05db67cb14844eaafe8070eb425685df6aa9e
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charcode.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charcode.cs
deleted file mode 100644
index fc9ca63b12e..00000000000
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charcode.cs
+++ /dev/null
@@ -1,413 +0,0 @@
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
-//
-// Authors:
-// Peter Bartok (pbartok@novell.com)
-//
-//
-
-// COMPLETE
-
-using System.Collections;
-
-namespace System.Windows.Forms.RTF {
- internal class Charcode {
- #region Local Variables
- private StandardCharCode[] codes;
- private Hashtable reverse;
- private int size;
- #endregion // Local Variables
-
- #region Cached Values
- static Charcode ansi_generic;
- #endregion
-
- #region Public Constructors
- public Charcode() : this(256) {
- }
-
- private Charcode(int size) {
- this.size = size;
- this.codes = new StandardCharCode[size];
- this.reverse = new Hashtable(size);
-
- // No need to reinitialize array to its default value
- //for (int i = 0; i < size; i++) {
- // codes[i] = StandardCharCode.nothing;
- //}
- }
- #endregion // Public Constructors
-
- #region Public Instance Properties
- public int this[StandardCharCode c] {
- get {
- object obj;
-
- obj = reverse[c];
- if (obj != null) {
- return (int)obj;
- }
- for (int i = 0; i < size; i++) {
- if (codes[i] == c) {
- return i;
- }
- }
-
- return -1;
- }
- }
-
- public StandardCharCode this[int c] {
- get {
- if (c < 0 || c >= size) {
- return StandardCharCode.nothing;
- }
-
- return codes[c];
- }
-
- private set {
- if (c < 0 || c >= size) {
- return;
- }
-
- codes[c] = value;
- reverse[value] = c;
- }
- }
- #endregion // Public Instance Properties
-
- #region Public Instance Methods
- #endregion // Public Instance Methods
-
- #region Public Static Methods
- public static Charcode AnsiGeneric {
- get {
- if (ansi_generic != null)
- return ansi_generic;
-
- ansi_generic = new Charcode(256);
-
- ansi_generic[0x06] = StandardCharCode.formula;
- ansi_generic[0x1e] = StandardCharCode.nobrkhyphen;
- ansi_generic[0x1f] = StandardCharCode.opthyphen;
- ansi_generic[' '] = StandardCharCode.space;
- ansi_generic['!'] = StandardCharCode.exclam;
- ansi_generic['"'] = StandardCharCode.quotedbl;
- ansi_generic['#'] = StandardCharCode.numbersign;
- ansi_generic['$'] = StandardCharCode.dollar;
- ansi_generic['%'] = StandardCharCode.percent;
- ansi_generic['&'] = StandardCharCode.ampersand;
- ansi_generic['\\'] = StandardCharCode.quoteright;
- ansi_generic['('] = StandardCharCode.parenleft;
- ansi_generic[')'] = StandardCharCode.parenright;
- ansi_generic['*'] = StandardCharCode.asterisk;
- ansi_generic['+'] = StandardCharCode.plus;
- ansi_generic[','] = StandardCharCode.comma;
- ansi_generic['-'] = StandardCharCode.hyphen;
- ansi_generic['.'] = StandardCharCode.period;
- ansi_generic['/'] = StandardCharCode.slash;
- ansi_generic['0'] = StandardCharCode.zero;
- ansi_generic['1'] = StandardCharCode.one;
- ansi_generic['2'] = StandardCharCode.two;
- ansi_generic['3'] = StandardCharCode.three;
- ansi_generic['4'] = StandardCharCode.four;
- ansi_generic['5'] = StandardCharCode.five;
- ansi_generic['6'] = StandardCharCode.six;
- ansi_generic['7'] = StandardCharCode.seven;
- ansi_generic['8'] = StandardCharCode.eight;
- ansi_generic['9'] = StandardCharCode.nine;
- ansi_generic[':'] = StandardCharCode.colon;
- ansi_generic[';'] = StandardCharCode.semicolon;
- ansi_generic['<'] = StandardCharCode.less;
- ansi_generic['='] = StandardCharCode.equal;
- ansi_generic['>'] = StandardCharCode.greater;
- ansi_generic['?'] = StandardCharCode.question;
- ansi_generic['@'] = StandardCharCode.at;
- ansi_generic['A'] = StandardCharCode.A;
- ansi_generic['B'] = StandardCharCode.B;
- ansi_generic['C'] = StandardCharCode.C;
- ansi_generic['D'] = StandardCharCode.D;
- ansi_generic['E'] = StandardCharCode.E;
- ansi_generic['F'] = StandardCharCode.F;
- ansi_generic['G'] = StandardCharCode.G;
- ansi_generic['H'] = StandardCharCode.H;
- ansi_generic['I'] = StandardCharCode.I;
- ansi_generic['J'] = StandardCharCode.J;
- ansi_generic['K'] = StandardCharCode.K;
- ansi_generic['L'] = StandardCharCode.L;
- ansi_generic['M'] = StandardCharCode.M;
- ansi_generic['N'] = StandardCharCode.N;
- ansi_generic['O'] = StandardCharCode.O;
- ansi_generic['P'] = StandardCharCode.P;
- ansi_generic['Q'] = StandardCharCode.Q;
- ansi_generic['R'] = StandardCharCode.R;
- ansi_generic['S'] = StandardCharCode.S;
- ansi_generic['T'] = StandardCharCode.T;
- ansi_generic['U'] = StandardCharCode.U;
- ansi_generic['V'] = StandardCharCode.V;
- ansi_generic['W'] = StandardCharCode.W;
- ansi_generic['X'] = StandardCharCode.X;
- ansi_generic['Y'] = StandardCharCode.Y;
- ansi_generic['Z'] = StandardCharCode.Z;
- ansi_generic['['] = StandardCharCode.bracketleft;
- ansi_generic['\\'] = StandardCharCode.backslash;
- ansi_generic[']'] = StandardCharCode.bracketright;
- ansi_generic['^'] = StandardCharCode.asciicircum;
- ansi_generic['_'] = StandardCharCode.underscore;
- ansi_generic['`'] = StandardCharCode.quoteleft;
- ansi_generic['a'] = StandardCharCode.a;
- ansi_generic['b'] = StandardCharCode.b;
- ansi_generic['c'] = StandardCharCode.c;
- ansi_generic['d'] = StandardCharCode.d;
- ansi_generic['e'] = StandardCharCode.e;
- ansi_generic['f'] = StandardCharCode.f;
- ansi_generic['g'] = StandardCharCode.g;
- ansi_generic['h'] = StandardCharCode.h;
- ansi_generic['i'] = StandardCharCode.i;
- ansi_generic['j'] = StandardCharCode.j;
- ansi_generic['k'] = StandardCharCode.k;
- ansi_generic['l'] = StandardCharCode.l;
- ansi_generic['m'] = StandardCharCode.m;
- ansi_generic['n'] = StandardCharCode.n;
- ansi_generic['o'] = StandardCharCode.o;
- ansi_generic['p'] = StandardCharCode.p;
- ansi_generic['q'] = StandardCharCode.q;
- ansi_generic['r'] = StandardCharCode.r;
- ansi_generic['s'] = StandardCharCode.s;
- ansi_generic['t'] = StandardCharCode.t;
- ansi_generic['u'] = StandardCharCode.u;
- ansi_generic['v'] = StandardCharCode.v;
- ansi_generic['w'] = StandardCharCode.w;
- ansi_generic['x'] = StandardCharCode.x;
- ansi_generic['y'] = StandardCharCode.y;
- ansi_generic['z'] = StandardCharCode.z;
- ansi_generic['{'] = StandardCharCode.braceleft;
- ansi_generic['|'] = StandardCharCode.bar;
- ansi_generic['}'] = StandardCharCode.braceright;
- ansi_generic['~'] = StandardCharCode.asciitilde;
- ansi_generic[0xa0] = StandardCharCode.nobrkspace;
- ansi_generic[0xa1] = StandardCharCode.exclamdown;
- ansi_generic[0xa2] = StandardCharCode.cent;
- ansi_generic[0xa3] = StandardCharCode.sterling;
- ansi_generic[0xa4] = StandardCharCode.currency;
- ansi_generic[0xa5] = StandardCharCode.yen;
- ansi_generic[0xa6] = StandardCharCode.brokenbar;
- ansi_generic[0xa7] = StandardCharCode.section;
- ansi_generic[0xa8] = StandardCharCode.dieresis;
- ansi_generic[0xa9] = StandardCharCode.copyright;
- ansi_generic[0xaa] = StandardCharCode.ordfeminine;
- ansi_generic[0xab] = StandardCharCode.guillemotleft;
- ansi_generic[0xac] = StandardCharCode.logicalnot;
- ansi_generic[0xad] = StandardCharCode.opthyphen;
- ansi_generic[0xae] = StandardCharCode.registered;
- ansi_generic[0xaf] = StandardCharCode.macron;
- ansi_generic[0xb0] = StandardCharCode.degree;
- ansi_generic[0xb1] = StandardCharCode.plusminus;
- ansi_generic[0xb2] = StandardCharCode.twosuperior;
- ansi_generic[0xb3] = StandardCharCode.threesuperior;
- ansi_generic[0xb4] = StandardCharCode.acute;
- ansi_generic[0xb5] = StandardCharCode.mu;
- ansi_generic[0xb6] = StandardCharCode.paragraph;
- ansi_generic[0xb7] = StandardCharCode.periodcentered;
- ansi_generic[0xb8] = StandardCharCode.cedilla;
- ansi_generic[0xb9] = StandardCharCode.onesuperior;
- ansi_generic[0xba] = StandardCharCode.ordmasculine;
- ansi_generic[0xbb] = StandardCharCode.guillemotright;
- ansi_generic[0xbc] = StandardCharCode.onequarter;
- ansi_generic[0xbd] = StandardCharCode.onehalf;
- ansi_generic[0xbe] = StandardCharCode.threequarters;
- ansi_generic[0xbf] = StandardCharCode.questiondown;
- ansi_generic[0xc0] = StandardCharCode.Agrave;
- ansi_generic[0xc1] = StandardCharCode.Aacute;
- ansi_generic[0xc2] = StandardCharCode.Acircumflex;
- ansi_generic[0xc3] = StandardCharCode.Atilde;
- ansi_generic[0xc4] = StandardCharCode.Adieresis;
- ansi_generic[0xc5] = StandardCharCode.Aring;
- ansi_generic[0xc6] = StandardCharCode.AE;
- ansi_generic[0xc7] = StandardCharCode.Ccedilla;
- ansi_generic[0xc8] = StandardCharCode.Egrave;
- ansi_generic[0xc9] = StandardCharCode.Eacute;
- ansi_generic[0xca] = StandardCharCode.Ecircumflex;
- ansi_generic[0xcb] = StandardCharCode.Edieresis;
- ansi_generic[0xcc] = StandardCharCode.Igrave;
- ansi_generic[0xcd] = StandardCharCode.Iacute;
- ansi_generic[0xce] = StandardCharCode.Icircumflex;
- ansi_generic[0xcf] = StandardCharCode.Idieresis;
- ansi_generic[0xd0] = StandardCharCode.Eth;
- ansi_generic[0xd1] = StandardCharCode.Ntilde;
- ansi_generic[0xd2] = StandardCharCode.Ograve;
- ansi_generic[0xd3] = StandardCharCode.Oacute;
- ansi_generic[0xd4] = StandardCharCode.Ocircumflex;
- ansi_generic[0xd5] = StandardCharCode.Otilde;
- ansi_generic[0xd6] = StandardCharCode.Odieresis;
- ansi_generic[0xd7] = StandardCharCode.multiply;
- ansi_generic[0xd8] = StandardCharCode.Oslash;
- ansi_generic[0xd9] = StandardCharCode.Ugrave;
- ansi_generic[0xda] = StandardCharCode.Uacute;
- ansi_generic[0xdb] = StandardCharCode.Ucircumflex;
- ansi_generic[0xdc] = StandardCharCode.Udieresis;
- ansi_generic[0xdd] = StandardCharCode.Yacute;
- ansi_generic[0xde] = StandardCharCode.Thorn;
- ansi_generic[0xdf] = StandardCharCode.germandbls;
- ansi_generic[0xe0] = StandardCharCode.agrave;
- ansi_generic[0xe1] = StandardCharCode.aacute;
- ansi_generic[0xe2] = StandardCharCode.acircumflex;
- ansi_generic[0xe3] = StandardCharCode.atilde;
- ansi_generic[0xe4] = StandardCharCode.adieresis;
- ansi_generic[0xe5] = StandardCharCode.aring;
- ansi_generic[0xe6] = StandardCharCode.ae;
- ansi_generic[0xe7] = StandardCharCode.ccedilla;
- ansi_generic[0xe8] = StandardCharCode.egrave;
- ansi_generic[0xe9] = StandardCharCode.eacute;
- ansi_generic[0xea] = StandardCharCode.ecircumflex;
- ansi_generic[0xeb] = StandardCharCode.edieresis;
- ansi_generic[0xec] = StandardCharCode.igrave;
- ansi_generic[0xed] = StandardCharCode.iacute;
- ansi_generic[0xee] = StandardCharCode.icircumflex;
- ansi_generic[0xef] = StandardCharCode.idieresis;
- ansi_generic[0xf0] = StandardCharCode.eth;
- ansi_generic[0xf1] = StandardCharCode.ntilde;
- ansi_generic[0xf2] = StandardCharCode.ograve;
- ansi_generic[0xf3] = StandardCharCode.oacute;
- ansi_generic[0xf4] = StandardCharCode.ocircumflex;
- ansi_generic[0xf5] = StandardCharCode.otilde;
- ansi_generic[0xf6] = StandardCharCode.odieresis;
- ansi_generic[0xf7] = StandardCharCode.divide;
- ansi_generic[0xf8] = StandardCharCode.oslash;
- ansi_generic[0xf9] = StandardCharCode.ugrave;
- ansi_generic[0xfa] = StandardCharCode.uacute;
- ansi_generic[0xfb] = StandardCharCode.ucircumflex;
- ansi_generic[0xfc] = StandardCharCode.udieresis;
- ansi_generic[0xfd] = StandardCharCode.yacute;
- ansi_generic[0xfe] = StandardCharCode.thorn;
- ansi_generic[0xff] = StandardCharCode.ydieresis;
-
- return ansi_generic;
- }
- }
-
- public static Charcode AnsiSymbol {
- get {
- Charcode code = new Charcode(256);
-
- code[0x06] = StandardCharCode.formula;
- code[0x1e] = StandardCharCode.nobrkhyphen;
- code[0x1f] = StandardCharCode.opthyphen;
- code[' '] = StandardCharCode.space;
- code['!'] = StandardCharCode.exclam;
- code['"'] = StandardCharCode.universal;
- code['#'] = StandardCharCode.mathnumbersign;
- code['$'] = StandardCharCode.existential;
- code['%'] = StandardCharCode.percent;
- code['&'] = StandardCharCode.ampersand;
- code['\\'] = StandardCharCode.suchthat;
- code['('] = StandardCharCode.parenleft;
- code[')'] = StandardCharCode.parenright;
- code['*'] = StandardCharCode.mathasterisk;
- code['+'] = StandardCharCode.mathplus;
- code[','] = StandardCharCode.comma;
- code['-'] = StandardCharCode.mathminus;
- code['.'] = StandardCharCode.period;
- code['/'] = StandardCharCode.slash;
- code['0'] = StandardCharCode.zero;
- code['1'] = StandardCharCode.one;
- code['2'] = StandardCharCode.two;
- code['3'] = StandardCharCode.three;
- code['4'] = StandardCharCode.four;
- code['5'] = StandardCharCode.five;
- code['6'] = StandardCharCode.six;
- code['7'] = StandardCharCode.seven;
- code['8'] = StandardCharCode.eight;
- code['9'] = StandardCharCode.nine;
- code[':'] = StandardCharCode.colon;
- code[';'] = StandardCharCode.semicolon;
- code['<'] = StandardCharCode.less;
- code['='] = StandardCharCode.mathequal;
- code['>'] = StandardCharCode.greater;
- code['?'] = StandardCharCode.question;
- code['@'] = StandardCharCode.congruent;
- code['A'] = StandardCharCode.Alpha;
- code['B'] = StandardCharCode.Beta;
- code['C'] = StandardCharCode.Chi;
- code['D'] = StandardCharCode.Delta;
- code['E'] = StandardCharCode.Epsilon;
- code['F'] = StandardCharCode.Phi;
- code['G'] = StandardCharCode.Gamma;
- code['H'] = StandardCharCode.Eta;
- code['I'] = StandardCharCode.Iota;
- code['K'] = StandardCharCode.Kappa;
- code['L'] = StandardCharCode.Lambda;
- code['M'] = StandardCharCode.Mu;
- code['N'] = StandardCharCode.Nu;
- code['O'] = StandardCharCode.Omicron;
- code['P'] = StandardCharCode.Pi;
- code['Q'] = StandardCharCode.Theta;
- code['R'] = StandardCharCode.Rho;
- code['S'] = StandardCharCode.Sigma;
- code['T'] = StandardCharCode.Tau;
- code['U'] = StandardCharCode.Upsilon;
- code['V'] = StandardCharCode.varsigma;
- code['W'] = StandardCharCode.Omega;
- code['X'] = StandardCharCode.Xi;
- code['Y'] = StandardCharCode.Psi;
- code['Z'] = StandardCharCode.Zeta;
- code['['] = StandardCharCode.bracketleft;
- code['\\'] = StandardCharCode.backslash;
- code[']'] = StandardCharCode.bracketright;
- code['^'] = StandardCharCode.asciicircum;
- code['_'] = StandardCharCode.underscore;
- code['`'] = StandardCharCode.quoteleft;
- code['a'] = StandardCharCode.alpha;
- code['b'] = StandardCharCode.beta;
- code['c'] = StandardCharCode.chi;
- code['d'] = StandardCharCode.delta;
- code['e'] = StandardCharCode.epsilon;
- code['f'] = StandardCharCode.phi;
- code['g'] = StandardCharCode.gamma;
- code['h'] = StandardCharCode.eta;
- code['i'] = StandardCharCode.iota;
- code['k'] = StandardCharCode.kappa;
- code['l'] = StandardCharCode.lambda;
- code['m'] = StandardCharCode.mu;
- code['n'] = StandardCharCode.nu;
- code['o'] = StandardCharCode.omicron;
- code['p'] = StandardCharCode.pi;
- code['q'] = StandardCharCode.theta;
- code['r'] = StandardCharCode.rho;
- code['s'] = StandardCharCode.sigma;
- code['t'] = StandardCharCode.tau;
- code['u'] = StandardCharCode.upsilon;
- code['w'] = StandardCharCode.omega;
- code['x'] = StandardCharCode.xi;
- code['y'] = StandardCharCode.psi;
- code['z'] = StandardCharCode.zeta;
- code['{'] = StandardCharCode.braceleft;
- code['|'] = StandardCharCode.bar;
- code['}'] = StandardCharCode.braceright;
- code['~'] = StandardCharCode.mathtilde;
-
- return code;
- }
- }
- #endregion // Public Static Methods
- }
-}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charset.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charset.cs
deleted file mode 100644
index cba57819595..00000000000
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Charset.cs
+++ /dev/null
@@ -1,157 +0,0 @@
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
-//
-// Authors:
-// Peter Bartok (pbartok@novell.com)
-//
-//
-
-using System;
-
-// COMPLETE
-
-namespace System.Windows.Forms.RTF {
-
-#if RTF_LIB
- public
-#else
- internal
-#endif
- class Charset {
- #region Local Variables
- private CharsetType id;
- private CharsetFlags flags;
- private Charcode code;
- private string file;
- #endregion // Local Variables
-
- #region Public Constructors
- public Charset() {
- flags = CharsetFlags.Read | CharsetFlags.Switch;
- id = CharsetType.General;
- file = string.Empty;
- this.ReadMap();
- }
- #endregion // Public Constructors
-
- #region Public Instance Properties
- public Charcode Code {
- get {
- return code;
- }
-
- set {
- code = value;
- }
- }
-
- public CharsetFlags Flags {
- get {
- return flags;
- }
-
- set {
- flags = value;
- }
- }
-
- public CharsetType ID {
- get {
- return id;
- }
-
- set {
- switch(value) {
- case CharsetType.Symbol: {
- id = CharsetType.Symbol;
- return;
- }
-
- default:
- case CharsetType.General: {
- id = CharsetType.General;
- return;
- }
- }
- }
- }
-
- public string File {
- get {
- return file;
- }
-
- set {
- if (file != value) {
- file = value;
- }
- }
- }
-
- public StandardCharCode this[int c] {
- get {
- return code[c];
- }
- }
-
- #endregion // Public Instance Properties
-
- #region Public Instance Methods
- public bool ReadMap() {
- switch (id) {
- case CharsetType.General: {
- if (file == string.Empty) {
- code = Charcode.AnsiGeneric;
- return true;
- }
- // FIXME - implement reading charmap from file...
- return true;
- }
-
- case CharsetType.Symbol: {
- if (file == string.Empty) {
- code = Charcode.AnsiSymbol;
- return true;
- }
-
- // FIXME - implement reading charmap from file...
- return true;
- }
-
- default: {
- return false;
- }
- }
- }
-
- public char StdCharCode(string name) {
- // FIXME - finish this
- return ' ';
-
- }
-
- public string StdCharName(char code) {
- // FIXME - finish this
- return String.Empty;
- }
- #endregion // Public Instance Methods
- }
-}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetFlags.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetFlags.cs
deleted file mode 100644
index 7cfcb8c6539..00000000000
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetFlags.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
-//
-// Authors:
-// Peter Bartok (pbartok@novell.com)
-//
-//
-
-// COMPLETE
-
-namespace System.Windows.Forms.RTF {
- [Flags]
-#if RTF_LIB
- public
-#else
- internal
-#endif
- enum CharsetFlags {
- None = 0x00,
- Read = 0x01,
- Switch = 0x02
- }
-}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetToCodepage.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetToCodepage.cs
new file mode 100644
index 00000000000..783c6351007
--- /dev/null
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetToCodepage.cs
@@ -0,0 +1,79 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2020 Karl Scowen
+//
+// Authors:
+// Karl Scowen <contact@scowencomputers.co.nz>
+//
+//
+
+
+namespace System.Windows.Forms.RTF {
+ internal static class CharsetToCodepage {
+ public static int Translate(CharsetType charset)
+ {
+ switch (charset) {
+ case CharsetType.General:
+ case CharsetType.Arabic_Traditional:
+ case CharsetType.Arabic_user:
+ case CharsetType.Hebrew_user:
+ case CharsetType.Mac: // Technically wrong, because "mac" should actually be quite a few with their own code pages...
+ default:
+ return System.Text.Encoding.Default.CodePage;
+ case CharsetType.ANSI:
+ return 1252;
+ case CharsetType.Symbol:
+ return 42;
+ case CharsetType.Shift_Jis:
+ return 932;
+ case CharsetType.Hangul:
+ return 949;
+ case CharsetType.Johab:
+ return 1361;
+ case CharsetType.GB2312:
+ return 936;
+ case CharsetType.Big5:
+ return 950;
+ case CharsetType.Greek:
+ return 1253;
+ case CharsetType.Turkish:
+ return 1254;
+ case CharsetType.Vietnamese:
+ return 1258;
+ case CharsetType.Hebrew:
+ return 1255;
+ case CharsetType.Arabic:
+ return 1256;
+ case CharsetType.Baltic:
+ return 1257;
+ case CharsetType.Russian:
+ return 1251;
+ case CharsetType.Thai:
+ return 874;
+ case CharsetType.Eastern_European:
+ return 1250;
+ case CharsetType.PC_437:
+ return 437;
+ case CharsetType.OEM:
+ return 850;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetType.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetType.cs
index a934dc82869..4dbb3d94897 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetType.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/CharsetType.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok (pbartok@novell.com)
+// Karl Scowen (contact@scowencomputers.co.nz)
//
//
@@ -33,8 +34,29 @@ namespace System.Windows.Forms.RTF {
#else
internal
#endif
- enum CharsetType {
- General = 0,
- Symbol = 1,
+ enum CharsetType : byte {
+ ANSI = 0,
+ General = 1,
+ Symbol = 2,
+ Mac = 77,
+ Shift_Jis = 128,
+ Hangul = 129,
+ Johab = 130,
+ GB2312 = 134,
+ Big5 = 136,
+ Greek = 161,
+ Turkish = 162,
+ Vietnamese = 163,
+ Hebrew = 177,
+ Arabic = 178,
+ Arabic_Traditional = 179,
+ Arabic_user = 180,
+ Hebrew_user = 181,
+ Baltic = 186,
+ Russian = 204,
+ Thai = 222,
+ Eastern_European = 238,
+ PC_437 = 254,
+ OEM = 255
}
}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/KeysInit.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/KeysInit.cs
index 72188e6daa7..5ff3ff426c6 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/KeysInit.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/KeysInit.cs
@@ -366,10 +366,12 @@ namespace System.Windows.Forms.RTF {
new KeyStruct(Major.StyleAttr, Minor.Next, "snext"),
new KeyStruct(Major.PictAttr, Minor.MacQD, "macpict"),
new KeyStruct(Major.PictAttr, Minor.PMMetafile, "pmmetafile"),
+ new KeyStruct(Major.PictAttr, Minor.EnhancedMetafile, "emfblip"),
new KeyStruct(Major.PictAttr, Minor.WinMetafile, "wmetafile"),
new KeyStruct(Major.PictAttr, Minor.DevIndBitmap, "dibitmap"),
new KeyStruct(Major.PictAttr, Minor.WinBitmap, "wbitmap"),
new KeyStruct(Major.PictAttr, Minor.PngBlip, "pngblip"),
+ new KeyStruct(Major.PictAttr, Minor.JpegBlip, "jpgblip"),
new KeyStruct(Major.PictAttr, Minor.PixelBits, "wbmbitspixel"),
new KeyStruct(Major.PictAttr, Minor.BitmapPlanes, "wbmplanes"),
new KeyStruct(Major.PictAttr, Minor.BitmapWid, "wbmwidthbytes"),
@@ -393,6 +395,7 @@ namespace System.Windows.Forms.RTF {
new KeyStruct(Major.NeXTGrAttr, Minor.NeXTGHeight, "height"),
new KeyStruct(Major.Destination, Minor.OptDest, "*"),
new KeyStruct(Major.Destination, Minor.FontTbl, "fonttbl"),
+ new KeyStruct(Major.Destination, Minor.FontName, "fname"),
new KeyStruct(Major.Destination, Minor.FontAltName, "falt"),
new KeyStruct(Major.Destination, Minor.EmbeddedFont, "fonteb"),
new KeyStruct(Major.Destination, Minor.FontFile, "fontfile"),
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Minor.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Minor.cs
index 8b0f1bc6f8d..4033f5bbf24 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Minor.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Minor.cs
@@ -41,6 +41,7 @@ namespace System.Windows.Forms.RTF {
// Major.Destinan
FontTbl,
+ FontName,
FontAltName,
EmbeddedFont,
FontFile,
@@ -520,10 +521,12 @@ namespace System.Windows.Forms.RTF {
// Major.PictAttr
MacQD,
PMMetafile,
+ EnhancedMetafile,
WinMetafile,
DevIndBitmap,
WinBitmap,
PngBlip,
+ JpegBlip,
PixelBits,
BitmapPlanes,
BitmapWid,
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Picture.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Picture.cs
index 244bcd9adff..35845b20aff 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Picture.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/Picture.cs
@@ -66,7 +66,7 @@ namespace System.Windows.Forms.RTF {
public float Width {
get {
float w = width;
- if (w == -1) {
+ if (w < 0) {
if (image == null)
image = ToImage ();
w = image.Width;
@@ -79,7 +79,7 @@ namespace System.Windows.Forms.RTF {
public float Height {
get {
float h = height;
- if (h == -1) {
+ if (h < 0) {
if (image == null)
image = ToImage ();
h = image.Height;
@@ -113,7 +113,9 @@ namespace System.Windows.Forms.RTF {
return false;
switch (image_type) {
case Minor.PngBlip:
+ case Minor.JpegBlip:
case Minor.WinMetafile:
+ case Minor.EnhancedMetafile:
break;
default:
return false;
@@ -126,15 +128,7 @@ namespace System.Windows.Forms.RTF {
{
if (image == null)
image = ToImage ();
-
- float height = this.height;
- float width = this.width;
-
- if (height == -1)
- height = image.Height;
- if (width == -1)
- width = image.Width;
- dc.DrawImage (image, x, y, width, height);
+ dc.DrawImage (image, x, y, Width, Height);
}
public Image ToImage ()
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/RTF.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/RTF.cs
index 3b02df81ffb..469c379ed2b 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/RTF.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/RTF.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok (pbartok@novell.com)
+// Karl Scowen <contact@scowencomputers.co.nz>
//
// COMPLETE
@@ -60,10 +61,6 @@ namespace System.Windows.Forms.RTF {
private char prev_char;
private bool bump_line;
-
- private Font font_list;
-
- private Charset cur_charset;
private Stack charset_stack;
private Style styles;
@@ -101,10 +98,7 @@ namespace System.Windows.Forms.RTF {
line_pos = 0;
prev_char = unchecked((char)-1);
bump_line = false;
- font_list = null;
- charset_stack = null;
-
- cur_charset = new Charset();
+ charset_stack = new Stack();
destination_callbacks = new DestinationCallback();
class_callbacks = new ClassCallback();
@@ -369,49 +363,52 @@ SkipCRLF:
GetToken2();
if (this.rtf_class == TokenClass.Text) {
- this.minor = (Minor)this.cur_charset[(int)this.major];
- if (encoding == null) {
+ if (encoding == null)
encoding = Encoding.GetEncoding (encoding_code_page);
- }
encoded_text = new String (encoding.GetChars (new byte [] { (byte) this.major }));
- }
-
- if (this.cur_charset.Flags == CharsetFlags.None) {
- return this.rtf_class;
- }
-
- if (CheckCMM (TokenClass.Control, Major.Unicode, Minor.UnicodeAnsiCodepage)) {
+ } else if (CheckCMM (TokenClass.Control, Major.Unicode, Minor.UnicodeAnsiCodepage)) {
encoding_code_page = param;
// fallback to the default one in case we have an invalid value
if (encoding_code_page < 0 || encoding_code_page > 65535)
encoding_code_page = DefaultEncodingCodePage;
- }
- if (((this.cur_charset.Flags & CharsetFlags.Read) != 0) && CheckCM(TokenClass.Control, Major.CharSet)) {
- this.cur_charset.ReadMap();
- } else if (((this.cur_charset.Flags & CharsetFlags.Switch) != 0) && CheckCMM(TokenClass.Control, Major.CharAttr, Minor.FontNum)) {
+ encoding = null;
+ } else if (CheckCMM(TokenClass.Control, Major.CharAttr, Minor.FontNum)) {
Font fp;
- fp = Font.GetFont(this.font_list, this.param);
+ fp = Font.GetFont(this.fonts, this.param);
if (fp != null) {
- if (fp.Name.StartsWith("Symbol")) {
- this.cur_charset.ID = CharsetType.Symbol;
+ if (fp.Codepage != 0) {
+ if (fp.Codepage != encoding_code_page) {
+ encoding_code_page = fp.Codepage;
+ encoding = null;
+ }
} else {
- this.cur_charset.ID = CharsetType.General;
- }
- } else if (((this.cur_charset.Flags & CharsetFlags.Switch) != 0) && (this.rtf_class == TokenClass.Group)) {
- switch(this.major) {
- case Major.BeginGroup: {
- this.charset_stack.Push(this.cur_charset);
- break;
+ var cp = CharsetToCodepage.Translate (fp.Charset);
+ if (cp != 0 && cp != encoding_code_page) {
+ encoding_code_page = cp;
+ encoding = null;
}
+ }
+ }
+ } else if (this.rtf_class == TokenClass.Group) {
+ switch(this.major) {
+ case Major.BeginGroup: {
+ charset_stack.Push(encoding_code_page);
+ break;
+ }
- case Major.EndGroup: {
- this.cur_charset = (Charset)this.charset_stack.Pop();
- break;
+ case Major.EndGroup: {
+ if (charset_stack.Count > 0) {
+ encoding_code_page = (int)this.charset_stack.Pop();
+ } else {
+ encoding_code_page = DefaultEncodingCodePage;
}
+ if (encoding != null && encoding.CodePage != encoding_code_page)
+ encoding = null;
+ break;
}
}
}
@@ -677,7 +674,10 @@ SkipCRLF:
font = new Font(rtf);
- while ((rtf.rtf_class != TokenClass.EOF) && (!rtf.CheckCM(TokenClass.Text, (Major)';')) && (!rtf.CheckCM(TokenClass.Group, Major.EndGroup))) {
+ int depth = 0;
+ string untaggedName = null;
+
+ while ((rtf.rtf_class != TokenClass.EOF) && (!rtf.CheckCM(TokenClass.Text, (Major)';')) && depth >= 0) {
if (rtf.rtf_class == TokenClass.Control) {
switch(rtf.major) {
case Major.FontFamily: {
@@ -734,6 +734,26 @@ SkipCRLF:
break;
}
+ case Major.Destination: {
+ switch (rtf.minor) {
+ case Minor.FontName:
+ untaggedName = ReadFontName (rtf);
+ break;
+
+ case Minor.FontAltName:
+ font.AltName = ReadFontName (rtf);
+ break;
+
+ default: {
+ #if RTF_DEBUG
+ Console.WriteLine ("Got unhandled Control.Destination.Minor: " + rtf.minor);
+ #endif
+ break;
+ }
+ }
+ break;
+ }
+
default: {
#if RTF_DEBUG
Console.WriteLine("ReadFontTbl: Unknown Control token " + rtf.major);
@@ -742,22 +762,12 @@ SkipCRLF:
}
}
} else if (rtf.CheckCM(TokenClass.Group, Major.BeginGroup)) {
- rtf.SkipGroup();
- } else if (rtf.rtf_class == TokenClass.Text) {
- StringBuilder sb;
-
- sb = new StringBuilder();
-
- while ((rtf.rtf_class != TokenClass.EOF) && (!rtf.CheckCM(TokenClass.Text, (Major)';')) && (!rtf.CheckCM(TokenClass.Group, Major.EndGroup)) && (!rtf.CheckCM(TokenClass.Group, Major.BeginGroup))) {
- sb.Append((char)rtf.major);
- rtf.GetToken();
- }
-
- if (rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
- rtf.UngetToken();
- }
-
- font.Name = sb.ToString();
+ depth++;
+ } else if (rtf.CheckCM(TokenClass.Group, Major.EndGroup)) {
+ depth--;
+ } else if (rtf.rtf_class == TokenClass.Text)
+ {
+ font.Name = ReadFontName (rtf);
continue;
#if RTF_DEBUG
} else {
@@ -768,6 +778,9 @@ SkipCRLF:
rtf.GetToken();
}
+ if (untaggedName != null)
+ font.Name = untaggedName;
+
if (old == 0) {
rtf.GetToken();
@@ -788,6 +801,26 @@ SkipCRLF:
rtf.RouteToken();
}
+ private static String ReadFontName(RTF rtf)
+ {
+ StringBuilder sb = new StringBuilder ();
+
+ while (rtf.rtf_class != TokenClass.EOF && rtf.rtf_class != TokenClass.Text)
+ rtf.GetToken ();
+
+ while ((rtf.rtf_class != TokenClass.EOF) && (!rtf.CheckCM (TokenClass.Text, (Major)';')) && (!rtf.CheckCM(TokenClass.Group, Major.EndGroup)) &&
+ (!rtf.CheckCM (TokenClass.Group, Major.BeginGroup))) {
+ sb.Append ((char)rtf.major);
+ rtf.GetToken ();
+ }
+
+ if (rtf.CheckCM (TokenClass.Group, Major.EndGroup)) {
+ rtf.UngetToken();
+ }
+
+ return sb.ToString ();
+ }
+
private void ReadColorTbl(RTF rtf) {
Color color;
int num;
@@ -943,20 +976,25 @@ SkipCRLF:
private void ReadPictGroup(RTF rtf)
{
bool read_image_data = false;
-
+ int groupDepth = 0;
Picture picture = new Picture ();
while (true) {
rtf.GetToken ();
+ if (rtf.CheckCM (TokenClass.Group, Major.BeginGroup))
+ groupDepth++;
+
if (rtf.CheckCM (TokenClass.Group, Major.EndGroup))
+ groupDepth--;
+
+ if (groupDepth < 0)
break;
switch (minor) {
case Minor.PngBlip:
- picture.ImageType = minor;
- read_image_data = true;
- break;
+ case Minor.JpegBlip:
case Minor.WinMetafile:
+ case Minor.EnhancedMetafile:
picture.ImageType = minor;
read_image_data = true;
continue;
@@ -1047,10 +1085,33 @@ SkipCRLF:
}
}
- private void ReadObjGroup(RTF rtf) {
- rtf.SkipGroup();
- rtf.RouteToken();
+ private void ReadObjGroup (RTF rtf)
+ {
+ int level;
+
+ level = 1;
+
+ while (GetToken () != TokenClass.EOF && this.minor != Minor.ObjResult) {
+ if (rtf_class == TokenClass.Group) {
+ if (this.major == Major.BeginGroup) {
+ level++;
+ } else if (this.major == Major.EndGroup) {
+ level--;
+ if (level < 1) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (level >= 1) {
+ GetToken ();
+
+ if (rtf_class == TokenClass.Group)
+ GetToken ();
+ rtf.RouteToken ();
+ }
}
#endregion // Default Delegates
}
-}
+ }
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharCode.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharCode.cs
deleted file mode 100644
index 906735ba181..00000000000
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharCode.cs
+++ /dev/null
@@ -1,392 +0,0 @@
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
-//
-// Authors:
-// Peter Bartok (pbartok@novell.com)
-//
-//
-
-// COMPLETE
-
-namespace System.Windows.Forms.RTF {
-
-#if RTF_LIB
- public
-#else
- internal
-#endif
- enum StandardCharCode {
- nothing = 0,
- space = 1,
- exclam = 2,
- quotedbl = 3,
- numbersign = 4,
- dollar = 5,
- percent = 6,
- ampersand = 7,
- quoteright = 8,
- parenleft = 9,
- parenright = 10,
- asterisk = 11,
- plus = 12,
- comma = 13,
- hyphen = 14,
- period = 15,
- slash = 16,
- zero = 17,
- one = 18,
- two = 19,
- three = 20,
- four = 21,
- five = 22,
- six = 23,
- seven = 24,
- eight = 25,
- nine = 26,
- colon = 27,
- semicolon = 28,
- less = 29,
- equal = 30,
- greater = 31,
- question = 32,
- at = 33,
- A = 34,
- B = 35,
- C = 36,
- D = 37,
- E = 38,
- F = 39,
- G = 40,
- H = 41,
- I = 42,
- J = 43,
- K = 44,
- L = 45,
- M = 46,
- N = 47,
- O = 48,
- P = 49,
- Q = 50,
- R = 51,
- S = 52,
- T = 53,
- U = 54,
- V = 55,
- W = 56,
- X = 57,
- Y = 58,
- Z = 59,
- bracketleft = 60,
- backslash = 61,
- bracketright = 62,
- asciicircum = 63,
- underscore = 64,
- quoteleft = 65,
- a = 66,
- b = 67,
- c = 68,
- d = 69,
- e = 70,
- f = 71,
- g = 72,
- h = 73,
- i = 74,
- j = 75,
- k = 76,
- l = 77,
- m = 78,
- n = 79,
- o = 80,
- p = 81,
- q = 82,
- r = 83,
- s = 84,
- t = 85,
- u = 86,
- v = 87,
- w = 88,
- x = 89,
- y = 90,
- z = 91,
- braceleft = 92,
- bar = 93,
- braceright = 94,
- asciitilde = 95,
- exclamdown = 96,
- cent = 97,
- sterling = 98,
- fraction = 99,
- yen = 100,
- florin = 101,
- section = 102,
- currency = 103,
- quotedblleft = 104,
- guillemotleft = 105,
- guilsinglleft = 106,
- guilsinglright = 107,
- fi = 108,
- fl = 109,
- endash = 110,
- dagger = 111,
- daggerdbl = 112,
- periodcentered = 113,
- paragraph = 114,
- bullet = 115,
- quotesinglbase = 116,
- quotedblbase = 117,
- quotedblright = 118,
- guillemotright = 119,
- ellipsis = 120,
- perthousand = 121,
- questiondown = 122,
- grave = 123,
- acute = 124,
- circumflex = 125,
- tilde = 126,
- macron = 127,
- breve = 128,
- dotaccent = 129,
- dieresis = 130,
- ring = 131,
- cedilla = 132,
- hungarumlaut = 133,
- ogonek = 134,
- caron = 135,
- emdash = 136,
- AE = 137,
- ordfeminine = 138,
- Lslash = 139,
- Oslash = 140,
- OE = 141,
- ordmasculine = 142,
- ae = 143,
- dotlessi = 144,
- lslash = 145,
- oslash = 146,
- oe = 147,
- germandbls = 148,
- Aacute = 149,
- Acircumflex = 150,
- Adieresis = 151,
- Agrave = 152,
- Aring = 153,
- Atilde = 154,
- Ccedilla = 155,
- Eacute = 156,
- Ecircumflex = 157,
- Edieresis = 158,
- Egrave = 159,
- Eth = 160,
- Iacute = 161,
- Icircumflex = 162,
- Idieresis = 163,
- Igrave = 164,
- Ntilde = 165,
- Oacute = 166,
- Ocircumflex = 167,
- Odieresis = 168,
- Ograve = 169,
- Otilde = 170,
- Scaron = 171,
- Thorn = 172,
- Uacute = 173,
- Ucircumflex = 174,
- Udieresis = 175,
- Ugrave = 176,
- Yacute = 177,
- Ydieresis = 178,
- aacute = 179,
- acircumflex = 180,
- adieresis = 181,
- agrave = 182,
- aring = 183,
- atilde = 184,
- brokenbar = 185,
- ccedilla = 186,
- copyright = 187,
- degree = 188,
- divide = 189,
- eacute = 190,
- ecircumflex = 191,
- edieresis = 192,
- egrave = 193,
- eth = 194,
- iacute = 195,
- icircumflex = 196,
- idieresis = 197,
- igrave = 198,
- logicalnot = 199,
- minus = 200,
- multiply = 201,
- ntilde = 202,
- oacute = 203,
- ocircumflex = 204,
- odieresis = 205,
- ograve = 206,
- onehalf = 207,
- onequarter = 208,
- onesuperior = 209,
- otilde = 210,
- plusminus = 211,
- registered = 212,
- thorn = 213,
- threequarters = 214,
- threesuperior = 215,
- trademark = 216,
- twosuperior = 217,
- uacute = 218,
- ucircumflex = 219,
- udieresis = 220,
- ugrave = 221,
- yacute = 222,
- ydieresis = 223,
- Alpha = 224,
- Beta = 225,
- Chi = 226,
- Delta = 227,
- Epsilon = 228,
- Phi = 229,
- Gamma = 230,
- Eta = 231,
- Iota = 232,
- Kappa = 233,
- Lambda = 234,
- Mu = 235,
- Nu = 236,
- Omicron = 237,
- Pi = 238,
- Theta = 239,
- Rho = 240,
- Sigma = 241,
- Tau = 242,
- Upsilon = 243,
- varUpsilon = 244,
- Omega = 245,
- Xi = 246,
- Psi = 247,
- Zeta = 248,
- alpha = 249,
- beta = 250,
- chi = 251,
- delta = 252,
- epsilon = 253,
- phi = 254,
- varphi = 255,
- gamma = 256,
- eta = 257,
- iota = 258,
- kappa = 259,
- lambda = 260,
- mu = 261,
- nu = 262,
- omicron = 263,
- pi = 264,
- varpi = 265,
- theta = 266,
- vartheta = 267,
- rho = 268,
- sigma = 269,
- varsigma = 270,
- tau = 271,
- upsilon = 272,
- omega = 273,
- xi = 274,
- psi = 275,
- zeta = 276,
- nobrkspace = 277,
- nobrkhyphen = 278,
- lessequal = 279,
- greaterequal = 280,
- infinity = 281,
- integral = 282,
- notequal = 283,
- radical = 284,
- radicalex = 285,
- approxequal = 286,
- apple = 287,
- partialdiff = 288,
- opthyphen = 289,
- formula = 290,
- lozenge = 291,
- universal = 292,
- existential = 293,
- suchthat = 294,
- congruent = 295,
- therefore = 296,
- perpendicular = 297,
- minute = 298,
- club = 299,
- diamond = 300,
- heart = 301,
- spade = 302,
- arrowboth = 303,
- arrowleft = 304,
- arrowup = 305,
- arrowright = 306,
- arrowdown = 307,
- second = 308,
- proportional = 309,
- equivalence = 310,
- arrowvertex = 311,
- arrowhorizex = 312,
- carriagereturn = 313,
- aleph = 314,
- Ifraktur = 315,
- Rfraktur = 316,
- weierstrass = 317,
- circlemultiply = 318,
- circleplus = 319,
- emptyset = 320,
- intersection = 321,
- union = 322,
- propersuperset = 323,
- reflexsuperset = 324,
- notsubset = 325,
- propersubset = 326,
- reflexsubset = 327,
- element = 328,
- notelement = 329,
- angle = 330,
- gradient = 331,
- product = 332,
- logicaland = 333,
- logicalor = 334,
- arrowdblboth = 335,
- arrowdblleft = 336,
- arrowdblup = 337,
- arrowdblright = 338,
- arrowdbldown = 339,
- angleleft = 340,
- registersans = 341,
- copyrightsans = 342,
- trademarksans = 343,
- angleright = 344,
- mathplus = 345,
- mathminus = 346,
- mathasterisk = 347,
- mathnumbersign = 348,
- dotmath = 349,
- mathequal = 350,
- mathtilde = 351,
-
- MaxChar = 352
- }
-}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharName.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharName.cs
deleted file mode 100644
index 0190b798cf2..00000000000
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/StandardCharName.cs
+++ /dev/null
@@ -1,411 +0,0 @@
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
-//
-// Authors:
-// Peter Bartok (pbartok@novell.com)
-//
-//
-
-// COMPLETE
-
-namespace System.Windows.Forms.RTF {
-
-#if RTF_LIB
- public
-#else
- internal
-#endif
- class StandardCharName {
- public static string[] Names = {
- "nothing",
- "space",
- "exclam",
- "quotedbl",
- "numbersign",
- "dollar",
- "percent",
- "ampersand",
- "quoteright",
- "parenleft",
- "parenright",
- "asterisk",
- "plus",
- "comma",
- "hyphen",
- "period",
- "slash",
- "zero",
- "one",
- "two",
- "three",
- "four",
- "five",
- "six",
- "seven",
- "eight",
- "nine",
- "colon",
- "semicolon",
- "less",
- "equal",
- "greater",
- "question",
- "at",
- "A",
- "B",
- "C",
- "D",
- "E",
- "F",
- "G",
- "H",
- "I",
- "J",
- "K",
- "L",
- "M",
- "N",
- "O",
- "P",
- "Q",
- "R",
- "S",
- "T",
- "U",
- "V",
- "W",
- "X",
- "Y",
- "Z",
- "bracketleft",
- "backslash",
- "bracketright",
- "asciicircum",
- "underscore",
- "quoteleft",
- "a",
- "b",
- "c",
- "d",
- "e",
- "f",
- "g",
- "h",
- "i",
- "j",
- "k",
- "l",
- "m",
- "n",
- "o",
- "p",
- "q",
- "r",
- "s",
- "t",
- "u",
- "v",
- "w",
- "x",
- "y",
- "z",
- "braceleft",
- "bar",
- "braceright",
- "asciitilde",
- "exclamdown",
- "cent",
- "sterling",
- "fraction",
- "yen",
- "florin",
- "section",
- "currency",
- "quotedblleft",
- "guillemotleft",
- "guilsinglleft",
- "guilsinglright",
- "fi",
- "fl",
- "endash",
- "dagger",
- "daggerdbl",
- "periodcentered",
- "paragraph",
- "bullet",
- "quotesinglbase",
- "quotedblbase",
- "quotedblright",
- "guillemotright",
- "ellipsis",
- "perthousand",
- "questiondown",
- "grave",
- "acute",
- "circumflex",
- "tilde",
- "macron",
- "breve",
- "dotaccent",
- "dieresis",
- "ring",
- "cedilla",
- "hungarumlaut",
- "ogonek",
- "caron",
- "emdash",
- "AE",
- "ordfeminine",
- "Lslash",
- "Oslash",
- "OE",
- "ordmasculine",
- "ae",
- "dotlessi",
- "lslash",
- "oslash",
- "oe",
- "germandbls",
- "Aacute",
- "Acircumflex",
- "Adieresis",
- "Agrave",
- "Aring",
- "Atilde",
- "Ccedilla",
- "Eacute",
- "Ecircumflex",
- "Edieresis",
- "Egrave",
- "Eth",
- "Iacute",
- "Icircumflex",
- "Idieresis",
- "Igrave",
- "Ntilde",
- "Oacute",
- "Ocircumflex",
- "Odieresis",
- "Ograve",
- "Otilde",
- "Scaron",
- "Thorn",
- "Uacute",
- "Ucircumflex",
- "Udieresis",
- "Ugrave",
- "Yacute",
- "Ydieresis",
- "aacute",
- "acircumflex",
- "adieresis",
- "agrave",
- "aring",
- "atilde",
- "brokenbar",
- "ccedilla",
- "copyright",
- "degree",
- "divide",
- "eacute",
- "ecircumflex",
- "edieresis",
- "egrave",
- "eth",
- "iacute",
- "icircumflex",
- "idieresis",
- "igrave",
- "logicalnot",
- "minus",
- "multiply",
- "ntilde",
- "oacute",
- "ocircumflex",
- "odieresis",
- "ograve",
- "onehalf",
- "onequarter",
- "onesuperior",
- "otilde",
- "plusminus",
- "registered",
- "thorn",
- "threequarters",
- "threesuperior",
- "trademark",
- "twosuperior",
- "uacute",
- "ucircumflex",
- "udieresis",
- "ugrave",
- "yacute",
- "ydieresis",
- "Alpha",
- "Beta",
- "Chi",
- "Delta",
- "Epsilon",
- "Phi",
- "Gamma",
- "Eta",
- "Iota",
- "Kappa",
- "Lambda",
- "Mu",
- "Nu",
- "Omicron",
- "Pi",
- "Theta",
- "Rho",
- "Sigma",
- "Tau",
- "Upsilon",
- "varUpsilon",
- "Omega",
- "Xi",
- "Psi",
- "Zeta",
- "alpha",
- "beta",
- "chi",
- "delta",
- "epsilon",
- "phi",
- "varphi",
- "gamma",
- "eta",
- "iota",
- "kappa",
- "lambda",
- "mu",
- "nu",
- "omicron",
- "pi",
- "varpi",
- "theta",
- "vartheta",
- "rho",
- "sigma",
- "varsigma",
- "tau",
- "upsilon",
- "omega",
- "xi",
- "psi",
- "zeta",
- "nobrkspace",
- "nobrkhyphen",
- "lessequal",
- "greaterequal",
- "infinity",
- "integral",
- "notequal",
- "radical",
- "radicalex",
- "approxequal",
- "apple",
- "partialdiff",
- "opthyphen",
- "formula",
- "lozenge",
- "universal",
- "existential",
- "suchthat",
- "congruent",
- "therefore",
- "perpendicular",
- "minute",
- "club",
- "diamond",
- "heart",
- "spade",
- "arrowboth",
- "arrowleft",
- "arrowup",
- "arrowright",
- "arrowdown",
- "second",
- "proportional",
- "equivalence",
- "arrowvertex",
- "arrowhorizex",
- "carriagereturn",
- "aleph",
- "Ifraktur",
- "Rfraktur",
- "weierstrass",
- "circlemultiply",
- "circleplus",
- "emptyset",
- "intersection",
- "union",
- "propersuperset",
- "reflexsuperset",
- "notsubset",
- "propersubset",
- "reflexsubset",
- "element",
- "notelement",
- "angle",
- "gradient",
- "product",
- "logicaland",
- "logicalor",
- "arrowdblboth",
- "arrowdblleft",
- "arrowdblup",
- "arrowdblright",
- "arrowdbldown",
- "angleleft",
- "registersans",
- "copyrightsans",
- "trademarksans",
- "angleright",
- "mathplus",
- "mathminus",
- "mathasterisk",
- "mathnumbersign",
- "dotmath",
- "mathequal",
- "mathtilde"
- };
-
- /// <summary>Lookup name by ID</summary>
- public static string Name(int index) {
- if ((index < 0) || (index >= Names.Length)) {
- return string.Empty;
- }
-
- return Names[index];
- }
-
- /// <summary>Lookup ID by name (e.g. mathtilde)</summary>
- public static int ID(string name) {
- for (int i=0; i < Names.Length; i++) {
- if (name.Equals(Names[i])) {
- return i;
- }
- }
- return 0;
- }
- }
-}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/TextMap.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/TextMap.cs
deleted file mode 100644
index f4474b92627..00000000000
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.RTF/TextMap.cs
+++ /dev/null
@@ -1,440 +0,0 @@
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
-//
-// Authors:
-// Peter Bartok (pbartok@novell.com)
-//
-//
-
-// This map is for convencience only, any app can create/use it's own
-// StdCharCode -> <text> table
-
-using System.Collections;
-
-namespace System.Windows.Forms.RTF {
-
-#if RTF_LIB
- public
-#else
- internal
-#endif
- class TextMap {
- #region Local Variables
- private string[] table;
- #endregion // Local Variables
-
- #region Public Constructors
- public TextMap() {
- table = new string[(int)StandardCharCode.MaxChar];
-
- for (int i = 0; i < (int)StandardCharCode.MaxChar; i++) {
- table[i] = string.Empty;
- }
- }
- #endregion // Public Constructors
-
- #region Public Instance Properties
- internal string this[StandardCharCode c] { // FIXME - this should be public, if the whole namespace was public (ie standalone RTF parser)
- get {
- return table[(int)c];
- }
-
- set {
- table[(int)c] = value;
- }
- }
-
- public string[] Table {
- get {
- return table;
- }
- }
- #endregion // Public Instance Properties
-
- #region Public Static Methods
- public static void SetupStandardTable(string[] table)
- {
- /*
- table[(int)StandardCharCode.space] = " ";
- table[(int)StandardCharCode.exclam] = "!";
- table[(int)StandardCharCode.quotedbl] = "\"";
- table[(int)StandardCharCode.numbersign] = "#";
- table[(int)StandardCharCode.dollar] = "$";
- table[(int)StandardCharCode.percent] = "%";
- table[(int)StandardCharCode.ampersand] = "&";
- table[(int)StandardCharCode.quoteright] = "'";
- table[(int)StandardCharCode.parenleft] = "(";
- table[(int)StandardCharCode.parenright] = ")";
- table[(int)StandardCharCode.asterisk] = "*";
- table[(int)StandardCharCode.plus] = "+";
- table[(int)StandardCharCode.comma] = ",";
- table[(int)StandardCharCode.hyphen] = "-";
- table[(int)StandardCharCode.period] = ".";
- table[(int)StandardCharCode.slash] = "/";
- table[(int)StandardCharCode.zero] = "0";
- table[(int)StandardCharCode.one] = "1";
- table[(int)StandardCharCode.two] = "2";
- table[(int)StandardCharCode.three] = "3";
- table[(int)StandardCharCode.four] = "4";
- table[(int)StandardCharCode.five] = "5";
- table[(int)StandardCharCode.six] = "6";
- table[(int)StandardCharCode.seven] = "7";
- table[(int)StandardCharCode.eight] = "8";
- table[(int)StandardCharCode.nine] = "9";
- table[(int)StandardCharCode.colon] = ":";
- table[(int)StandardCharCode.semicolon] = ";";
- table[(int)StandardCharCode.less] = "<";
- table[(int)StandardCharCode.equal] = "=";
- table[(int)StandardCharCode.greater] = ">";
- table[(int)StandardCharCode.question] = "?";
- table[(int)StandardCharCode.at] = "@";
- table[(int)StandardCharCode.A] = "A";
- table[(int)StandardCharCode.B] = "B";
- table[(int)StandardCharCode.C] = "C";
- table[(int)StandardCharCode.D] = "D";
- table[(int)StandardCharCode.E] = "E";
- table[(int)StandardCharCode.F] = "F";
- table[(int)StandardCharCode.G] = "G";
- table[(int)StandardCharCode.H] = "H";
- table[(int)StandardCharCode.I] = "I";
- table[(int)StandardCharCode.J] = "J";
- table[(int)StandardCharCode.K] = "K";
- table[(int)StandardCharCode.L] = "L";
- table[(int)StandardCharCode.M] = "M";
- table[(int)StandardCharCode.N] = "N";
- table[(int)StandardCharCode.O] = "O";
- table[(int)StandardCharCode.P] = "P";
- table[(int)StandardCharCode.Q] = "Q";
- table[(int)StandardCharCode.R] = "R";
- table[(int)StandardCharCode.S] = "S";
- table[(int)StandardCharCode.T] = "T";
- table[(int)StandardCharCode.U] = "U";
- table[(int)StandardCharCode.V] = "V";
- table[(int)StandardCharCode.W] = "W";
- table[(int)StandardCharCode.X] = "X";
- table[(int)StandardCharCode.Y] = "Y";
- table[(int)StandardCharCode.Z] = "Z";
- table[(int)StandardCharCode.bracketleft] = "[";
- table[(int)StandardCharCode.backslash] = "\\";
- table[(int)StandardCharCode.bracketright] = "]";
- table[(int)StandardCharCode.asciicircum] = "^";
- table[(int)StandardCharCode.underscore] = "_";
- table[(int)StandardCharCode.quoteleft] = "`";
- table[(int)StandardCharCode.a] = "a";
- table[(int)StandardCharCode.b] = "b";
- table[(int)StandardCharCode.c] = "c";
- table[(int)StandardCharCode.d] = "d";
- table[(int)StandardCharCode.e] = "e";
- table[(int)StandardCharCode.f] = "f";
- table[(int)StandardCharCode.g] = "g";
- table[(int)StandardCharCode.h] = "h";
- table[(int)StandardCharCode.i] = "i";
- table[(int)StandardCharCode.j] = "j";
- table[(int)StandardCharCode.k] = "k";
- table[(int)StandardCharCode.l] = "l";
- table[(int)StandardCharCode.m] = "m";
- table[(int)StandardCharCode.n] = "n";
- table[(int)StandardCharCode.o] = "o";
- table[(int)StandardCharCode.p] = "p";
- table[(int)StandardCharCode.q] = "q";
- table[(int)StandardCharCode.r] = "r";
- table[(int)StandardCharCode.s] = "s";
- table[(int)StandardCharCode.t] = "t";
- table[(int)StandardCharCode.u] = "u";
- table[(int)StandardCharCode.v] = "v";
- table[(int)StandardCharCode.w] = "w";
- table[(int)StandardCharCode.x] = "x";
- table[(int)StandardCharCode.y] = "y";
- table[(int)StandardCharCode.z] = "z";
- table[(int)StandardCharCode.braceleft] = "{";
- table[(int)StandardCharCode.bar] = "|";
- table[(int)StandardCharCode.braceright] = "}";
- table[(int)StandardCharCode.asciitilde] = "~";
- table[(int)StandardCharCode.AE] = "AE";
- table[(int)StandardCharCode.OE] = "OE";
- table[(int)StandardCharCode.acute] = "'";
- table[(int)StandardCharCode.ae] = "ae";
- table[(int)StandardCharCode.angleleft] = "<";
- table[(int)StandardCharCode.angleright] = ">";
- table[(int)StandardCharCode.arrowboth] = "<->";
- table[(int)StandardCharCode.arrowdblboth] = "<=>";
- table[(int)StandardCharCode.arrowdblleft] = "<=";
- table[(int)StandardCharCode.arrowdblright] = "=>";
- table[(int)StandardCharCode.arrowleft] = "<-";
- table[(int)StandardCharCode.arrowright] = "->";
- table[(int)StandardCharCode.bullet] = "o";
- table[(int)StandardCharCode.cent] = "cent";
- table[(int)StandardCharCode.circumflex] = "^";
- table[(int)StandardCharCode.copyright] = "(c)";
- table[(int)StandardCharCode.copyrightsans] = "(c)";
- table[(int)StandardCharCode.degree] = "deg.";
- table[(int)StandardCharCode.divide] = "/";
- table[(int)StandardCharCode.dotlessi] = "i";
- table[(int)StandardCharCode.ellipsis] = "...";
- table[(int)StandardCharCode.emdash] = "--";
- table[(int)StandardCharCode.endash] = "-";
- table[(int)StandardCharCode.fi] = "fi";
- table[(int)StandardCharCode.fl] = "fl";
- table[(int)StandardCharCode.fraction] = "/";
- table[(int)StandardCharCode.germandbls] = "ss";
- table[(int)StandardCharCode.grave] = "`";
- table[(int)StandardCharCode.greaterequal] = ">=";
- table[(int)StandardCharCode.guillemotleft] = "<<";
- table[(int)StandardCharCode.guillemotright] = ">>";
- table[(int)StandardCharCode.guilsinglleft] = "<";
- table[(int)StandardCharCode.guilsinglright] = ">";
- table[(int)StandardCharCode.lessequal] = "<=";
- table[(int)StandardCharCode.logicalnot] = "~";
- table[(int)StandardCharCode.mathasterisk] = "*";
- table[(int)StandardCharCode.mathequal] = "=";
- table[(int)StandardCharCode.mathminus] = "-";
- table[(int)StandardCharCode.mathnumbersign] = "#";
- table[(int)StandardCharCode.mathplus] = "+";
- table[(int)StandardCharCode.mathtilde] = "~";
- table[(int)StandardCharCode.minus] = "-";
- table[(int)StandardCharCode.mu] = "u";
- table[(int)StandardCharCode.multiply] = "x";
- table[(int)StandardCharCode.nobrkhyphen] = "-";
- table[(int)StandardCharCode.nobrkspace] = "";
- table[(int)StandardCharCode.notequal] = "!=";
- table[(int)StandardCharCode.oe] = "oe";
- table[(int)StandardCharCode.onehalf] = "1/2";
- table[(int)StandardCharCode.onequarter] = "1/4";
- table[(int)StandardCharCode.periodcentered] = ".";
- table[(int)StandardCharCode.plusminus] = "+/-";
- table[(int)StandardCharCode.quotedblbase] = ",,";
- table[(int)StandardCharCode.quotedblleft] = "\"";
- table[(int)StandardCharCode.quotedblright] = "\"";
- table[(int)StandardCharCode.quotesinglbase] = ",";
- table[(int)StandardCharCode.registered] = "reg.";
- table[(int)StandardCharCode.registersans] = "reg.";
- table[(int)StandardCharCode.threequarters] = "3/4";
- table[(int)StandardCharCode.tilde] = "~";
- table[(int)StandardCharCode.trademark] = "(TM)";
- table[(int)StandardCharCode.trademarksans] = "(TM)";
-
- table[(int)StandardCharCode.aacute] = "\xE0";
- table[(int)StandardCharCode.questiondown] = "\xBF";
-
- table[(int)StandardCharCode.udieresis] = "\xFC";
- table[(int)StandardCharCode.Udieresis] = "\xDC";
- table[(int)StandardCharCode.odieresis] = "\xF6";
- table[(int)StandardCharCode.Odieresis] = "\xD6";
- */
-
- table [(int) StandardCharCode.formula] = "\x6";
- table [(int) StandardCharCode.nobrkhyphen] = "\x1e";
- table [(int) StandardCharCode.opthyphen] = "\x1f";
- table [(int) StandardCharCode.space] = " ";
- table [(int) StandardCharCode.exclam] = "!";
- table [(int) StandardCharCode.quotedbl] = "\"";
- table [(int) StandardCharCode.numbersign] = "#";
- table [(int) StandardCharCode.dollar] = "$";
- table [(int) StandardCharCode.percent] = "%";
- table [(int) StandardCharCode.ampersand] = "&";
- table [(int) StandardCharCode.parenleft] = "(";
- table [(int) StandardCharCode.parenright] = ")";
- table [(int) StandardCharCode.asterisk] = "*";
- table [(int) StandardCharCode.plus] = "+";
- table [(int) StandardCharCode.comma] = ",";
- table [(int) StandardCharCode.hyphen] = "-";
- table [(int) StandardCharCode.period] = ".";
- table [(int) StandardCharCode.slash] = "/";
- table [(int) StandardCharCode.zero] = "0";
- table [(int) StandardCharCode.one] = "1";
- table [(int) StandardCharCode.two] = "2";
- table [(int) StandardCharCode.three] = "3";
- table [(int) StandardCharCode.four] = "4";
- table [(int) StandardCharCode.five] = "5";
- table [(int) StandardCharCode.six] = "6";
- table [(int) StandardCharCode.seven] = "7";
- table [(int) StandardCharCode.eight] = "8";
- table [(int) StandardCharCode.nine] = "9";
- table [(int) StandardCharCode.colon] = ":";
- table [(int) StandardCharCode.semicolon] = ";";
- table [(int) StandardCharCode.less] = "<";
- table [(int) StandardCharCode.equal] = "=";
- table [(int) StandardCharCode.greater] = ">";
- table [(int) StandardCharCode.question] = "?";
- table [(int) StandardCharCode.at] = "@";
- table [(int) StandardCharCode.A] = "A";
- table [(int) StandardCharCode.B] = "B";
- table [(int) StandardCharCode.C] = "C";
- table [(int) StandardCharCode.D] = "D";
- table [(int) StandardCharCode.E] = "E";
- table [(int) StandardCharCode.F] = "F";
- table [(int) StandardCharCode.G] = "G";
- table [(int) StandardCharCode.H] = "H";
- table [(int) StandardCharCode.I] = "I";
- table [(int) StandardCharCode.J] = "J";
- table [(int) StandardCharCode.K] = "K";
- table [(int) StandardCharCode.L] = "L";
- table [(int) StandardCharCode.M] = "M";
- table [(int) StandardCharCode.N] = "N";
- table [(int) StandardCharCode.O] = "O";
- table [(int) StandardCharCode.P] = "P";
- table [(int) StandardCharCode.Q] = "Q";
- table [(int) StandardCharCode.R] = "R";
- table [(int) StandardCharCode.S] = "S";
- table [(int) StandardCharCode.T] = "T";
- table [(int) StandardCharCode.U] = "U";
- table [(int) StandardCharCode.V] = "V";
- table [(int) StandardCharCode.W] = "W";
- table [(int) StandardCharCode.X] = "X";
- table [(int) StandardCharCode.Y] = "Y";
- table [(int) StandardCharCode.Z] = "Z";
- table [(int) StandardCharCode.bracketleft] = "[";
- table [(int) StandardCharCode.backslash] = "\\";
- table [(int) StandardCharCode.bracketright] = "]";
- table [(int) StandardCharCode.asciicircum] = "^";
- table [(int) StandardCharCode.underscore] = "_";
- table [(int) StandardCharCode.quoteleft] = "`";
- table [(int) StandardCharCode.a] = "a";
- table [(int) StandardCharCode.b] = "b";
- table [(int) StandardCharCode.c] = "c";
- table [(int) StandardCharCode.d] = "d";
- table [(int) StandardCharCode.e] = "e";
- table [(int) StandardCharCode.f] = "f";
- table [(int) StandardCharCode.g] = "g";
- table [(int) StandardCharCode.h] = "h";
- table [(int) StandardCharCode.i] = "i";
- table [(int) StandardCharCode.j] = "j";
- table [(int) StandardCharCode.k] = "k";
- table [(int) StandardCharCode.l] = "l";
- table [(int) StandardCharCode.m] = "m";
- table [(int) StandardCharCode.n] = "n";
- table [(int) StandardCharCode.o] = "o";
- table [(int) StandardCharCode.p] = "p";
- table [(int) StandardCharCode.q] = "q";
- table [(int) StandardCharCode.r] = "r";
- table [(int) StandardCharCode.s] = "s";
- table [(int) StandardCharCode.t] = "t";
- table [(int) StandardCharCode.u] = "u";
- table [(int) StandardCharCode.v] = "v";
- table [(int) StandardCharCode.w] = "w";
- table [(int) StandardCharCode.x] = "x";
- table [(int) StandardCharCode.y] = "y";
- table [(int) StandardCharCode.z] = "z";
- table [(int) StandardCharCode.braceleft] = "{";
- table [(int) StandardCharCode.bar] = "|";
- table [(int) StandardCharCode.braceright] = "}";
- table [(int) StandardCharCode.asciitilde] = "~";
- table [(int) StandardCharCode.nobrkspace] = "\xa0";
- table [(int) StandardCharCode.exclamdown] = "\xa1";
- table [(int) StandardCharCode.cent] = "\xa2";
- table [(int) StandardCharCode.sterling] = "\xa3";
- table [(int) StandardCharCode.currency] = "\xa4";
- table [(int) StandardCharCode.yen] = "\xa5";
- table [(int) StandardCharCode.brokenbar] = "\xa6";
- table [(int) StandardCharCode.section] = "\xa7";
- table [(int) StandardCharCode.dieresis] = "\xa8";
- table [(int) StandardCharCode.copyright] = "\xa9";
- table [(int) StandardCharCode.ordfeminine] = "\xaa";
- table [(int) StandardCharCode.guillemotleft] = "\xab";
- table [(int) StandardCharCode.logicalnot] = "\xac";
- table [(int) StandardCharCode.opthyphen] = "\xad";
- table [(int) StandardCharCode.registered] = "\xae";
- table [(int) StandardCharCode.macron] = "\xaf";
- table [(int) StandardCharCode.degree] = "\xb0";
- table [(int) StandardCharCode.plusminus] = "\xb1";
- table [(int) StandardCharCode.twosuperior] = "\xb2";
- table [(int) StandardCharCode.threesuperior] = "\xb3";
- table [(int) StandardCharCode.acute] = "\xb4";
- table [(int) StandardCharCode.mu] = "\xb5";
- table [(int) StandardCharCode.paragraph] = "\xb6";
- table [(int) StandardCharCode.periodcentered] = "\xb7";
- table [(int) StandardCharCode.cedilla] = "\xb8";
- table [(int) StandardCharCode.onesuperior] = "\xb9";
- table [(int) StandardCharCode.ordmasculine] = "\xba";
- table [(int) StandardCharCode.guillemotright] = "\xbb";
- table [(int) StandardCharCode.onequarter] = "\xbc";
- table [(int) StandardCharCode.onehalf] = "\xbd";
- table [(int) StandardCharCode.threequarters] = "\xbe";
- table [(int) StandardCharCode.questiondown] = "\xbf";
- table [(int) StandardCharCode.Agrave] = "\xc0";
- table [(int) StandardCharCode.Aacute] = "\xc1";
- table [(int) StandardCharCode.Acircumflex] = "\xc2";
- table [(int) StandardCharCode.Atilde] = "\xc3";
- table [(int) StandardCharCode.Adieresis] = "\xc4";
- table [(int) StandardCharCode.Aring] = "\xc5";
- table [(int) StandardCharCode.AE] = "\xc6";
- table [(int) StandardCharCode.Ccedilla] = "\xc7";
- table [(int) StandardCharCode.Egrave] = "\xc8";
- table [(int) StandardCharCode.Eacute] = "\xc9";
- table [(int) StandardCharCode.Ecircumflex] = "\xca";
- table [(int) StandardCharCode.Edieresis] = "\xcb";
- table [(int) StandardCharCode.Igrave] = "\xcc";
- table [(int) StandardCharCode.Iacute] = "\xcd";
- table [(int) StandardCharCode.Icircumflex] = "\xce";
- table [(int) StandardCharCode.Idieresis] = "\xcf";
- table [(int) StandardCharCode.Eth] = "\xd0";
- table [(int) StandardCharCode.Ntilde] = "\xd1";
- table [(int) StandardCharCode.Ograve] = "\xd2";
- table [(int) StandardCharCode.Oacute] = "\xd3";
- table [(int) StandardCharCode.Ocircumflex] = "\xd4";
- table [(int) StandardCharCode.Otilde] = "\xd5";
- table [(int) StandardCharCode.Odieresis] = "\xd6";
- table [(int) StandardCharCode.multiply] = "\xd7";
- table [(int) StandardCharCode.Oslash] = "\xd8";
- table [(int) StandardCharCode.Ugrave] = "\xd9";
- table [(int) StandardCharCode.Uacute] = "\xda";
- table [(int) StandardCharCode.Ucircumflex] = "\xdb";
- table [(int) StandardCharCode.Udieresis] = "\xdc";
- table [(int) StandardCharCode.Yacute] = "\xdd";
- table [(int) StandardCharCode.Thorn] = "\xde";
- table [(int) StandardCharCode.germandbls] = "\xdf";
- table [(int) StandardCharCode.agrave] = "\xe0";
- table [(int) StandardCharCode.aacute] = "\xe1";
- table [(int) StandardCharCode.acircumflex] = "\xe2";
- table [(int) StandardCharCode.atilde] = "\xe3";
- table [(int) StandardCharCode.adieresis] = "\xe4";
- table [(int) StandardCharCode.aring] = "\xe5";
- table [(int) StandardCharCode.ae] = "\xe6";
- table [(int) StandardCharCode.ccedilla] = "\xe7";
- table [(int) StandardCharCode.egrave] = "\xe8";
- table [(int) StandardCharCode.eacute] = "\xe9";
- table [(int) StandardCharCode.ecircumflex] = "\xea";
- table [(int) StandardCharCode.edieresis] = "\xeb";
- table [(int) StandardCharCode.igrave] = "\xec";
- table [(int) StandardCharCode.iacute] = "\xed";
- table [(int) StandardCharCode.icircumflex] = "\xee";
- table [(int) StandardCharCode.idieresis] = "\xef";
- table [(int) StandardCharCode.eth] = "\xf0";
- table [(int) StandardCharCode.ntilde] = "\xf1";
- table [(int) StandardCharCode.ograve] = "\xf2";
- table [(int) StandardCharCode.oacute] = "\xf3";
- table [(int) StandardCharCode.ocircumflex] = "\xf4";
- table [(int) StandardCharCode.otilde] = "\xf5";
- table [(int) StandardCharCode.odieresis] = "\xf6";
- table [(int) StandardCharCode.divide] = "\xf7";
- table [(int) StandardCharCode.oslash] = "\xf8";
- table [(int) StandardCharCode.ugrave] = "\xf9";
- table [(int) StandardCharCode.uacute] = "\xfa";
- table [(int) StandardCharCode.ucircumflex] = "\xfb";
- table [(int) StandardCharCode.udieresis] = "\xfc";
- table [(int) StandardCharCode.yacute] = "\xfd";
- table [(int) StandardCharCode.thorn] = "\xfe";
- table [(int) StandardCharCode.ydieresis] = "\xff";
-
- }
- #endregion // Public Static Methods
- }
-}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.csproj b/mcs/class/System.Windows.Forms/System.Windows.Forms.csproj
index fb32cde820b..f94733d9e20 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.csproj
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.csproj
@@ -100,9 +100,7 @@
<Compile Include="System.Windows.Forms.Layout\TableLayout.cs" />
<Compile Include="System.Windows.Forms.Layout\TableLayoutSettingsTypeConverter.cs" />
<Compile Include="System.Windows.Forms.PropertyGridInternal\PropertiesTab.cs" />
- <Compile Include="System.Windows.Forms.RTF\Charcode.cs" />
- <Compile Include="System.Windows.Forms.RTF\Charset.cs" />
- <Compile Include="System.Windows.Forms.RTF\CharsetFlags.cs" />
+ <Compile Include="System.Windows.Forms.RTF\CharsetToCodepage.cs" />
<Compile Include="System.Windows.Forms.RTF\CharsetType.cs" />
<Compile Include="System.Windows.Forms.RTF\ClassDelegate.cs" />
<Compile Include="System.Windows.Forms.RTF\Color.cs" />
@@ -115,12 +113,9 @@
<Compile Include="System.Windows.Forms.RTF\Picture.cs" />
<Compile Include="System.Windows.Forms.RTF\RTF.cs" />
<Compile Include="System.Windows.Forms.RTF\RTFException.cs" />
- <Compile Include="System.Windows.Forms.RTF\StandardCharCode.cs" />
- <Compile Include="System.Windows.Forms.RTF\StandardCharName.cs" />
<Compile Include="System.Windows.Forms.RTF\Style.cs" />
<Compile Include="System.Windows.Forms.RTF\StyleElement.cs" />
<Compile Include="System.Windows.Forms.RTF\StyleType.cs" />
- <Compile Include="System.Windows.Forms.RTF\TextMap.cs" />
<Compile Include="System.Windows.Forms.RTF\TokenClass.cs" />
<Compile Include="System.Windows.Forms.Theming\Default\ButtonPainter.cs" />
<Compile Include="System.Windows.Forms.Theming\Default\CheckBoxPainter.cs" />
@@ -787,6 +782,7 @@
<Compile Include="System.Windows.Forms\TabPage.cs" />
<Compile Include="System.Windows.Forms\TabRenderer.cs" />
<Compile Include="System.Windows.Forms\TabSizeMode.cs" />
+ <Compile Include="System.Windows.Forms\TabStops.cs" />
<Compile Include="System.Windows.Forms\TableLayoutCellPaintEventArgs.cs" />
<Compile Include="System.Windows.Forms\TableLayoutCellPaintEventHandler.cs" />
<Compile Include="System.Windows.Forms\TableLayoutColumnStyleCollection.cs" />
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms.dll.sources b/mcs/class/System.Windows.Forms/System.Windows.Forms.dll.sources
index 0655e691273..235dd61bed4 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms.dll.sources
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms.dll.sources
@@ -29,9 +29,7 @@ System.Windows.Forms.Design/WindowsFormsComponentEditor.cs
System.Windows.Forms.Internal/Accessor.cs
System.Windows.Forms.Internal/DebugHelper.cs
System.Windows.Forms.PropertyGridInternal/PropertiesTab.cs
-System.Windows.Forms.RTF/Charcode.cs
-System.Windows.Forms.RTF/Charset.cs
-System.Windows.Forms.RTF/CharsetFlags.cs
+System.Windows.Forms.RTF/CharsetToCodepage.cs
System.Windows.Forms.RTF/CharsetType.cs
System.Windows.Forms.RTF/ClassDelegate.cs
System.Windows.Forms.RTF/Color.cs
@@ -44,12 +42,9 @@ System.Windows.Forms.RTF/Minor.cs
System.Windows.Forms.RTF/Picture.cs
System.Windows.Forms.RTF/RTF.cs
System.Windows.Forms.RTF/RTFException.cs
-System.Windows.Forms.RTF/StandardCharCode.cs
-System.Windows.Forms.RTF/StandardCharName.cs
System.Windows.Forms.RTF/Style.cs
System.Windows.Forms.RTF/StyleElement.cs
System.Windows.Forms.RTF/StyleType.cs
-System.Windows.Forms.RTF/TextMap.cs
System.Windows.Forms.RTF/TokenClass.cs
System.Windows.Forms.Theming/Default/LabelPainter.cs
System.Windows.Forms.Theming/Default/LinkLabelPainter.cs
@@ -657,6 +652,7 @@ System.Windows.Forms/TableLayoutRowStyleCollection.cs
System.Windows.Forms/TableLayoutSettings.cs
System.Windows.Forms/TableLayoutStyle.cs
System.Windows.Forms/TableLayoutStyleCollection.cs
+System.Windows.Forms/TabStops.cs
System.Windows.Forms/TextBox.cs
System.Windows.Forms/TextBoxBase.cs
System.Windows.Forms/TextBoxRenderer.cs
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/ContextMenuStrip.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/ContextMenuStrip.cs
index 1df14883d09..c95804739f9 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/ContextMenuStrip.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/ContextMenuStrip.cs
@@ -35,27 +35,23 @@ namespace System.Windows.Forms
[DefaultEvent ("Opening")]
public class ContextMenuStrip : ToolStripDropDownMenu
{
- Control source_control;
- internal Control container;
+ internal Control AssociatedControl;
#region Public Construtors
public ContextMenuStrip () : base ()
{
- source_control = null;
}
- public ContextMenuStrip (IContainer container) : base ()
+ public ContextMenuStrip (IContainer container) : this ()
{
- source_control = null;
+ // TODO: handle `container` argument
}
#endregion
#region Public Properties
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
- public Control SourceControl {
- get { return this.source_control; }
- }
+ public Control SourceControl { get; protected set; }
#endregion
#region Protected Methods
@@ -70,11 +66,12 @@ namespace System.Windows.Forms
if (visible)
XplatUI.SetTopmost (this.Handle, true);
}
- #endregion
- internal void SetSourceControl (Control source_control)
+ protected override void SetOwnerControl (Control control)
{
- container = this.source_control = source_control;
+ base.SetOwnerControl (control);
+ SourceControl = control;
}
+ #endregion
}
}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs
index ecd8c90e51b..53f489d751b 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/Control.cs
@@ -1406,8 +1406,7 @@ namespace System.Windows.Forms
if (background_image == null) {
if (!tbstyle_flat) {
Rectangle paintRect = pevent.ClipRectangle;
- Brush pen = ThemeEngine.Current.ResPool.GetSolidBrush(BackColor);
- pevent.Graphics.FillRectangle(pen, paintRect);
+ pevent.Graphics.FillRectangle(BackColorBrush, paintRect);
}
return;
}
@@ -1417,8 +1416,8 @@ namespace System.Windows.Forms
void DrawBackgroundImage (Graphics g) {
Rectangle drawing_rectangle = new Rectangle ();
- g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), ClientRectangle);
-
+ g.FillRectangle (BackColorBrush, ClientRectangle);
+
switch (backgroundimage_layout)
{
case ImageLayout.Tile:
@@ -2426,7 +2425,7 @@ namespace System.Windows.Forms
if (this.context_menu_strip != value) {
this.context_menu_strip = value;
if (value != null)
- value.container = this;
+ value.AssociatedControl = this;
OnContextMenuStripChanged (EventArgs.Empty);
}
}
@@ -3469,6 +3468,8 @@ namespace System.Windows.Forms
}
}
+ protected SolidBrush BackColorBrush => ThemeEngine.Current.ResPool.GetSolidBrush (BackColor);
+
#endregion // Protected Instance Properties
#region Public Static Methods
@@ -5497,22 +5498,21 @@ namespace System.Windows.Forms
return;
}
- // If there isn't a regular context menu, show the Strip version
- if (context_menu == null && context_menu_strip != null) {
- Point pt;
+ // If there isn't a regular context menu, show the Strip version
+ if (context_menu == null && context_menu_strip != null) {
+ Point pt;
- pt = new Point (LowOrder ((int)m.LParam.ToInt32 ()), HighOrder ((int)m.LParam.ToInt32 ()));
-
- if (pt.X == -1 || pt.Y == -1) {
- pt.X = (this.Width / 2) + this.Left;
- pt.Y = (this.Height /2) + this.Top;
- pt = this.PointToScreen (pt);
- }
-
- context_menu_strip.SetSourceControl (this);
- context_menu_strip.Show (this, PointToClient (pt));
- return;
+ pt = new Point (LowOrder ((int)m.LParam.ToInt32 ()), HighOrder ((int)m.LParam.ToInt32 ()));
+
+ if (pt.X == -1 || pt.Y == -1) {
+ pt.X = (this.Width / 2) + this.Left;
+ pt.Y = (this.Height /2) + this.Top;
+ pt = this.PointToScreen (pt);
}
+
+ context_menu_strip.Show (this, PointToClient (pt));
+ return;
+ }
DefWndProc(ref m);
}
@@ -6499,7 +6499,6 @@ namespace System.Windows.Forms
remove { Events.RemoveHandler (ContextMenuStripChangedEvent, value);}
}
-
[EditorBrowsable(EditorBrowsableState.Advanced)]
[Browsable(true)]
public event ControlEventHandler ControlAdded {
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/ControlPaint.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/ControlPaint.cs
index 4004c1ec8ec..5a933f1dc10 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/ControlPaint.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/ControlPaint.cs
@@ -370,11 +370,11 @@ namespace System.Windows.Forms {
ThemeEngine.Current.CPDrawContainerGrabHandle (graphics, bounds);
}
- public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle) {
+ public static void DrawFocusRectangle(Graphics graphics, Rectangle rectangle) {
DrawFocusRectangle(graphics, rectangle, SystemColors.Control, SystemColors.ControlText);
}
- public static void DrawFocusRectangle( Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) {
+ public static void DrawFocusRectangle(Graphics graphics, Rectangle rectangle, Color foreColor, Color backColor) {
ThemeEngine.Current.CPDrawFocusRectangle (graphics, rectangle, foreColor, backColor);
}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs
index 7f032754f70..fcd95416024 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/Form.cs
@@ -201,7 +201,11 @@ namespace System.Windows.Forms {
internal override void UpdateWindowText ()
{
+ var old_clientsize = ClientSize;
+
if (!IsHandleCreated) {
+ if (is_clientsize_set)
+ ClientSize = old_clientsize;
return;
}
@@ -213,6 +217,9 @@ namespace System.Windows.Forms {
}
XplatUI.Text (Handle, Text.Replace (Environment.NewLine, string.Empty));
+
+ if (ClientSize != old_clientsize)
+ ClientSize = old_clientsize;
}
internal void SelectActiveControl ()
@@ -236,7 +243,7 @@ namespace System.Windows.Forms {
this.is_visible = visible;
} else {
- Select (ActiveControl);
+ SendControlFocus (ActiveControl);
}
}
@@ -596,7 +603,7 @@ namespace System.Windows.Forms {
set {
if (control_box != value) {
control_box = value;
- UpdateStyles();
+ UpdateFormStyles();
}
}
}
@@ -662,15 +669,10 @@ namespace System.Windows.Forms {
window_manager.UpdateBorderStyle (value);
}
- Size current_client_size = ClientSize;
- UpdateStyles();
+ UpdateFormStyles();
- if (this.IsHandleCreated) {
- this.Size = InternalSizeFromClientSize (current_client_size);
+ if (this.IsHandleCreated)
XplatUI.InvalidateNC (this.Handle);
- } else if (is_clientsize_set) {
- this.Size = InternalSizeFromClientSize (current_client_size);
- }
}
}
@@ -1124,7 +1126,7 @@ namespace System.Windows.Forms {
set {
if (this.show_icon != value ) {
this.show_icon = value;
- UpdateStyles ();
+ UpdateFormStyles ();
if (IsHandleCreated) {
XplatUI.SetIcon (this.Handle, value == true ? this.Icon : null);
@@ -2197,7 +2199,7 @@ namespace System.Windows.Forms {
if (keyData == Keys.Enter) {
IntPtr window = XplatUI.GetFocus ();
Control c = Control.FromHandle (window);
- if (c is Button && c.FindForm () == this) {
+ if (c is Button && c.Visible && c.Enabled && c.FindForm () == this) {
((Button)c).PerformClick ();
return true;
}
@@ -2894,6 +2896,13 @@ namespace System.Windows.Forms {
is_loaded = true;
}
+ private void UpdateFormStyles() {
+ var old_clientsize = ClientSize;
+ UpdateStyles();
+ if ((!IsHandleCreated && is_clientsize_set) || ClientSize != old_clientsize)
+ ClientSize = old_clientsize;
+ }
+
private void UpdateMinMax()
{
var min_size = AutoSize ? new Size (Math.Max (minimum_auto_size.Width, minimum_size.Width), Math.Max (minimum_auto_size.Height, minimum_size.Height)) : minimum_size;
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/Line.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/Line.cs
index d169d9adfd2..f7f063a8b70 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/Line.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/Line.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok pbartok@novell.com
+// Karl Scowen <contact@scowencomputers.co.nz>
//
//
@@ -44,14 +45,20 @@ namespace System.Windows.Forms
internal int line_no; // Line number
internal LineTag tags; // Tags describing the text
internal int offset; // Baseline can be on the X or Y axis depending if we are in multiline mode or not
- internal int height; // Height of the line (height of tallest tag)
- internal int ascent; // Ascent of the line (ascent of the tallest tag)
+ internal int height; // Total height of the line, including TotalParagraphSpacing and LineSpacing
+ private int textHeight; // Height of the line without spacing.
+ internal int ascent; // Ascent of the line (highest distance above the baseline, including character offset)
internal HorizontalAlignment alignment; // Alignment of the line
internal int align_shift; // Pixel shift caused by the alignment
- internal int indent; // Left indent for the first line
- internal int hanging_indent; // Hanging indent (left indent for all but the first line)
- internal int right_indent; // Right indent for all lines
+ internal float indent; // Left indent for the first line
+ internal float hanging_indent; // Hanging indent (difference between first line indent and other lines)
+ internal float right_indent; // Right indent for all lines
internal LineEnding ending;
+ internal float spacing_before;
+ internal float spacing_after;
+ internal float line_spacing;
+ internal bool line_spacing_multiple;
+ internal TabStopCollection tab_stops; // Custom tabstops for this paragraph.
// Stuff that's important for the tree
internal Line parent; // Our parent line
@@ -86,10 +93,11 @@ namespace System.Windows.Forms
text = new StringBuilder (Text, space);
line_no = LineNo;
this.ending = ending;
+ tab_stops = new TabStopCollection();
widths = new float[space + 1];
-
+
tags = new LineTag(this, 1);
tags.Font = font;
tags.Color = color;
@@ -103,6 +111,7 @@ namespace System.Windows.Forms
line_no = LineNo;
this.ending = ending;
alignment = align;
+ tab_stops = new TabStopCollection();
widths = new float[space + 1];
@@ -112,6 +121,38 @@ namespace System.Windows.Forms
tags.Color = color;
}
+ internal Line (Document document, int LineNo, string Text, HorizontalAlignment align, Font font, Color color,
+ Color back_color, TextPositioning text_position, float char_offset, float left_indent, float hanging_indent,
+ float right_indent, float spacing_before, float spacing_after, float line_spacing, bool line_spacing_multiple,
+ TabStopCollection tab_stops, bool visible, LineEnding ending) : this(document, ending)
+ {
+ space = Text.Length > DEFAULT_TEXT_LEN ? Text.Length+1 : DEFAULT_TEXT_LEN;
+
+ text = new StringBuilder (Text, space);
+ line_no = LineNo;
+ this.ending = ending;
+ alignment = align;
+ indent = left_indent;
+ HangingIndent = hanging_indent;
+ this.right_indent = right_indent;
+ this.spacing_before = spacing_before;
+ this.spacing_after = spacing_after;
+ this.tab_stops = tab_stops;
+ this.line_spacing = line_spacing;
+ this.line_spacing_multiple = line_spacing_multiple;
+
+ widths = new float[space + 1];
+
+
+ tags = new LineTag(this, 1);
+ tags.Font = font;
+ tags.Color = color;
+ tags.BackColor = back_color;
+ tags.TextPosition = text_position;
+ tags.CharOffset = char_offset;
+ tags.Visible = visible;
+ }
+
internal Line (Document document, int LineNo, string Text, LineTag tag, LineEnding ending) : this(document, ending)
{
space = Text.Length > DEFAULT_TEXT_LEN ? Text.Length+1 : DEFAULT_TEXT_LEN;
@@ -137,10 +178,10 @@ namespace System.Windows.Forms
}
}
- internal int HangingIndent {
+ internal float HangingIndent {
get { return hanging_indent; }
set {
- hanging_indent = value;
+ this.hanging_indent = value;
recalc = true;
}
}
@@ -151,7 +192,63 @@ namespace System.Windows.Forms
set { height = value; }
}
- internal int Indent {
+ internal int TextHeight {
+ get {
+ return textHeight;
+ }
+ }
+
+ internal TabStopCollection TabStops {
+ get { return tab_stops; }
+ set { tab_stops = value; }
+ }
+
+ internal float TotalParagraphSpacing {
+ get {
+ return SpacingBefore + SpacingAfter;
+ }
+ }
+
+ internal float LineSpacing {
+ get {
+ if (textHeight == 0) {
+ throw new InvalidOperationException("Can't get LineSpacing when the line height isn't calculated!");
+ }
+ if (line_spacing < 0) {
+ return -line_spacing;
+ } else if (line_spacing_multiple) {
+ return line_spacing * textHeight * 6f / document.Dpi;
+ } else {
+ return Math.Max(line_spacing, textHeight);
+ }
+ }
+ }
+
+ internal float SpacingBefore {
+ get {
+ bool has_spacing = true;
+ if (line_no > 1) {
+ Line previous_line = document.GetLine(line_no - 1);
+ if (previous_line != null && (previous_line.ending == LineEnding.Wrap || previous_line.ending == LineEnding.None))
+ has_spacing = false;
+ }
+ if (has_spacing)
+ return spacing_before;
+ else
+ return 0;
+ }
+ }
+
+ internal float SpacingAfter {
+ get {
+ if (ending == LineEnding.Wrap)
+ return 0;
+ else
+ return spacing_after;
+ }
+ }
+
+ internal float Indent {
get { return indent; }
set {
indent = value;
@@ -164,7 +261,7 @@ namespace System.Windows.Forms
set { line_no = value; }
}
- internal int RightIndent {
+ internal float RightIndent {
get { return right_indent; }
set {
right_indent = value;
@@ -254,7 +351,7 @@ namespace System.Windows.Forms
return;
// Find the first tag that we are deleting from
- tag = FindTag (pos + 1);
+ tag = FindTag (pos);
// Remove the characters from the line
text.Remove (pos, count);
@@ -271,10 +368,10 @@ namespace System.Windows.Forms
left = count;
left -= tag.Start + tag.Length - pos - 1;
- tag = tag.Next;
// Update the start of each tag
- while ((tag != null) && (left > 0)) {
+ while ((tag.Next != null) && (left > 0)) {
+ tag = tag.Next;
// Cache tag.Length as is will be indireclty modified
// by changes to tag.Start
int tag_length = tag.Length;
@@ -284,7 +381,6 @@ namespace System.Windows.Forms
left = 0;
} else {
left -= tag_length;
- tag = tag.Next;
}
}
@@ -295,15 +391,7 @@ namespace System.Windows.Forms
streamline = true;
}
- // Delete empty orphaned tags at the end
LineTag walk = tag;
- while (walk != null && walk.Next != null && walk.Next.Length == 0) {
- LineTag t = walk;
- walk.Next = walk.Next.Next;
- if (walk.Next != null)
- walk.Next.Previous = t;
- walk = walk.Next;
- }
// Adjust the start point of any tags following
if (tag != null) {
@@ -314,6 +402,15 @@ namespace System.Windows.Forms
}
}
+ // Delete empty orphaned tags at the end. Do this after adjusting their starts, otherwise we might delete tags that acutally do have content.
+ while (walk != null && walk.Next != null && walk.Next.Length == 0) {
+ LineTag t = walk;
+ walk.Next = walk.Next.Next;
+ if (walk.Next != null)
+ walk.Next.Previous = t;
+ walk = walk.Next;
+ }
+
recalc = true;
if (streamline)
@@ -361,7 +458,7 @@ namespace System.Windows.Forms
pos = text.Length - 1;
while (tag != null) {
- if (((tag.Start - 1) <= pos) && (pos <= (tag.Start + tag.Length - 1)))
+ if (((tag.Start - 1) <= pos) && (pos < (tag.Start + tag.Length - 1)))
return LineTag.GetFinalTag (tag);
tag = tag.Next;
@@ -434,6 +531,33 @@ namespace System.Windows.Forms
// Insert the text into the StringBuilder
text.Insert (pos, s);
+ // Check that tag is still in use in the line. If not, then we choose the last tag at that position.
+ LineTag t = tags;
+ while (t != null) {
+ if (((t.Start - 1) <= pos) && (pos < (t.End - 1) || (pos == t.End - 1 && t.Length == 0))) {
+ // found the location
+ bool foundTag = false;
+ while (pos < (t.Start + t.Length - 1)) {
+ if (t == tag) {
+ foundTag = true;
+ break;
+ }
+ if (t.Next == null)
+ break;
+ t = t.Next;
+ }
+ if (!foundTag) {
+ if (pos < (t.Start + t.Length - 1)) {
+ tag = t.Previous;
+ } else {
+ tag = t;
+ }
+ }
+ break;
+ }
+ t = t.Next;
+ }
+
// Update the start position of every tag after this one
tag = tag.Next;
@@ -455,55 +579,94 @@ namespace System.Windows.Forms
/// </summary>
internal bool RecalculateLine (Graphics g, Document doc)
{
- return RecalculateLine (g, doc, kerning_fonts.ContainsKey (tags.Font.GetHashCode ()));
- }
-
- private bool RecalculateLine (Graphics g, Document doc, bool handleKerning)
- {
LineTag tag;
int pos;
int len;
+ Font currentFont;
+ int currentFontStart;
SizeF size;
float w;
int prev_offset;
bool retval;
bool wrapped;
+ bool first_in_para;
Line line;
int wrap_pos;
+ int prev_wrap_pos;
int prev_height;
int prev_ascent;
- float add_width;
+ float prev_spacing_before;
+ int max_above_baseline;
+ int max_below_baseline;
+ int total_ascent;
+ int total_descent;
+ TabStop lastTab;
+ int lastTabPos;
+ char c;
+ bool handleKerning;
+ float right_indent;
pos = 0;
len = this.text.Length;
+ currentFont = tags.FontToDisplay;
+ currentFontStart = 0;
tag = this.tags;
prev_offset = this.offset; // For drawing optimization calculations
prev_height = this.height;
prev_ascent = this.ascent;
+ prev_spacing_before = this.SpacingBefore;
+ max_above_baseline = 0;
+ max_below_baseline = 0;
+ total_ascent = 0;
+ total_descent = 0;
+ lastTab = null;
+ lastTabPos = 0;
this.height = 0; // Reset line height
this.ascent = 0; // Reset the ascent for the line
tag.Shift = 0; // Reset shift (which should be stored as pixels, not as points)
+ right_indent = Math.Max(this.right_indent, 0); // Ignore any negative right indent.
- if (ending == LineEnding.Wrap)
- widths[0] = document.left_margin + hanging_indent;
+ if (line_no > 0) {
+ line = doc.GetLine (LineNo - 1);
+ first_in_para = line != null && line.ending != LineEnding.Wrap;
+ } else {
+ first_in_para = true;
+ }
+
+ if (first_in_para)
+ widths [0] = indent;
else
- widths[0] = document.left_margin + indent;
+ widths [0] = indent + hanging_indent;
+
+ if (widths [0] < 0)
+ widths [0] = 0; // Don't allow a negative indent to take the line to a negative position.
+
+ widths [0] += document.left_margin;
this.recalc = false;
retval = false;
wrapped = false;
wrap_pos = 0;
- add_width = 0;
+ prev_wrap_pos = 0;
- while (pos < len) {
+ handleKerning = kerning_fonts.ContainsKey (currentFont.GetHashCode ());
+ while (pos < len) {
while (tag.Length == 0) { // We should always have tags after a tag.length==0 unless len==0
//tag.Ascent = 0;
- tag.Shift = (tag.Line.ascent - tag.Ascent) / 72;
+ tag.Shift = (tag.Line.ascent - tag.Ascent); // / 72;
tag = tag.Next;
+ if (tag.Length != 0 && tag.FontToDisplay != currentFont) {
+ CheckKerning (g, currentFont, currentFontStart, pos - currentFontStart);
+ currentFont = tag.FontToDisplay;
+ currentFontStart = pos;
+ handleKerning = kerning_fonts.ContainsKey (currentFont.GetHashCode ());
+ }
}
+ c = text [pos];
+
// kerning is a problem. The original code in this method assumed that the
// width of a string equals the sum of the widths of its characters. This is
// not true when kerning takes place during the display process. Since it's
@@ -520,44 +683,103 @@ namespace System.Windows.Forms
// MeasureText doesn't measure trailing spaces, so we do the best we can for those
// in the else branch.
// It doesn't measure /t characters either, we need to add it manually with add_width.
- size = TextBoxTextRenderer.MeasureText (g, text.ToString (0, pos + 1), tag.Font);
- newWidth = widths[0] + size.Width + add_width;
+ size = TextBoxTextRenderer.MeasureText (g, text.ToString (currentFontStart, pos + 1 - currentFontStart), currentFont);
+ newWidth = widths [currentFontStart] + size.Width;
}
- else
- {
+ else if (c != '\t') {
size = tag.SizeOfPosition (g, pos);
w = size.Width;
newWidth = widths[pos] + w;
- if (text[pos] == '\t') add_width += w;
+ } else {
+ CheckKerning (g, currentFont, currentFontStart, pos - currentFontStart);
+ currentFontStart = pos + 1; // Don't try handling the tab along with kerned text.
+
+ if (lastTab != null) {
+ ProcessLastTab (lastTab, lastTabPos, pos);
+ lastTab = null;
+ }
+
+ float l = widths [pos];
+ w = -1;
+ for (int i = 0; i < tab_stops.Count; i++) {
+ if (tab_stops [i].Position > l) {
+ lastTab = tab_stops [i];
+ lastTabPos = pos;
+ w = lastTab.GetInitialWidth (this, pos);
+ break;
+ }
+ }
+
+ if (w < 0) {
+ w = tag.SizeOfPosition (g, pos).Width;
+ }
+
+ newWidth = widths [pos] + w;
}
- if (Char.IsWhiteSpace (text[pos]))
- wrap_pos = pos + 1;
-
- if (doc.wrap) {
- if ((wrap_pos > 0) && (wrap_pos != len) && (newWidth + 5) > (doc.viewport_width - this.right_indent)) {
- // Make sure to set the last width of the line before wrapping
- widths[pos + 1] = newWidth;
-
- pos = wrap_pos;
- len = text.Length;
- doc.Split (this, tag, pos);
- ending = LineEnding.Wrap;
- len = this.text.Length;
-
- retval = true;
- wrapped = true;
- } else if (pos > 1 && newWidth > (doc.viewport_width - this.right_indent)) {
- // No suitable wrap position was found so break right in the middle of a word
-
- // Make sure to set the last width of the line before wrapping
- widths[pos + 1] = newWidth;
-
- doc.Split (this, tag, pos);
- ending = LineEnding.Wrap;
- len = this.text.Length;
- retval = true;
- wrapped = true;
+ if (doc.Wrap) {
+ // FIXME: Technically there are multiple no-break spaces, not just the main one.
+ if ((Char.IsWhiteSpace (c) && c != '\u00A0') || c == '-' || c == '\u2013' || c == '\u2014') {
+ // Primarily break on dashes or whitespace other than a no-break space.
+ prev_wrap_pos = wrap_pos;
+ if (c == '\t') {
+ wrap_pos = pos; // Wrap before tabs for some reason.
+ } else {
+ wrap_pos = pos + 1;
+ }
+ }
+
+ if (newWidth > (doc.viewport_width - this.right_indent)) {
+ LineTag split_tag = null;
+ if (wrap_pos > 0) {
+ // Make sure to set the last width of the line before wrapping
+ widths [pos + 1] = newWidth;
+
+ if (Char.IsWhiteSpace (c)) {
+ if (wrap_pos > pos) {
+ while (wrap_pos < text.Length && Char.IsWhiteSpace (text [wrap_pos]) && text [wrap_pos] != '\t') {
+ wrap_pos++;
+ }
+ pos++;
+ wrapped = true;
+ // don't try pulling more into this line, but keep looping to deal with the rest of the widths and tags
+ }
+ } else {
+ if (wrap_pos > pos && pos > 0) {
+ // We're at a dash (otherwise we'd be above), but don't have room to fit it in.
+ // Wrap at the previous wrap point if possible.
+ wrap_pos = prev_wrap_pos > 0 ? prev_wrap_pos : pos;
+ }
+ split_tag = tag;
+ pos = wrap_pos;
+ }
+ } else if (pos > 0) {
+ // No suitable wrap position was found so break right in the middle of a word
+
+ // Make sure to set the last width of the line before wrapping
+ widths [pos + 1] = newWidth;
+
+ split_tag = tag;
+ } // Else don't wrap -- pos == 0, so we'd infinite loop adding blank lines before this.
+
+ if (split_tag != null) {
+ if (lastTab != null) {
+ ProcessLastTab (lastTab, lastTabPos, pos);
+ lastTab = null;
+ }
+
+ while (pos < split_tag.Start)
+ split_tag = split_tag.Previous;
+ // We have to pass Split the correct tag, and that can change if pos
+ // is set somewhere before the tag change (e.g. by wrap_pos).
+
+ doc.Split (this, split_tag, pos);
+ ending = LineEnding.Wrap;
+ len = this.text.Length;
+
+ retval = true;
+ wrapped = true;
+ }
}
}
@@ -569,12 +791,23 @@ namespace System.Windows.Forms
if (pos == len) {
line = doc.GetLine (this.line_no + 1);
- if ((line != null) && (ending == LineEnding.Wrap || ending == LineEnding.None)) {
- // Pull the two lines together
- doc.Combine (this.line_no, this.line_no + 1);
- len = this.text.Length;
- retval = true;
- }
+ do {
+ if ((line != null) && (ending == LineEnding.Wrap || ending == LineEnding.None) &&
+ (widths[pos] < (doc.viewport_width - this.right_indent) || line.text.Length == 0)) {
+ // Pull the two lines together
+ // Only do this if the line isn't already full, or the next line is empty.
+ var h = this.height; // Back up h, because Combine sets it to zero.
+ doc.Combine (this, line);
+ this.height = h; // And restore it. There's no point starting at the start again.
+ // Document.Combine() called Line.Streamline(), so it is possible tag points a tag that got removed.
+ tag = FindTag (pos - 1); // So make sure we've got the correct tag.
+ len = this.text.Length;
+ line = doc.GetLine (this.line_no + 1);
+ retval = true;
+ }
+ } while ((ending == LineEnding.Wrap || ending == LineEnding.None) && line != null && line.text.Length == 0);
+ // If the next line is empty, do it again (if possible).
+ // The amount of room on this line doesn't matter when there's no text being added...
}
}
@@ -582,54 +815,63 @@ namespace System.Windows.Forms
// We just found the end of our current tag
tag.Height = tag.MaxHeight ();
- // Check if we're the tallest on the line (so far)
- if (tag.Height > this.height)
- this.height = tag.Height; // Yep; make sure the line knows
-
- if (tag.Ascent > this.ascent) {
- LineTag t;
-
- // We have a tag that has a taller ascent than the line;
- t = tags;
+ /* line.ascent is the highest point above the baseline.
+ * total_ascent will equal the maximum distance of the tag above the baseline.
+ * total_descent is needed to calculate the line height.
+ * tag.Shift does not include tag.CharOffset, because Shift puts the tag
+ * on the baseline, while CharOffset moves the baseline.
+ * However, we move the normal baseline when CharOffset is trying to push
+ * stuff off the top.
+ */
+ total_ascent = tag.Ascent + (int)tag.CharOffset;
+ total_descent = tag.Descent - (int)tag.CharOffset; // gets bigger as CharOffset gets smaller
+ if (total_ascent > max_above_baseline) {
+ int moveBy = total_ascent - max_above_baseline;
+ max_above_baseline = total_ascent;
+
+ LineTag t = tags;
while (t != null && t != tag) {
- t.Shift = (tag.Ascent - t.Ascent) / 72;
+ t.Shift += moveBy;
t = t.Next;
}
- // Save on our line
- this.ascent = tag.Ascent;
+ tag.Shift = (int)tag.CharOffset;
+ this.ascent = max_above_baseline;
} else {
- tag.Shift = (this.ascent - tag.Ascent) / 72;
+ tag.Shift = (this.ascent - tag.Ascent);
}
+ if (total_descent > max_below_baseline)
+ max_below_baseline = total_descent;
+
+ if (this.height < max_above_baseline + max_below_baseline + tag.Height - tag.Ascent - tag.Descent)
+ this.height = max_above_baseline + max_below_baseline + tag.Height - tag.Ascent - tag.Descent;
+
tag = tag.Next;
if (tag != null) {
+ if (tag.Length != 0 && tag.FontToDisplay != currentFont) {
+ CheckKerning (g, currentFont, currentFontStart, pos - currentFontStart);
+ currentFont = tag.FontToDisplay;
+ currentFontStart = pos;
+ handleKerning = kerning_fonts.ContainsKey (currentFont.GetHashCode ());
+ }
tag.Shift = 0;
- wrap_pos = pos;
+ // We can't just wrap on tag boundaries -- e.g. if the first letter of the word has a different colour / font.
}
}
}
- var fullText = text.ToString();
- if (!handleKerning && fullText.Length > 1 && !wrapped)
- {
- // Check whether kerning takes place for this string and font.
- var realSize = TextBoxTextRenderer.MeasureText(g, fullText, tags.Font);
- float realWidth = realSize.Width + widths[0];
- // MeasureText ignores trailing whitespace, so we will too at this point.
- int length = fullText.TrimEnd().Length;
- float sumWidth = widths[length];
- if (realWidth != sumWidth)
- {
- kerning_fonts.Add(tags.Font.GetHashCode (), true);
- // Using a slightly incorrect width this time around isn't that bad. All that happens
- // is that the cursor is a pixel or two off until the next character is typed. It's
- // the accumulation of pixel after pixel that causes display problems.
- }
+ if (pos != currentFontStart) {
+ CheckKerning (g, currentFont, currentFontStart, pos - currentFontStart);
}
- while (tag != null) {
- tag.Shift = (tag.Line.ascent - tag.Ascent) / 72;
+ if (lastTab != null) {
+ ProcessLastTab (lastTab, lastTabPos, pos);
+ lastTab = null;
+ }
+
+ while (tag != null) {
+ tag.Shift = (tag.Line.ascent - tag.Ascent); // / 72;
tag = tag.Next;
}
@@ -639,12 +881,49 @@ namespace System.Windows.Forms
tags.Shift = 0;
}
- if (prev_offset != offset || prev_height != this.height || prev_ascent != this.ascent)
+ this.textHeight = this.height;
+ this.height = (int)(this.LineSpacing + this.TotalParagraphSpacing);
+
+ if (prev_offset != offset || prev_height != this.height || prev_ascent != this.ascent ||
+ Math.Abs (prev_spacing_before - this.SpacingBefore) > document.Dpi / 1440f)
retval = true;
return retval;
}
+ private void ProcessLastTab (TabStop tab, int tab_pos, int pos)
+ {
+ float prevTabRight = widths[tab_pos + 1];
+ float tabRight = tab.CalculateRight (this, tab_pos);
+ float change = tabRight - prevTabRight;
+
+ for (int i = tab_pos + 1; i <= pos; i++) {
+ widths[i] += change;
+ }
+ }
+
+ private void CheckKerning (Graphics g, Font font, int start, int length)
+ {
+ if (length > 1) {
+ if (!kerning_fonts.ContainsKey (font.GetHashCode ())) {
+ // Check whether kerning takes place for this string and font.
+ var partText = text.ToString(start, length);
+ var realSize = TextBoxTextRenderer.MeasureText(g, partText, font);
+ float realWidth = realSize.Width + widths[start + 1];
+ // MeasureText ignores trailing whitespace, so we will too at this point.
+ int textLength = partText.TrimEnd().Length;
+ float sumWidth = widths[textLength + start + 1];
+ if (realWidth != sumWidth)
+ {
+ kerning_fonts.Add(font.GetHashCode (), true);
+ // Using a slightly incorrect width this time around isn't that bad. All that happens
+ // is that the cursor is a pixel or two off until the next character is typed. It's
+ // the accumulation of pixel after pixel that causes display problems.
+ }
+ }
+ }
+ }
+
/// <summary>
/// Recalculate a single line using the same char for every character in the line
/// </summary>
@@ -667,13 +946,14 @@ namespace System.Windows.Forms
w = TextBoxTextRenderer.MeasureText (g, doc.password_char, tags.Font).Width;
- if (this.height != (int)tag.Font.Height)
+ if (this.textHeight != (int)tag.Font.Height)
ret = true;
else
ret = false;
- this.height = (int)tag.Font.Height;
- tag.Height = this.height;
+ this.textHeight = (int)tag.Font.Height;
+ tag.Height = this.textHeight;
+ this.height = (int)(this.textHeight + this.LineSpacing + this.TotalParagraphSpacing);
this.ascent = tag.Ascent;
@@ -684,7 +964,42 @@ namespace System.Windows.Forms
return ret;
}
-
+
+ internal void CalculateAlignment ()
+ {
+ var alignmentWidth = document.ViewPortWidth - document.left_margin - document.right_margin;
+ var alignmentLineWidth = GetAlignmentLineWidth ();
+
+ switch (alignment) {
+ case HorizontalAlignment.Left:
+ align_shift = 0;
+ break;
+ case HorizontalAlignment.Center:
+ align_shift = (alignmentWidth - alignmentLineWidth) / 2;
+ break;
+ case HorizontalAlignment.Right:
+ align_shift = alignmentWidth - alignmentLineWidth;
+ break;
+ }
+
+ align_shift = Math.Max (align_shift, 0); // Don't allow negative shifts.
+ }
+
+ private int GetAlignmentLineWidth ()
+ {
+ int last = text.Length - 1;
+ if (last < 0)
+ return 0;
+
+ char c = text [last];
+ while (last > 0 && Char.IsWhiteSpace (c) && c != '\t' && c != '\u00A0') {
+ c = text [--last];
+ }
+ // widths[0] has both the left margin and the left indents.
+ // Remove the margin (it is part of the viewport) and add the right indents (part of the line width, for alignment purposes).
+ return (int)(widths [last + 1] - document.left_margin + Math.Max (right_indent, 0));
+ }
+
internal void Streamline (int lines)
{
LineTag current;
@@ -711,7 +1026,7 @@ namespace System.Windows.Forms
return;
while (next != null) {
- // Take out 0 length tags unless it's the last tag in the document
+ // Take out 0 length tags unless it's the last tag in the document.
if (current.IsTextTag && next.Length == 0 && next.IsTextTag) {
if ((next.Next != null) || (line_no != lines)) {
current.Next = next.Next;
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/LineTag.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/LineTag.cs
index a551e813de9..38e5bb58dd5 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/LineTag.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/LineTag.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok pbartok@novell.com
+// Karl Scowen <contact@scowencomputers.co.nz>
//
//
@@ -44,6 +45,10 @@ namespace System.Windows.Forms
private string link_text; // The full link text e.g. this might be
// word-wrapped to "w" but this would be
// "www.example.com"
+ private bool visible;
+ private TextPositioning text_position; // Normal / superscript / subscript
+ private Font small_font; // Cached font for superscript / subscript
+ private float char_offset; // Shift the text baseline up or down
// Payload; text
private int start; // start, in chars; index into Line.text
@@ -53,7 +58,8 @@ namespace System.Windows.Forms
private int height; // Height in pixels of the text this tag describes
private int ascent; // Ascent of the font for this tag
private int descent; // Descent of the font for this tag
- private int shift; // Shift down for this tag, to stay on baseline
+ private int shift; // Shift down for this tag, to stay on baseline.
+ // Measured from top of line to top of tag.
// Administrative
private Line line; // The line we're on
@@ -69,6 +75,7 @@ namespace System.Windows.Forms
link_font = null;
is_link = false;
link_text = null;
+ visible = true;
}
#endregion // Constructors
@@ -113,6 +120,16 @@ namespace System.Windows.Forms
return link_font;
}
+ if (TextPosition != TextPositioning.Normal) {
+ if (small_font == null)
+ small_font = new Font (font.FontFamily, font.Size * 0.583F, font.Style);
+
+ if (IsLink)
+ return new Font (small_font, font.Style | FontStyle.Underline);
+ else
+ return small_font;
+ }
+
return font;
}
}
@@ -122,20 +139,43 @@ namespace System.Windows.Forms
set {
if (font != value) {
link_font = null;
+ small_font = null;
font = value;
height = Font.Height;
XplatUI.GetFontMetrics (Hwnd.GraphicsContext, Font, out ascent, out descent);
+ float scale_factor = font.GetHeight () / font.FontFamily.GetLineSpacing (font.Style);
+ ascent = (int) Math.Ceiling (ascent * scale_factor);
+ descent = (int) Math.Ceiling (descent * scale_factor);
line.recalc = true;
}
}
}
+ public TextPositioning TextPosition {
+ get { return text_position; }
+ set { text_position = value; }
+ }
+
+ public float CharOffset {
+ get { return char_offset; }
+ set { char_offset = value; }
+ }
+
public int Height {
get { return height; }
set { height = value; }
}
+ public int DrawnHeight {
+ get {
+ if (text_position != TextPositioning.Normal)
+ return (int) (height * 0.583F);
+
+ return height;
+ }
+ }
+
public virtual bool IsTextTag {
get { return true; }
}
@@ -186,7 +226,7 @@ namespace System.Windows.Forms
throw new Exception("New tag makes an insane tag");
}
#endif
- start = value;
+ start = value;
}
}
@@ -206,9 +246,14 @@ namespace System.Windows.Forms
}
}
+ public bool Visible {
+ get { return visible; }
+ set { visible = value; }
+ }
+
public float Width {
get {
- if (Length == 0)
+ if (Length == 0 || !visible)
return 0;
return line.widths [start + Length - 1] - (start != 0 ? line.widths [start - 1] : 0);
}
@@ -222,6 +267,15 @@ namespace System.Windows.Forms
}
}
+ public int OffsetY {
+ get {
+ if (text_position == TextPositioning.Subscript)
+ return (int) (height * 0.45F);
+
+ return 0;
+ }
+ }
+
public bool IsLink {
get { return is_link; }
set { is_link = value; }
@@ -253,8 +307,8 @@ namespace System.Windows.Forms
new_tag = new LineTag(line, pos);
new_tag.CopyFormattingFrom (this);
- new_tag.next = this.next;
- this.next = new_tag;
+ new_tag.Next = this.next;
+ this.Next = new_tag;
new_tag.previous = this;
if (new_tag.next != null)
@@ -269,7 +323,7 @@ namespace System.Windows.Forms
if (!this.Equals (other))
return false;
- this.next = other.next;
+ this.Next = other.next;
if (this.next != null)
this.next.previous = this;
@@ -282,6 +336,9 @@ namespace System.Windows.Forms
Font = other.font;
color = other.color;
back_color = other.back_color;
+ TextPosition = other.text_position;
+ CharOffset = other.CharOffset;
+ Visible = other.Visible;
}
public void Delete ()
@@ -312,6 +369,8 @@ namespace System.Windows.Forms
public virtual void Draw (Graphics dc, Color color, float x, float y, int start, int end)
{
+ if (text_position == TextPositioning.Subscript)
+ y += OffsetY;
TextBoxTextRenderer.DrawText (dc, line.text.ToString (start, end).Replace ("\r", string.Empty), FontToDisplay, color, x, y, false);
}
@@ -328,6 +387,14 @@ namespace System.Windows.Forms
public virtual void Draw (Graphics dc, Color color, float xoff, float y, int drawStart, int drawEnd,
string text, out Rectangle measuredText, bool measureText)
{
+ if (!visible) {
+ measuredText = new Rectangle ();
+ return;
+ }
+
+ if (text_position == TextPositioning.Subscript)
+ y += OffsetY;
+
if (measureText) {
int xstart = (int)line.widths [drawStart] + (int)xoff;
int xend = (int)line.widths [drawEnd] - (int)line.widths [drawStart];
@@ -342,7 +409,7 @@ namespace System.Windows.Forms
while (drawStart < drawEnd) {
int tab_index = text.IndexOf ("\t", drawStart);
- if (tab_index == -1)
+ if (tab_index == -1 || tab_index > drawEnd)
tab_index = drawEnd;
TextBoxTextRenderer.DrawText (dc, text.Substring (drawStart, tab_index - drawStart).Replace ("\r", string.Empty), FontToDisplay, color, xoff + line.widths [drawStart], y, false);
@@ -380,7 +447,16 @@ namespace System.Windows.Forms
if (this.LinkText != other.LinkText)
return false;
- if (this.font.Equals (other.font) && this.color.Equals (other.color))
+ if (this.TextPosition != other.TextPosition)
+ return false;
+
+ if (this.CharOffset != other.CharOffset)
+ return false;
+
+ if (this.Visible != other.Visible)
+ return false;
+
+ if (this.font.Equals (other.font) && this.color.Equals (other.color) && this.back_color.Equals (other.back_color))
return true;
return false;
@@ -409,11 +485,17 @@ namespace System.Windows.Forms
return null;
}
+ public static bool FormatText (Line line, int formatStart, int length, Font font, Color color, Color backColor, FormatSpecified specified)
+ {
+ return FormatText (line, formatStart, length, font, color, backColor, TextPositioning.Normal, 0, true, specified);
+ }
+
/// <summary>Applies 'font' and 'brush' to characters starting at 'start' for 'length' chars;
/// Removes any previous tags overlapping the same area;
/// returns true if lineheight has changed</summary>
/// <param name="formatStart">1-based character position on line</param>
- public static bool FormatText (Line line, int formatStart, int length, Font font, Color color, Color backColor, FormatSpecified specified)
+ public static bool FormatText (Line line, int formatStart, int length, Font font, Color color, Color backColor,
+ TextPositioning text_position, float char_offset, bool visible, FormatSpecified specified)
{
LineTag tag;
LineTag start_tag;
@@ -422,7 +504,7 @@ namespace System.Windows.Forms
bool retval = false; // Assume line-height doesn't change
// Too simple?
- if (((FormatSpecified.Font & specified) == FormatSpecified.Font) && font.Height != line.height)
+ if (((FormatSpecified.Font & specified) == FormatSpecified.Font) && font.Height != line.TextHeight)
retval = true;
line.recalc = true; // This forces recalculation of the line in RecalculateDocument
@@ -436,7 +518,7 @@ namespace System.Windows.Forms
// Common special case
if ((formatStart == 1) && (length == tag.Length)) {
- SetFormat (tag, font, color, backColor, specified);
+ SetFormat (tag, font, color, backColor, text_position, char_offset, visible, specified);
return retval;
}
@@ -444,7 +526,7 @@ namespace System.Windows.Forms
// we only need one new tag
if (formatStart == 1 && length == 0) {
line.tags.Break (1);
- SetFormat (line.tags, font, color, backColor, specified);
+ SetFormat (line.tags, font, color, backColor, text_position, char_offset, visible, specified);
return retval;
}
@@ -455,7 +537,7 @@ namespace System.Windows.Forms
// Find Tag will return tag 0 at position 3, but we should just
// use the empty tag after..
if (start_tag.End == formatStart && length == 0 && start_tag.Next != null && start_tag.Next.Length == 0) {
- SetFormat (start_tag.Next, font, color, backColor, specified);
+ SetFormat (start_tag.Next, font, color, backColor, text_position, char_offset, visible, specified);
return retval;
}
@@ -463,13 +545,22 @@ namespace System.Windows.Forms
while (start_tag.End == formatStart && start_tag.Next != null)
start_tag = start_tag.Next;
- tag = start_tag.Break (formatStart);
+ if (start_tag.Start == formatStart && start_tag.Length == length) {
+ SetFormat (start_tag, font, color, backColor, text_position, char_offset, visible, specified);
+ return retval;
+ }
+
+ // Break the tag if needed -- we don't need to break for the start if we're starting at its start.
+ if (start_tag.Start != formatStart)
+ tag = start_tag.Break (formatStart);
+ else
+ tag = start_tag;
// empty selection style at end of line - its the only situation
// where the rest of the tag would be empty, since we moved to the
// begining of next non empty tag
if (tag.Length == 0) {
- SetFormat (tag, font, color, backColor, specified);
+ SetFormat (tag, font, color, backColor, text_position, char_offset, visible, specified);
return retval;
}
@@ -477,25 +568,27 @@ namespace System.Windows.Forms
// after our new (now) empty one..
if (length == 0) {
tag.Break (formatStart);
- SetFormat (tag, font, color, backColor, specified);
+ SetFormat (tag, font, color, backColor, text_position, char_offset, visible, specified);
return retval;
}
+ bool atEnd = false;
while (tag != null && tag.End <= end) {
- SetFormat (tag, font, color, backColor, specified);
+ SetFormat (tag, font, color, backColor, text_position, char_offset, visible, specified);
+ atEnd |= tag.End == end;
tag = tag.next;
}
// did the last tag conveniently fit?
- if (tag != null && tag.End == end)
+ if (atEnd || (tag != null && tag.End == end))
return retval;
- /// Now do the last tag
+ // Now do the last tag
end_tag = FindTag (line, end-1);
if (end_tag != null) {
end_tag.Break (end);
- SetFormat (end_tag, font, color, backColor, specified);
+ SetFormat (end_tag, font, color, backColor, text_position, char_offset, visible, specified);
}
return retval;
@@ -509,6 +602,7 @@ namespace System.Windows.Forms
int low = start;
int high = low + Length;
int length_no_ending = line.TextLengthWithoutEnding ();
+ float char_mid;
if (Length == 0)
return low-1;
@@ -517,7 +611,8 @@ namespace System.Windows.Forms
return 0;
if (x < line.widths [low]) {
- if (low == 1 && x > (line.widths [1] / 2))
+ char_mid = (line.widths [1] + line.widths [0]) / 2;
+ if (low == 1 && x >= char_mid)
return low;
return low - 1;
}
@@ -535,9 +630,9 @@ namespace System.Windows.Forms
high = mid;
}
- float char_width = line.widths[high] - line.widths[low];
+ char_mid = (line.widths [high] + line.widths [low]) / 2;
- if ((x - line.widths[low]) >= (char_width / 2))
+ if (x >= char_mid)
return high;
else
return low;
@@ -569,6 +664,12 @@ namespace System.Windows.Forms
private static void SetFormat (LineTag tag, Font font, Color color, Color back_color, FormatSpecified specified)
{
+ SetFormat (tag, font, color, back_color, TextPositioning.Normal, 0, true, specified);
+ }
+
+ private static void SetFormat (LineTag tag, Font font, Color color, Color back_color, TextPositioning text_position,
+ float char_offset, bool visible, FormatSpecified specified)
+ {
if ((FormatSpecified.Font & specified) == FormatSpecified.Font) {
tag.Font = font;
}
@@ -577,28 +678,52 @@ namespace System.Windows.Forms
if ((FormatSpecified.BackColor & specified) == FormatSpecified.BackColor) {
tag.back_color = back_color;
}
+ if ((FormatSpecified.TextPosition & specified) == FormatSpecified.TextPosition)
+ tag.TextPosition = text_position;
+ if ((FormatSpecified.CharOffset & specified) == FormatSpecified.CharOffset)
+ tag.CharOffset = char_offset;
+ if ((FormatSpecified.Visibility & specified) == FormatSpecified.Visibility)
+ tag.Visible = visible;
// Console.WriteLine ("setting format: {0} {1} new color {2}", color.Color, specified, tag.color.Color);
}
public virtual SizeF SizeOfPosition (Graphics dc, int pos)
{
- if (pos >= line.TextLengthWithoutEnding () && line.document.multiline)
+ if ((pos >= line.TextLengthWithoutEnding () && line.document.multiline) || !visible)
return SizeF.Empty;
string text = line.text.ToString (pos, 1);
- switch ((int) text [0]) {
+ switch ((int)text [0]) {
case '\t':
if (!line.document.multiline)
goto case 10;
- SizeF res = TextBoxTextRenderer.MeasureText (dc, " ", font);
- res.Width *= 8.0F;
+ SizeF res = TextBoxTextRenderer.MeasureText (dc, " ", FontToDisplay); // This way we get the height, not that it is ever used...
+ float left = line.widths [pos];
+ float right = -1;
+ TabStopCollection stops = line.tab_stops;
+ float tabPos;
+ for (int i = 0; i < stops.Count; i++) {
+ tabPos = stops [i].Position;
+ if (tabPos >= left) {
+ if (tabPos <= line.document.viewport_width - line.RightIndent)
+ break; // Can't use tabs that are past the end of the line.
+
+ right = stops [i].CalculateRight (line, pos);
+ break;
+ }
+ }
+ if (right < 0) {
+ float maxWidth = dc.DpiX / 2; // tab stops are 1/2"
+ right = (float)(Math.Floor (left / maxWidth) + 1) * maxWidth;
+ }
+ res.Width = right - left;
return res;
case 10:
case 13:
- return TextBoxTextRenderer.MeasureText (dc, "\u000D", font);
+ return TextBoxTextRenderer.MeasureText (dc, "\u000D", FontToDisplay);
}
-
- return TextBoxTextRenderer.MeasureText (dc, text, font);
+
+ return TextBoxTextRenderer.MeasureText (dc, text, FontToDisplay);
}
public virtual string Text ()
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/ListBox.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/ListBox.cs
index fbc74eed38d..b513cf90910 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/ListBox.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/ListBox.cs
@@ -1614,7 +1614,7 @@ namespace System.Windows.Forms
private bool KeySearch (Keys key)
{
char c = (char) key;
- if (!Char.IsLetterOrDigit (c))
+ if (!Char.IsLetterOrDigit (c) || SelectionMode == SelectionMode.None)
return false;
int idx = FindString (c.ToString (), SelectedIndex);
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/RichTextBox.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/RichTextBox.cs
index 9073f2c10c4..1b5f9513a23 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/RichTextBox.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/RichTextBox.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok <pbartok@novell.com>
+// Karl Scowen <contact@scowencomputers.co.nz>
//
//
@@ -28,6 +29,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
@@ -55,7 +57,9 @@ namespace System.Windows.Forms {
// properties so we can revert
private Stack rtf_section_stack;
- private RTF.TextMap rtf_text_map;
+ bool fire_contents_resized;
+ Size existing_contents_size;
+
private int rtf_skip_count;
private int rtf_cursor_x;
private int rtf_cursor_y;
@@ -64,7 +68,7 @@ namespace System.Windows.Forms {
private bool enable_auto_drag_drop;
private RichTextBoxLanguageOptions language_option;
private bool rich_text_shortcuts_enabled;
- private Color selection_back_color;
+
#endregion // Local Variables
#region Public Constructors
@@ -85,15 +89,17 @@ namespace System.Windows.Forms {
rtf_style = new RtfSectionStyle ();
rtf_section_stack = null;
+ fire_contents_resized = true;
+
scrollbars = RichTextBoxScrollBars.Both;
alignment = HorizontalAlignment.Left;
+ document.SizeChanged += new EventHandler<Document.SizeChangedEventArgs> (ContentSizeChanged);
LostFocus += new EventHandler(RichTextBox_LostFocus);
GotFocus += new EventHandler(RichTextBox_GotFocus);
BackColor = ThemeEngine.Current.ColorWindow;
backcolor_set = false;
language_option = RichTextBoxLanguageOptions.AutoFontSizeAdjust;
rich_text_shortcuts_enabled = true;
- selection_back_color = DefaultBackColor;
ForeColor = ThemeEngine.Current.ColorWindowText;
base.HScrolled += new EventHandler(RichTextBox_HScrolled);
@@ -133,6 +139,29 @@ namespace System.Windows.Forms {
private void RichTextBox_GotFocus(object sender, EventArgs e) {
Invalidate();
}
+
+ private void ContentSizeChanged (object sender, Document.SizeChangedEventArgs e)
+ {
+ ContentSizeChanged ();
+ }
+
+ private void ContentSizeChanged ()
+ {
+ if (fire_contents_resized && (existing_contents_size.IsEmpty ||
+ existing_contents_size.Height != document.Height || existing_contents_size.Width != document.Width)) {
+ int width;
+ int height = document.Height + document.top_margin * 2 + Height - ClientRectangle.Height;
+
+ if (Multiline) {
+ width = Width; // yes, this is the insanity that is the traditional .Net implementation...
+ } else {
+ width = document.Width + document.left_margin + document.right_margin + Width - ClientRectangle.Width;
+ }
+
+ ContentsResizedEventArgs args = new ContentsResizedEventArgs (new Rectangle (Left, Top, width, height));
+ OnContentsResized (args);
+ }
+ }
#endregion // Private & Internal Methods
#region Public Instance Properties
@@ -324,14 +353,25 @@ namespace System.Windows.Forms {
set {
MemoryStream data;
+ fire_contents_resized = false;
+ existing_contents_size = new Size (document.Width, document.Height);
+
document.Empty();
data = new MemoryStream(Encoding.ASCII.GetBytes(value), false);
InsertRTFFromStream(data, 0, 1);
+ Line line = document.GetLine (1);
+ document.SetSelection (line, 0);
+ document.PositionCaret (line, 0);
+
data.Close();
Invalidate();
+
+ fire_contents_resized = true;
+ ContentSizeChanged ();
+ existing_contents_size = Size.Empty;
}
}
@@ -371,6 +411,9 @@ namespace System.Windows.Forms {
Line line;
LineTag tag;
+ fire_contents_resized = false;
+ existing_contents_size = new Size (document.Width, document.Height);
+ document.SuspendRecalc ();
if (document.selection_visible) {
document.ReplaceSelection("", false);
}
@@ -393,14 +436,19 @@ namespace System.Windows.Forms {
int nl_length = document.LineEndingLength (XplatUI.RunningOnUnix ? LineEnding.Rich : LineEnding.Hard);
document.CharIndexToLineTag(sel_start + chars + (y - document.selection_start.line.line_no) * nl_length,
out line, out tag, out sel_start);
- if (sel_start >= line.text.Length)
- sel_start = line.text.Length -1;
+ if (sel_start > line.text.Length)
+ sel_start = line.text.Length; //zero-based, but we want to go after the last character rather than before.
document.SetSelection(line, sel_start);
document.PositionCaret(line, sel_start);
+ document.ResumeRecalc(true);
document.DisplayCaret();
ScrollToCaret();
OnTextChanged(EventArgs.Empty);
+
+ fire_contents_resized = true;
+ ContentSizeChanged();
+ existing_contents_size = Size.Empty;
}
}
@@ -473,12 +521,56 @@ namespace System.Windows.Forms {
}
}
- [MonoTODO ("Stub, does nothing")]
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
public Color SelectionBackColor {
- get { return selection_back_color; }
- set { selection_back_color = value; }
+ get {
+ Color back_colour;
+ LineTag start;
+ LineTag end;
+ LineTag tag;
+
+ start = document.selection_start.line.FindTag (document.selection_start.pos);
+
+ if (SelectionLength > 0) {
+ end = document.selection_start.line.FindTag (document.selection_end.pos - 1);
+ } else {
+ end = start;
+ }
+
+ back_colour = start.BackColor;
+
+ tag = start;
+ while (tag != null) {
+ if (back_colour != tag.BackColor)
+ return Color.Empty;
+
+ if (tag == end)
+ break;
+
+ tag = document.NextTag (tag);
+ }
+
+ return back_colour;
+ }
+ set {
+ int sel_start;
+ int sel_end;
+
+ sel_start = document.LineTagToCharIndex (document.selection_start.line, document.selection_start.pos);
+ sel_end = document.LineTagToCharIndex (document.selection_end.line, document.selection_end.pos);
+
+ document.FormatText (document.selection_start.line, document.selection_start.pos + 1,
+ document.selection_end.line, document.selection_end.pos + 1, null,
+ Color.Empty, value, FormatSpecified.BackColor);
+
+ document.CharIndexToLineTag (sel_start, out document.selection_start.line, out document.selection_start.tag, out document.selection_start.pos);
+ document.CharIndexToLineTag (sel_end, out document.selection_end.line, out document.selection_end.tag, out document.selection_end.pos);
+
+ document.UpdateView (document.selection_start.line, 0);
+ //Re-Align the caret in case its changed size or position
+ Document.AlignCaret (false);
+ }
}
[Browsable(false)]
@@ -497,13 +589,54 @@ namespace System.Windows.Forms {
[Browsable(false)]
[DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [MonoTODO ("Stub, does nothing")]
public int SelectionCharOffset {
get {
- return 0;
+ float char_offset;
+ LineTag start;
+ LineTag end;
+ LineTag tag;
+
+ start = document.selection_start.line.FindTag (document.selection_start.pos);
+
+ if (SelectionLength > 0) {
+ end = document.selection_start.line.FindTag (document.selection_end.pos - 1);
+ } else {
+ end = start;
+ }
+
+ char_offset = start.CharOffset;
+
+ tag = start;
+ while (tag != null) {
+ if (Math.Abs(char_offset - tag.CharOffset) > 0.01)
+ return 0;
+
+ if (tag == end)
+ break;
+
+ tag = document.NextTag (tag);
+ }
+
+ return (int)char_offset;
}
set {
+ int sel_start;
+ int sel_end;
+
+ sel_start = document.LineTagToCharIndex (document.selection_start.line, document.selection_start.pos);
+ sel_end = document.LineTagToCharIndex (document.selection_end.line, document.selection_end.pos);
+
+ document.FormatText (document.selection_start.line, document.selection_start.pos + 1,
+ document.selection_end.line, document.selection_end.pos + 1, null,
+ Color.Empty, Color.Empty, TextPositioning.Normal, value, true, FormatSpecified.CharOffset);
+
+ document.CharIndexToLineTag (sel_start, out document.selection_start.line, out document.selection_start.tag, out document.selection_start.pos);
+ document.CharIndexToLineTag (sel_end, out document.selection_end.line, out document.selection_end.tag, out document.selection_end.pos);
+
+ document.UpdateView (document.selection_start.line, 0);
+ //Re-Align the caret in case its changed size or position -- probably not necessary
+ Document.AlignCaret (false);
}
}
@@ -516,11 +649,11 @@ namespace System.Windows.Forms {
LineTag end;
LineTag tag;
- if (selection_length > 0) {
- start = document.selection_start.line.FindTag (document.selection_start.pos + 1);
- end = document.selection_start.line.FindTag (document.selection_end.pos);
+ start = document.selection_start.line.FindTag (document.selection_start.pos);
+
+ if (SelectionLength > 0) {
+ end = document.selection_start.line.FindTag (document.selection_end.pos - 1);
} else {
- start = document.selection_start.line.FindTag (document.selection_start.pos);
end = start;
}
@@ -575,17 +708,16 @@ namespace System.Windows.Forms {
LineTag end;
LineTag tag;
- if (selection_length > 0) {
- start = document.selection_start.line.FindTag (document.selection_start.pos + 1);
- end = document.selection_start.line.FindTag (document.selection_end.pos);
+ start = document.selection_start.line.FindTag (document.selection_start.pos);
+ if (SelectionLength > 0) {
+ end = document.selection_start.line.FindTag (document.selection_end.pos - 1);
} else {
- start = document.selection_start.line.FindTag (document.selection_start.pos);
end = start;
}
font = start.Font;
- if (selection_length > 1) {
+ if (SelectionLength > 1) {
tag = start;
while (tag != null) {
@@ -626,26 +758,106 @@ namespace System.Windows.Forms {
[Browsable(false)]
[DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [MonoTODO ("Stub, does nothing")]
public int SelectionHangingIndent {
get {
- return 0;
+ int indent;
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ indent = (int)start.hanging_indent;
+
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ if ((int)line.hanging_indent != indent) {
+ return 0;
+ }
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+
+ return indent;
}
set {
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ line.HangingIndent = value;
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+ this.CalculateDocument ();
}
}
[Browsable(false)]
[DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [MonoTODO ("Stub, does nothing")]
public int SelectionIndent {
get {
- return 0;
+ int indent;
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ indent = (int)start.indent;
+
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ if ((int)line.indent != indent) {
+ return 0;
+ }
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+
+ return indent;
}
set {
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ line.Indent = value;
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+ this.CalculateDocument ();
}
}
@@ -677,25 +889,105 @@ namespace System.Windows.Forms {
[Browsable(false)]
[DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [MonoTODO ("Stub, does nothing")]
public int SelectionRightIndent {
get {
- return 0;
+ int indent;
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ indent = (int)start.right_indent;
+
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ if ((int)line.right_indent != indent) {
+ return 0;
+ }
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+
+ return indent;
}
set {
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ line.RightIndent = value;
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+ this.CalculateDocument ();
}
}
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
- [MonoTODO ("Stub, does nothing")]
public int[] SelectionTabs {
get {
- return new int[0];
+ TabStopCollection tabs;
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ tabs = start.TabStops;
+
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ if (!line.TabStops.Equals (tabs))
+ return new int[0];
+
+ if (line == end)
+ break;
+ line = document.GetLine (line.line_no + 1);
+ }
+
+ return tabs.ToPosArray ();
}
set {
+ Line start;
+ Line end;
+ Line line;
+
+ start = document.ParagraphStart (document.selection_start.line);
+ end = document.ParagraphEnd (document.selection_end.line);
+
+ line = start;
+
+ while (true) {
+ line.TabStops.Clear ();
+ foreach (int val in value)
+ line.TabStops.Add (new LeftTabStop (val));
+
+ if (line == end) {
+ break;
+ }
+ line = document.GetLine (line.line_no + 1);
+ }
+ this.CalculateDocument ();
}
}
@@ -1308,26 +1600,47 @@ namespace System.Windows.Forms {
private class RtfSectionStyle : ICloneable {
internal Color rtf_color;
+ internal Color rtf_back_color;
internal RTF.Font rtf_rtffont;
- internal int rtf_rtffont_size;
+ internal float rtf_rtffont_size;
internal FontStyle rtf_rtfstyle;
- internal HorizontalAlignment rtf_rtfalign;
- internal int rtf_par_line_left_indent;
+ internal HorizontalAlignment rtf_par_align;
+ internal float rtf_par_line_left_indent;
+ internal float rtf_par_first_line_indent;
+ internal float rtf_par_line_right_indent;
internal bool rtf_visible;
internal int rtf_skip_width;
+ internal float rtf_par_spacing_after;
+ internal float rtf_par_spacing_before;
+ internal float rtf_par_line_spacing;
+ internal bool rtf_par_line_spacing_multiple;
+ internal TextPositioning rtf_text_position;
+ internal float rtf_char_offset;
+ internal TabStop rtf_par_next_tab_stop = null;
+ internal TabStopCollection rtf_par_tab_stops = new TabStopCollection ();
public object Clone ()
{
RtfSectionStyle new_style = new RtfSectionStyle ();
new_style.rtf_color = rtf_color;
+ new_style.rtf_back_color = rtf_back_color;
new_style.rtf_par_line_left_indent = rtf_par_line_left_indent;
- new_style.rtf_rtfalign = rtf_rtfalign;
+ new_style.rtf_par_first_line_indent = rtf_par_first_line_indent;
+ new_style.rtf_par_line_right_indent = rtf_par_line_right_indent;
+ new_style.rtf_par_align = rtf_par_align;
new_style.rtf_rtffont = rtf_rtffont;
new_style.rtf_rtffont_size = rtf_rtffont_size;
new_style.rtf_rtfstyle = rtf_rtfstyle;
new_style.rtf_visible = rtf_visible;
new_style.rtf_skip_width = rtf_skip_width;
+ new_style.rtf_par_spacing_after = rtf_par_spacing_after;
+ new_style.rtf_par_spacing_before = rtf_par_spacing_before;
+ new_style.rtf_par_line_spacing = rtf_par_line_spacing;
+ new_style.rtf_par_line_spacing_multiple = rtf_par_line_spacing_multiple;
+ new_style.rtf_text_position = rtf_text_position;
+ new_style.rtf_char_offset = rtf_char_offset;
+ new_style.rtf_par_tab_stops = rtf_par_tab_stops.Clone ();
return new_style;
}
@@ -1385,11 +1698,9 @@ namespace System.Windows.Forms {
case RTF.Major.PictAttr:
if (rtf.Picture != null && rtf.Picture.IsValid ()) {
+ FlushText (rtf, false, true);
Line line = document.GetLine (rtf_cursor_y);
- document.InsertPicture (line, 0, rtf.Picture);
- rtf_cursor_x++;
-
- FlushText (rtf, true);
+ document.InsertPicture (line, rtf_cursor_x++, rtf.Picture);
rtf.Picture = null;
}
break;
@@ -1399,14 +1710,31 @@ namespace System.Windows.Forms {
case RTF.Minor.ForeColor: {
System.Windows.Forms.RTF.Color color;
+ color = System.Windows.Forms.RTF.Color.GetColor (rtf, rtf.Param);
+
+ if (color != null) {
+ FlushText (rtf, false);
+ if (color.Red == -1 && color.Green == -1 && color.Blue == -1) {
+ this.rtf_style.rtf_color = ForeColor;
+ } else {
+ this.rtf_style.rtf_color = Color.FromArgb (color.Red, color.Green, color.Blue);
+ }
+ FlushText (rtf, false);
+ }
+ break;
+ }
+
+ case RTF.Minor.BackColor: {
+ System.Windows.Forms.RTF.Color color;
+
color = System.Windows.Forms.RTF.Color.GetColor(rtf, rtf.Param);
-
+
if (color != null) {
FlushText(rtf, false);
if (color.Red == -1 && color.Green == -1 && color.Blue == -1) {
- this.rtf_style.rtf_color = ForeColor;
+ this.rtf_style.rtf_back_color = BackColor;
} else {
- this.rtf_style.rtf_color = Color.FromArgb(color.Red, color.Green, color.Blue);
+ this.rtf_style.rtf_back_color = Color.FromArgb(color.Red, color.Green, color.Blue);
}
FlushText (rtf, false);
}
@@ -1415,7 +1743,7 @@ namespace System.Windows.Forms {
case RTF.Minor.FontSize: {
FlushText(rtf, false);
- this.rtf_style.rtf_rtffont_size = rtf.Param / 2;
+ this.rtf_style.rtf_rtffont_size = rtf.Param / 2f;
break;
}
@@ -1478,7 +1806,7 @@ namespace System.Windows.Forms {
case RTF.Minor.Invisible: {
FlushText (rtf, false);
- rtf_style.rtf_visible = false;
+ rtf_style.rtf_visible = (rtf.Param != RTF.RTF.NoParam);
break;
}
@@ -1487,6 +1815,36 @@ namespace System.Windows.Forms {
rtf_style.rtf_rtfstyle &= ~FontStyle.Underline;
break;
}
+
+ case RTF.Minor.SuperScrShrink: {
+ FlushText (rtf, false);
+ rtf_style.rtf_text_position = TextPositioning.Superscript;
+ break;
+ }
+
+ case RTF.Minor.SubScrShrink: {
+ FlushText (rtf, false);
+ rtf_style.rtf_text_position = TextPositioning.Subscript;
+ break;
+ }
+
+ case RTF.Minor.NoSuperSub: {
+ FlushText (rtf, false);
+ rtf_style.rtf_text_position = TextPositioning.Normal;
+ break;
+ }
+
+ case RTF.Minor.SuperScript: {
+ FlushText (rtf, false);
+ rtf_style.rtf_char_offset = ((float) rtf.Param / 144.0F) * document.Dpi;
+ break;
+ }
+
+ case RTF.Minor.SubScript: {
+ FlushText (rtf, false);
+ rtf_style.rtf_char_offset = -((float) rtf.Param / 144.0F) * document.Dpi;
+ break;
+ }
}
break;
}
@@ -1497,32 +1855,90 @@ namespace System.Windows.Forms {
case RTF.Minor.ParDef:
FlushText (rtf, false);
rtf_style.rtf_par_line_left_indent = 0;
- rtf_style.rtf_rtfalign = HorizontalAlignment.Left;
+ rtf_style.rtf_par_first_line_indent = 0;
+ rtf_style.rtf_par_line_right_indent = 0;
+ rtf_style.rtf_par_spacing_after = 0;
+ rtf_style.rtf_par_spacing_before = 0;
+ rtf_style.rtf_par_line_spacing = 0;
+ rtf_style.rtf_par_line_spacing_multiple = false;
+ rtf_style.rtf_par_align = HorizontalAlignment.Left;
+ rtf_style.rtf_par_next_tab_stop = null;
+ rtf_style.rtf_par_tab_stops.Clear ();
+ break;
+
+ case RTF.Minor.TabLeft:
+ rtf_style.rtf_par_next_tab_stop = new LeftTabStop ();
+ break;
+
+ case RTF.Minor.TabCenter:
+ rtf_style.rtf_par_next_tab_stop = new CentredTabStop ();
+ break;
+
+ case RTF.Minor.TabRight:
+ rtf_style.rtf_par_next_tab_stop = new RightTabStop ();
+ break;
+
+ case RTF.Minor.TabDecimal:
+ rtf_style.rtf_par_next_tab_stop = new DecimalTabStop ();
+ break;
+
+ case RTF.Minor.TabPos:
+ float tabPos = ((float)rtf.Param / 1440.0F) * document.Dpi;
+ if (rtf_style.rtf_par_next_tab_stop != null) {
+ rtf_style.rtf_par_next_tab_stop.Position = tabPos;
+ rtf_style.rtf_par_tab_stops.Add (rtf_style.rtf_par_next_tab_stop);
+ rtf_style.rtf_par_next_tab_stop = null;
+ } else {
+ rtf_style.rtf_par_tab_stops.Add (new LeftTabStop (tabPos));
+ }
break;
case RTF.Minor.LeftIndent:
- using (Graphics g = CreateGraphics ())
- rtf_style.rtf_par_line_left_indent = (int) (((float) rtf.Param / 1440.0F) * g.DpiX + 0.5F);
+ rtf_style.rtf_par_line_left_indent = ((float) rtf.Param / 1440.0F) * document.Dpi;
+ break;
+
+ case RTF.Minor.FirstIndent:
+ rtf_style.rtf_par_first_line_indent = ((float) rtf.Param / 1440.0F) * document.Dpi;
+ break;
+
+ case RTF.Minor.RightIndent:
+ rtf_style.rtf_par_line_right_indent = ((float) rtf.Param / 1440.0F) * document.Dpi;
break;
case RTF.Minor.QuadCenter:
FlushText (rtf, false);
- rtf_style.rtf_rtfalign = HorizontalAlignment.Center;
+ rtf_style.rtf_par_align = HorizontalAlignment.Center;
break;
case RTF.Minor.QuadJust:
FlushText (rtf, false);
- rtf_style.rtf_rtfalign = HorizontalAlignment.Center;
+ rtf_style.rtf_par_align = HorizontalAlignment.Left;
break;
case RTF.Minor.QuadLeft:
FlushText (rtf, false);
- rtf_style.rtf_rtfalign = HorizontalAlignment.Left;
+ rtf_style.rtf_par_align = HorizontalAlignment.Left;
break;
case RTF.Minor.QuadRight:
FlushText (rtf, false);
- rtf_style.rtf_rtfalign = HorizontalAlignment.Right;
+ rtf_style.rtf_par_align = HorizontalAlignment.Right;
+ break;
+
+ case RTF.Minor.SpaceAfter:
+ rtf_style.rtf_par_spacing_after = ((float) rtf.Param / 1440.0F) * document.Dpi;
+ break;
+
+ case RTF.Minor.SpaceBefore:
+ rtf_style.rtf_par_spacing_before = ((float) rtf.Param / 1440.0F) * document.Dpi;
+ break;
+
+ case RTF.Minor.SpaceBetween:
+ rtf_style.rtf_par_line_spacing = ((float) rtf.Param / 1440.0F) * document.Dpi;
+ break;
+
+ case RTF.Minor.SpaceMultiply:
+ rtf_style.rtf_par_line_spacing_multiple = (rtf.Param == 1);
break;
}
break;
@@ -1543,7 +1959,8 @@ namespace System.Windows.Forms {
case RTF.Minor.Row:
case RTF.Minor.Line:
case RTF.Minor.Par: {
- FlushText(rtf, true);
+ if (Multiline)
+ FlushText (rtf, true);
break;
}
@@ -1575,8 +1992,8 @@ namespace System.Windows.Forms {
break;
}
- case RTF.Minor.WidowCtrl:
- break;
+ case RTF.Minor.WidowCtrl:
+ break;
case RTF.Minor.EmDash: {
rtf_line.Append ("\u2014");
@@ -1587,7 +2004,7 @@ namespace System.Windows.Forms {
rtf_line.Append ("\u2013");
break;
}
-/*
+
case RTF.Minor.LQuote: {
Console.Write("\u2018");
break;
@@ -1607,7 +2024,7 @@ namespace System.Windows.Forms {
Console.Write("\u201D");
break;
}
-*/
+
default: {
// Console.WriteLine ("skipped special char: {0}", rtf.Minor);
// rtf.SkipGroup();
@@ -1640,16 +2057,21 @@ namespace System.Windows.Forms {
}
*/
- if (rtf_style.rtf_visible)
- rtf_line.Append (str);
+ rtf_line.Append (str);
}
private void FlushText(RTF.RTF rtf, bool newline) {
+ FlushText (rtf, newline, false);
+ }
+
+ private void FlushText(RTF.RTF rtf, bool newline, bool force) {
int length;
+ float hanging_indent;
+ float left_indent;
Font font;
length = rtf_line.Length;
- if (!newline && (length == 0)) {
+ if (!newline && (length == 0) && !force) {
return;
}
@@ -1659,7 +2081,12 @@ namespace System.Windows.Forms {
}
font = new Font (rtf_style.rtf_rtffont.Name, rtf_style.rtf_rtffont_size, rtf_style.rtf_rtfstyle);
+ if (font.Name != rtf_style.rtf_rtffont.Name && !string.IsNullOrEmpty (rtf_style.rtf_rtffont.AltName))
+ font = new Font (rtf_style.rtf_rtffont.AltName, rtf_style.rtf_rtffont_size, rtf_style.rtf_rtfstyle);
+ hanging_indent = -rtf_style.rtf_par_first_line_indent;
+ left_indent = rtf_style.rtf_par_line_left_indent - hanging_indent;
+
if (rtf_style.rtf_color == Color.Empty) {
System.Windows.Forms.RTF.Color color;
@@ -1682,30 +2109,40 @@ namespace System.Windows.Forms {
if (newline && rtf_line.ToString ().EndsWith (Environment.NewLine) == false)
rtf_line.Append (Environment.NewLine);
- document.Add (rtf_cursor_y, rtf_line.ToString (), rtf_style.rtf_rtfalign, font, rtf_style.rtf_color,
- newline ? LineEnding.Rich : LineEnding.Wrap);
- if (rtf_style.rtf_par_line_left_indent != 0) {
- Line line = document.GetLine (rtf_cursor_y);
- line.indent = rtf_style.rtf_par_line_left_indent;
- }
+ document.Add (rtf_cursor_y, rtf_line.ToString (), rtf_style.rtf_par_align, font, rtf_style.rtf_color,
+ rtf_style.rtf_back_color, rtf_style.rtf_text_position, rtf_style.rtf_char_offset, left_indent, hanging_indent,
+ rtf_style.rtf_par_line_right_indent, rtf_style.rtf_par_spacing_before, rtf_style.rtf_par_spacing_after,
+ rtf_style.rtf_par_line_spacing, rtf_style.rtf_par_line_spacing_multiple,
+ rtf_style.rtf_par_tab_stops.Clone() , rtf_style.rtf_visible,
+ newline ? LineEnding.Rich : LineEnding.None);
} else {
- Line line;
+ Line line = document.GetLine (rtf_cursor_y);
+
+ if (newline) {
+ if (rtf_cursor_x < line.text.Length)
+ document.Split(line, rtf_cursor_x);
+ line.ending = LineEnding.Rich;
+ }
+
+ line.indent = left_indent;
+ line.HangingIndent = hanging_indent;
+ line.right_indent = rtf_style.rtf_par_line_right_indent;
+ line.spacing_after = rtf_style.rtf_par_spacing_after;
+ line.spacing_before = rtf_style.rtf_par_spacing_before;
+ line.line_spacing = rtf_style.rtf_par_line_spacing;
+ line.line_spacing_multiple = rtf_style.rtf_par_line_spacing_multiple;
+ line.alignment = rtf_style.rtf_par_align;
- line = document.GetLine (rtf_cursor_y);
- line.indent = rtf_style.rtf_par_line_left_indent;
if (rtf_line.Length > 0) {
document.InsertString (line, rtf_cursor_x, rtf_line.ToString ());
document.FormatText (line, rtf_cursor_x + 1, line, rtf_cursor_x + 1 + length,
- font, rtf_style.rtf_color, Color.Empty,
- FormatSpecified.Font | FormatSpecified.Color);
+ font, rtf_style.rtf_color, rtf_style.rtf_back_color, rtf_style.rtf_text_position, rtf_style.rtf_char_offset,
+ rtf_style.rtf_visible, FormatSpecified.Font | FormatSpecified.Color | FormatSpecified.BackColor |
+ FormatSpecified.TextPosition | FormatSpecified.CharOffset | FormatSpecified.Visibility);
}
- if (newline) {
- line = document.GetLine (rtf_cursor_y);
- line.ending = LineEnding.Rich;
- if (line.Text.EndsWith (Environment.NewLine) == false)
- line.Text += Environment.NewLine;
- }
+ if (newline && line.Text.EndsWith (Environment.NewLine) == false)
+ line.Text += Environment.NewLine;
reuse_line = false; // sanity assignment - in this case we have already re-used one line.
}
@@ -1740,9 +2177,20 @@ namespace System.Windows.Forms {
rtf_skip_count = 0;
rtf_line = new StringBuilder();
rtf_style.rtf_color = Color.Empty;
+ rtf_style.rtf_back_color = Color.Empty;
rtf_style.rtf_rtffont_size = (int)this.Font.Size;
- rtf_style.rtf_rtfalign = HorizontalAlignment.Left;
+ rtf_style.rtf_par_align = HorizontalAlignment.Left;
rtf_style.rtf_rtfstyle = FontStyle.Regular;
+ rtf_style.rtf_text_position = TextPositioning.Normal;
+ rtf_style.rtf_par_spacing_after = 0;
+ rtf_style.rtf_par_spacing_before = 0;
+ rtf_style.rtf_par_line_spacing = 0;
+ rtf_style.rtf_par_line_spacing_multiple = false;
+ rtf_style.rtf_par_line_left_indent = 0;
+ rtf_style.rtf_par_first_line_indent = 0;
+ rtf_style.rtf_par_line_right_indent = 0;
+ rtf_style.rtf_par_tab_stops.Clear ();
+ rtf_style.rtf_char_offset = 0;
rtf_style.rtf_rtffont = null;
rtf_style.rtf_visible = true;
rtf_style.rtf_skip_width = 1;
@@ -1751,15 +2199,18 @@ namespace System.Windows.Forms {
rtf_chars = 0;
rtf.DefaultFont(this.Font.Name);
- rtf_text_map = new RTF.TextMap();
- RTF.TextMap.SetupStandardTable(rtf_text_map.Table);
-
document.SuspendRecalc ();
try {
rtf.Read(); // That's it
FlushText(rtf, false);
+ if (document.Lines > 1) {
+ Line last_line = document.GetLine (document.Lines);
+ if (last_line.text.Length == 0) {
+ document.Delete (last_line);
+ }
+ }
}
@@ -1780,10 +2231,11 @@ namespace System.Windows.Forms {
rtf_section_stack.Clear();
if (IsHandleCreated) {
+ CalculateScrollBars ();
using (var graphics = CreateGraphics())
document.RecalculateDocument(graphics, cursor_y, document.Lines, false);
document.ResumeRecalc (true);
- document.Invalidate (document.GetLine(cursor_y), 0, document.GetLine(document.Lines), -1);
+ document.InvalidateLinesAfter(document.GetLine(cursor_y));
} else {
document.ResumeRecalc (false);
}
@@ -1822,7 +2274,7 @@ namespace System.Windows.Forms {
rtf.Append(String.Format("\\f{0}", font_index)); // Font table entry
}
- if ((prev_font == null) || (prev_font.Size != font.Size)) {
+ if ((prev_font == null) || (Math.Abs (prev_font.Size - font.Size) > 0.01)) {
rtf.Append(String.Format("\\fs{0}", (int)(font.Size * 2))); // Font size
}
@@ -1873,19 +2325,20 @@ namespace System.Windows.Forms {
int start = rtf.Length;
int count = text.Length;
- // First emit simple unicode chars as escaped
- EmitEscapedUnicode (rtf, text);
-
// This method emits user text *only*, so it's safe to escape any reserved rtf chars
// Escape '\' first, since it is used later to escape the other chars
if (text.IndexOfAny (ReservedRTFChars) > -1) {
- rtf.Replace ("\\", "\\\\", start, count);
- rtf.Replace ("{", "\\{", start, count);
- rtf.Replace ("}", "\\}", start, count);
+ StringBuilder sb = new StringBuilder(text); // Would it be better to just use text = text.Replace for this?
+ sb.Replace ("\\", "\\\\");
+ sb.Replace ("{", "\\{");
+ sb.Replace ("}", "\\}");
+ text = sb.ToString ();
}
+
+ // Then actually emit the text, and also escape any Unicode
+ EmitEscapedUnicode (rtf, text);
}
- // The chars to be escaped use "\'" + its hexadecimal value.
private void EmitEscapedUnicode (StringBuilder sb, string text)
{
int pos;
@@ -1894,9 +2347,10 @@ namespace System.Windows.Forms {
while ((pos = IndexOfNonAscii (text, start)) > -1) {
sb.Append (text, start, pos - start);
- int n = (int)text [pos];
- sb.Append ("\\'");
- sb.Append (n.ToString ("X"));
+ short n = (short)text [pos];
+ sb.Append ("\\u");
+ sb.Append (n.ToString ());
+ sb.Append ("?");
start = pos + 1;
}
@@ -1918,24 +2372,182 @@ namespace System.Windows.Forms {
return -1;
}
+ static char[] GetHexChars (byte[] bytes, int length)
+ {
+ if (length > bytes.Length)
+ throw new ArgumentOutOfRangeException ("length");
+
+ var chars = new char [length * 2];
+ int n;
+ for (int i = 0; i < length; i++) {
+ n = bytes [i] >> 4;
+ chars [i * 2] = (char)('A' - 10 + n + (((n - 10) >> 31) & ('0' - 55)));
+ n = bytes [i] & 0x0F;
+ chars [i * 2 + 1] = (char)('A' - 10 + n + (((n - 10) >> 31) & ('0' - 55)));
+ }
+ return chars;
+ }
+
+ void EmitRtfPicture (PictureTag picture, StringBuilder sb)
+ {
+ if (!picture.picture.IsValid ()) {
+ return;
+ }
+
+ int width = (int)((float)picture.picture.Width / document.Dpi * 1440f);
+ int height = (int)((float)picture.picture.Height / document.Dpi * 1440f);
+ string type = "";
+ switch (picture.picture.ImageType) {
+ case RTF.Minor.WinMetafile:
+ type = "wmetafile1"; // The number should actually vary, but I don't see how it is used here at all.
+ break;
+ case RTF.Minor.EnhancedMetafile:
+ type = "emfblip";
+ break;
+ case RTF.Minor.PngBlip:
+ type = "pngblip";
+ break;
+ case RTF.Minor.JpegBlip:
+ type = "jpegblip";
+ break;
+ }
+ sb.AppendFormat ("{{\\pict\\{0}\\picwgoal{1}\\pichgoal{2} ", type, width, height);
+
+ var data = picture.picture.Data;
+ data.Position = 0;
+ if (sb.Capacity - sb.Length < data.Length) {
+ sb.Capacity += (int)data.Length * 2;
+ }
+ var buffer = new byte [39];
+ int length;
+ while ((length = data.Read (buffer, 0, buffer.Length)) > 0) {
+ sb.AppendLine ().Append (GetHexChars (buffer, length));
+ }
+ sb.Append ("}");
+ }
+
+ void EmitTabStops (StringBuilder sb, TabStopCollection tabs)
+ {
+ foreach (var tab in tabs) {
+ if (tab is DecimalTabStop) {
+ sb.Append ("\\tqdec");
+ } else if (tab is CentredTabStop) {
+ sb.Append ("\\tqc");
+ } else if (tab is RightTabStop) {
+ sb.Append ("\\tqr");
+ }
+ sb.Append ("\\tx");
+ sb.Append (Int (tab.Position / document.Dpi * 1440f));
+ }
+ }
+
+ void EmitPard (StringBuilder sb, ArrayList fonts, Line line, LineTag tag, TabStopCollection tabs, float ppt)
+ {
+ var first_line_indent = -line.HangingIndent;
+ var left_indent = line.Indent - first_line_indent;
+ var right_indent = line.RightIndent;
+
+ sb.Append ("\\pard");
+ // Reset to default paragraph properties
+ switch (line.alignment) {
+ case HorizontalAlignment.Left:
+ sb.Append ("\\ql");
+ break;
+ case HorizontalAlignment.Center:
+ sb.Append ("\\qc");
+ break;
+ case HorizontalAlignment.Right:
+ sb.Append ("\\qr");
+ break;
+ }
+ if (Math.Abs (line.spacing_after) > ppt) {
+ sb.Append ("\\sa");
+ sb.Append (Int (line.spacing_after / ppt));
+ }
+ if (Math.Abs (line.spacing_before) > ppt) {
+ sb.Append ("\\sb");
+ sb.Append (Int (line.spacing_before / ppt));
+ }
+ if (Math.Abs (line.line_spacing) > ppt) {
+ sb.Append ("\\sl");
+ sb.Append (Int (line.line_spacing / ppt));
+ sb.Append ("\\slmult");
+ sb.Append (line.line_spacing_multiple ? "1" : "0");
+ }
+ if (Math.Abs (left_indent) > ppt) {
+ sb.Append ("\\li");
+ sb.Append (Int (left_indent / ppt));
+ }
+ if (Math.Abs (first_line_indent) > ppt) {
+ sb.Append ("\\fi");
+ sb.Append (Int (first_line_indent / ppt));
+ }
+ if (Math.Abs (right_indent) > ppt) {
+ sb.Append ("\\ri");
+ sb.Append (Int (right_indent / ppt));
+ }
+ if (tabs.Count > 0) {
+ EmitTabStops (sb, tabs);
+ }
+ }
+
+ static void LoadParaSettings (Line line, out HorizontalAlignment line_alignment, out float spacing_after, out float spacing_before, out float line_spacing,
+ out bool line_spacing_multiple, out float left_indent, out float prev_left_indent, out float first_line_indent,
+ out float prev_first_line_indent, out float right_indent, out TabStopCollection tabs)
+ {
+ spacing_after = line.spacing_after;
+ spacing_before = line.spacing_before;
+ line_spacing = line.line_spacing;
+ line_spacing_multiple = line.line_spacing_multiple;
+ line_alignment = line.alignment;
+ first_line_indent = -line.HangingIndent;
+ left_indent = line.Indent - first_line_indent;
+ prev_first_line_indent = first_line_indent;
+ prev_left_indent = left_indent;
+ right_indent = line.RightIndent;
+ tabs = line.TabStops;
+ }
+
// start_pos and end_pos are 0-based
private StringBuilder GenerateRTF(Line start_line, int start_pos, Line end_line, int end_pos) {
StringBuilder sb;
ArrayList fonts;
ArrayList colors;
Color color;
+ Color back_color;
Font font;
Line line;
LineTag tag;
+ TextPositioning text_position;
+ HorizontalAlignment line_alignment;
+ float spacing_after;
+ float spacing_before;
+ float line_spacing;
+ bool line_spacing_multiple;
+ float left_indent;
+ float prev_left_indent;
+ float first_line_indent;
+ float prev_first_line_indent;
+ float right_indent;
+ TabStopCollection tabs;
+ TabStopCollection tabDiff;
+ bool emit_defaults;
+ float char_offset;
+ bool visible;
int pos;
int line_no;
int line_len;
- int i;
+ int i, j;
int length;
+ float ppt; // pixels per twip
+
+ ppt = document.Dpi / 1440f; // 1 twip = 1/20 point, 1 point = 1/72 inch, thus 1440 twips = 1 inch.
+ emit_defaults = false;
sb = new StringBuilder();
fonts = new ArrayList(10);
colors = new ArrayList(10);
+ tabDiff = new TabStopCollection ();
// Two runs, first we parse to determine tables;
// and unlike most of our processing here we work on tags
@@ -1949,6 +2561,7 @@ namespace System.Windows.Forms {
tag = LineTag.FindTag(start_line, pos);
font = tag.Font;
color = tag.Color;
+ back_color = Color.Empty;
fonts.Add(font.Name);
colors.Add(color);
@@ -1972,11 +2585,18 @@ namespace System.Windows.Forms {
if (tag.Color != color) {
color = tag.Color;
- if (!colors.Contains(color)) {
+ if (color != Color.Empty && !colors.Contains (color)) {
colors.Add(color);
}
}
+ if (tag.BackColor != back_color) {
+ back_color = tag.BackColor;
+ if (back_color != Color.Empty && !colors.Contains (back_color)) {
+ colors.Add (back_color);
+ }
+ }
+
pos = tag.Start + tag.Length - 1;
tag = tag.Next;
}
@@ -2008,7 +2628,7 @@ namespace System.Windows.Forms {
// Emit the color table (if needed)
if ((colors.Count > 1) || ((((Color)colors[0]).R != this.ForeColor.R) || (((Color)colors[0]).G != this.ForeColor.G) || (((Color)colors[0]).B != this.ForeColor.B))) {
- sb.Append("{\\colortbl "); // Header and NO! default color
+ sb.Append("{\\colortbl;"); // Header and default color (default is needed)
for (i = 0; i < colors.Count; i++) {
sb.Append(String.Format("\\red{0}", ((Color)colors[i]).R));
sb.Append(String.Format("\\green{0}", ((Color)colors[i]).G));
@@ -2020,17 +2640,24 @@ namespace System.Windows.Forms {
}
sb.Append("{\\*\\generator Mono RichTextBox;}");
- // Emit initial paragraph settings
- tag = LineTag.FindTag(start_line, start_pos);
- sb.Append("\\pard"); // Reset to default paragraph properties
- EmitRTFFontProperties(sb, -1, fonts.IndexOf(tag.Font.Name), null, tag.Font); // Font properties
- sb.Append(" "); // Space separator
+ tag = LineTag.FindTag (start_line, start_pos);
font = tag.Font;
- color = (Color)colors[0];
+ color = Color.Empty;
+ back_color = Color.Empty;
+ text_position = TextPositioning.Normal;
+ char_offset = 0;
+ visible = true;
line = start_line;
line_no = start_line.line_no;
pos = start_pos;
+ LoadParaSettings (line, out line_alignment, out spacing_after, out spacing_before, out line_spacing,
+ out line_spacing_multiple, out left_indent, out prev_left_indent, out first_line_indent,
+ out prev_first_line_indent, out right_indent, out tabs);
+
+ EmitPard (sb, fonts, line, tag, tabs, ppt);
+ EmitRTFFontProperties (sb, -1, fonts.IndexOf (tag.Font.Name), null, tag.Font); // Font properties
+ sb.Append(" "); // Space separator
while (line_no <= end_line.line_no) {
line = document.GetLine(line_no);
@@ -2042,7 +2669,110 @@ namespace System.Windows.Forms {
line_len = end_pos;
}
- while (pos < line_len) {
+ i = 0;
+ j = 0;
+ tabDiff.Clear ();
+ emit_defaults = line.TabStops.Count < tabs.Count; // If there are less tabs on the new line, we've got to start over.
+ while (!emit_defaults && i < tabs.Count && j < line.TabStops.Count) {
+ if (tabs [i].Equals (line.TabStops [j])) {
+ i++;
+ j++;
+ } else if (tabs [i].Position - ppt > line.TabStops [j].Position) {
+ // The current tabstop is after the new line's one, so we need to add one in between.
+ tabDiff.Add (line.TabStops [j]);
+ j++;
+ } else {
+ // Either the tabs are at the same position and are of different types, or this line is missing at least one.
+ // This in turn means we must start the line with a \pard, and re-emit all other paragraph properties.
+ emit_defaults = true;
+ }
+ }
+ if (i < tabs.Count) // We didn't reach the end of the existing tabstops, so the rest have to be removed.
+ emit_defaults = true;
+ while (!emit_defaults && j < line.TabStops.Count) { // Any new ones have to be added on the end too.
+ tabDiff.Add (line.TabStops[j]);
+ j++;
+ }
+ tabs = line.TabStops;
+
+ if (!emit_defaults) {
+ length = sb.Length;
+ if (line.Alignment != line_alignment) {
+ line_alignment = line.Alignment;
+ switch (line_alignment) {
+ case HorizontalAlignment.Left:
+ sb.Append("\\ql");
+ break;
+ case HorizontalAlignment.Center:
+ sb.Append("\\qc");
+ break;
+ case HorizontalAlignment.Right:
+ sb.Append("\\qr");
+ break;
+ }
+ }
+
+ if (Math.Abs(line.spacing_after - spacing_after) > ppt) {
+ spacing_after = line.spacing_after;
+ sb.Append("\\sa");
+ sb.Append(Int(spacing_after / ppt));
+ }
+
+ if (Math.Abs(line.spacing_before - spacing_before) > ppt) {
+ spacing_before = line.spacing_before;
+ sb.Append("\\sb");
+ sb.Append(Int(spacing_before / ppt));
+ }
+
+ if (Math.Abs(line.line_spacing - line_spacing) > ppt) {
+ line_spacing = line.line_spacing;
+ sb.Append("\\sl");
+ sb.Append(Int(line.line_spacing / ppt));
+ }
+
+ if (line.line_spacing_multiple != line_spacing_multiple) {
+ line_spacing_multiple = line.line_spacing_multiple;
+ sb.Append("\\slmult");
+ sb.Append(line.line_spacing_multiple ? "1" : "0");
+ }
+
+ first_line_indent = -line.HangingIndent;
+ left_indent = line.Indent - first_line_indent;
+
+ if (Math.Abs(prev_left_indent - left_indent) > ppt) {
+ prev_left_indent = left_indent;
+ sb.Append("\\li");
+ sb.Append(Int(left_indent / ppt));
+ }
+
+ if (Math.Abs(prev_first_line_indent - first_line_indent) > ppt) {
+ prev_first_line_indent = first_line_indent;
+ sb.Append("\\fi");
+ sb.Append(Int(first_line_indent / ppt));
+ }
+
+ if (Math.Abs(line.right_indent - right_indent) > ppt) {
+ right_indent = line.right_indent;
+ sb.Append("\\ri");
+ sb.Append(Int(right_indent / ppt));
+ }
+
+ if (tabDiff.Count > 0) {
+ EmitTabStops(sb, tabDiff);
+ }
+
+ if (length != sb.Length) {
+ sb.Append(" ");
+ }
+ } else {
+ EmitPard (sb, fonts, line, tag, tabs, ppt);
+ sb.Append(" ");
+ LoadParaSettings (line, out line_alignment, out spacing_after, out spacing_before, out line_spacing,
+ out line_spacing_multiple, out left_indent, out prev_left_indent, out first_line_indent,
+ out prev_first_line_indent, out right_indent, out tabs);
+ }
+
+ while (pos < line_len && tag != null) {
length = sb.Length;
if (tag.Font != font) {
@@ -2052,14 +2782,65 @@ namespace System.Windows.Forms {
if (tag.Color != color) {
color = tag.Color;
- sb.Append(String.Format("\\cf{0}", colors.IndexOf(color)));
+ if (color != Color.Empty)
+ sb.Append(String.Format("\\cf{0}", colors.IndexOf(color) + 1));
+ else
+ sb.Append("\\cf0");
+ }
+
+ if (tag.BackColor != back_color) {
+ back_color = tag.BackColor;
+ if (back_color != Color.Empty)
+ sb.Append(String.Format("\\cb{0}", colors.IndexOf(back_color) + 1));
+ else
+ sb.Append("\\cb0");
+ }
+
+ if (tag.TextPosition != text_position) {
+ if (text_position != TextPositioning.Normal && tag.TextPosition != TextPositioning.Normal)
+ sb.Append("\\nosupersub");
+ // Technically it is possible to have subscripts in superscript and vise versa. But that's not what we've got.
+ text_position = tag.TextPosition;
+ switch (tag.TextPosition) {
+ case TextPositioning.Normal:
+ sb.Append("\\nosupersub");
+ break;
+ case TextPositioning.Subscript:
+ sb.Append("\\sub");
+ break;
+ case TextPositioning.Superscript:
+ sb.Append("\\super");
+ break;
+ }
+ }
+
+ if (tag.CharOffset != char_offset) {
+ char_offset = tag.CharOffset;
+ if (char_offset >= 0) {
+ sb.Append("\\up");
+ sb.Append(Int((char_offset / document.Dpi) * 144));
+ } else {
+ sb.Append("\\dn");
+ sb.Append(-Int((char_offset / document.Dpi) * 144));
+ }
+ }
+
+ if (tag.Visible != visible) {
+ visible = tag.Visible;
+ if (visible)
+ sb.Append("\\v0");
+ else
+ sb.Append("\\v");
}
+
if (length != sb.Length) {
sb.Append(" "); // Emit space to separate keywords from text
}
// Emit the string itself
- if (line_no != end_line.line_no) {
+ if (tag is PictureTag) {
+ EmitRtfPicture((PictureTag)tag, sb);
+ } else if (line_no != end_line.line_no) {
EmitRTFText(sb, tag.Line.text.ToString(pos, tag.Start + tag.Length - pos - 1));
} else {
if (end_pos < (tag.Start + tag.Length - 1)) {
@@ -2071,11 +2852,16 @@ namespace System.Windows.Forms {
}
pos = tag.Start + tag.Length - 1;
- tag = tag.Next;
+ do {
+ tag = tag.Next;
+ } while (tag != null && tag.IsTextTag && tag.Length == 0);
}
if (pos >= line.text.Length) {
if (line.ending != LineEnding.Wrap) {
- sb.Append("\\par");
+ // pos is incremented by the tag length, so it can be after where we want to finish.
+ // If we're on the last line we don't want to output \par when we're stopping before the end of the line.
+ if (!(line_no == end_line.line_no && pos > end_pos))
+ sb.Append("\\par");
sb.Append(Environment.NewLine);
}
}
@@ -2088,6 +2874,11 @@ namespace System.Windows.Forms {
return sb;
}
+
+ int Int (float f)
+ {
+ return (int)(f + 0.5f);
+ }
#endregion // Private Methods
}
}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/TabStops.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/TabStops.cs
new file mode 100644
index 00000000000..6226024cdc1
--- /dev/null
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/TabStops.cs
@@ -0,0 +1,258 @@
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2015 Karl Scowen
+//
+// Authors:
+// Karl Scowen <contact@scowencomputers.co.nz>
+//
+//
+
+using System;
+using System.Collections.Generic;
+
+namespace System.Windows.Forms {
+ abstract class TabStop : IComparable<TabStop> {
+ float _pos = -1;
+
+ internal float Position {
+ get {
+ return _pos;
+ }
+
+ set {
+ if (_pos >= 0)
+ throw new InvalidOperationException ("Can't change Position once it has been set!");
+
+ _pos = value;
+ }
+ }
+
+ internal virtual float GetInitialWidth (Line line, int pos)
+ {
+ return 0;
+ }
+
+ internal abstract float CalculateRight (Line line, int pos);
+
+ public override bool Equals (object obj)
+ {
+ return obj.GetType () == this.GetType () && Math.Abs (((TabStop)obj).Position - Position) < 0.01;
+ }
+
+ public override int GetHashCode ()
+ {
+ return this.GetType ().GetHashCode () ^ Position.GetHashCode ();
+ }
+
+ public override string ToString ()
+ {
+ return string.Format ("[{0}: Position {1}]", this.GetType().Name, Position);
+ }
+
+ #region IComparable implementation
+ public int CompareTo (TabStop other)
+ {
+ return Position.CompareTo (other.Position);
+ }
+
+ #endregion
+ }
+
+ class LeftTabStop : TabStop {
+ internal LeftTabStop ()
+ {
+ }
+ internal LeftTabStop (float position)
+ {
+ Position = position;
+ }
+
+ internal override float GetInitialWidth (Line line, int pos)
+ {
+ return Position - line.widths[pos];
+ }
+
+ internal override float CalculateRight (Line line, int pos)
+ {
+ return Position;
+ }
+ }
+
+ class CentredTabStop : TabStop {
+ internal override float CalculateRight (Line line, int pos)
+ {
+ int endIndex = line.Text.IndexOfAny (new [] {'\t', '\n', '\r'}, pos + 1); // pos is this tab's index, so look after that.
+ if (endIndex < 0)
+ endIndex = line.text.Length;
+ float textWidth = line.widths [endIndex] - line.widths [pos + 1]; // We use the position after this tabstop, hence pos + 1.
+ return Math.Max (Position - textWidth / 2f, line.widths [pos]); // We want the width until the start of the text, which is before Position, but we can't go below zero.
+ }
+ }
+
+ internal class RightTabStop : TabStop {
+ internal override float CalculateRight (Line line, int pos)
+ {
+ int endIndex = line.Text.IndexOfAny (new [] {'\t', '\n', '\r'}, pos + 1); // pos is this tab's index, so look after that.
+ return calcWidth (line, pos, endIndex);
+ }
+
+ protected float calcWidth (Line line, int pos, int endIndex)
+ {
+ if (endIndex < 0)
+ endIndex = line.text.Length;
+ float textWidth = line.widths [endIndex] - line.widths [pos + 1]; // We use the position after this tabstop, hence pos + 1.
+ return Math.Max (Position - textWidth, line.widths [pos]);
+ }
+ }
+
+ internal class DecimalTabStop : RightTabStop {
+ internal override float CalculateRight (Line line, int pos)
+ {
+ // This is simply a right-align tabstop that regards the decimal as the end.
+ int endIndex = line.Text.IndexOfAny (new [] {'\t', '\n', '\r', '.'}, pos + 1); // pos is this tab's index, so look after that.
+ return calcWidth (line, pos, endIndex);
+ }
+ }
+
+ internal class TabStopCollection : IList<TabStop> {
+ SortedList<TabStop, TabStop> tabs = new SortedList<TabStop, TabStop> ();
+
+ public TabStopCollection Clone ()
+ {
+ var n = new TabStopCollection ();
+ foreach (var tab in tabs.Keys) {
+ n.tabs.Add (tab, null);
+ }
+ return n;
+ }
+
+ public int IndexOf (TabStop tab)
+ {
+ return tabs.IndexOfKey (tab);
+ }
+
+ public void Insert (int index, TabStop item)
+ {
+ throw new NotSupportedException ("Not relevant to sorted data!");
+ }
+
+ public void RemoveAt (int index)
+ {
+ tabs.RemoveAt (index);
+ }
+
+ public TabStop this [int index] {
+ get {
+ return tabs.Keys [index];
+ }
+ set {
+ throw new NotSupportedException ("Not relevant to sorted data!");
+ }
+ }
+
+ #region ICollection implementation
+ public void Add (TabStop tab)
+ {
+ tabs.Add (tab, null);
+ }
+
+ public void Clear ()
+ {
+ tabs.Clear ();
+ }
+
+ public bool Contains (TabStop tab)
+ {
+ return tabs.ContainsKey (tab);
+ }
+
+ public void CopyTo (TabStop[] array, int arrayIndex)
+ {
+ tabs.Keys.CopyTo (array, arrayIndex);
+ }
+
+ public TabStop[] ToArray ()
+ {
+ var arr = new TabStop [Count];
+ CopyTo (arr, 0);
+ return arr;
+ }
+
+ public int[] ToPosArray ()
+ {
+ var arr = new int [Count];
+ for (int i = 0; i < Count; i++) {
+ arr [i] = (int)this [i].Position;
+ }
+ return arr;
+ }
+
+ public bool Remove (TabStop tab)
+ {
+ return tabs.Remove (tab);
+ }
+
+ public int Count {
+ get {
+ return tabs.Count;
+ }
+ }
+
+ bool ICollection<TabStop>.IsReadOnly {
+ get {
+ return false;
+ }
+ }
+ #endregion
+
+ #region IEnumerable implementation
+ public IEnumerator<TabStop> GetEnumerator ()
+ {
+ return tabs.Keys.GetEnumerator ();
+ }
+ #endregion
+
+ #region IEnumerable implementation
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+ #endregion
+
+ public override bool Equals (object obj)
+ {
+ var other = obj as TabStopCollection;
+ if (other == null || other.Count != this.Count)
+ return false;
+
+ for (int i = 0; i < Count; i++) {
+ if (!tabs.Keys [i].Equals (other.tabs.Keys [i]))
+ return false;
+ }
+ return true;
+ }
+
+ public override int GetHashCode ()
+ {
+ // I don't like warnings, but I honestly don't care about the hash code.
+ return base.GetHashCode ();
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/TextBoxBase.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/TextBoxBase.cs
index a2cc8560ffd..b4440143b76 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/TextBoxBase.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/TextBoxBase.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok pbartok@novell.com
+// Karl Scowen <contact@scowencomputers.co.nz>
//
//
@@ -116,8 +117,7 @@ namespace System.Windows.Forms
current_link = null;
show_caret_w_selection = (this is TextBox);
document = new Document(this);
- document.WidthChanged += new EventHandler(document_WidthChanged);
- document.HeightChanged += new EventHandler(document_HeightChanged);
+ document.SizeChanged += new EventHandler<Document.SizeChangedEventArgs> (document_SizeChanged);
//document.CaretMoved += new EventHandler(CaretMoved);
document.Wrap = false;
click_last = DateTime.Now;
@@ -296,8 +296,7 @@ namespace System.Windows.Forms
if (value == actual_border_style)
return;
- if (actual_border_style != BorderStyle.Fixed3D || value != BorderStyle.Fixed3D)
- Invalidate ();
+ Invalidate ();
actual_border_style = value;
document.UpdateMargins ();
@@ -617,7 +616,10 @@ namespace System.Windows.Forms
Line line = null;
for (int i = 1; i <= document.Lines; i++) {
line = document.GetLine (i);
- sb.Append(line.text.ToString ());
+ if (i == document.Lines)
+ sb.Append(line.TextWithoutEnding ());
+ else
+ sb.Append(line.text.ToString ());
}
return sb.ToString();
@@ -2043,22 +2045,24 @@ namespace System.Windows.Forms
Invalidate();
}
- internal void CalculateScrollBars ()
+ internal bool CalculateScrollBars ()
{
- // FIXME - need separate calculations for center and right alignment
+ var old_canvas_width = canvas_width;
+
SizeControls ();
- if (document.Width >= document.ViewPortWidth) {
+ if (document.Width > document.ViewPortWidth) {
hscroll.SetValues (0, Math.Max (1, document.Width), -1,
document.ViewPortWidth < 0 ? 0 : document.ViewPortWidth);
if (document.multiline)
hscroll.Enabled = true;
} else {
hscroll.Enabled = false;
+ hscroll.Value = hscroll.Minimum;
hscroll.Maximum = document.ViewPortWidth;
}
- if (document.Height >= document.ViewPortHeight) {
+ if (document.Height > document.ViewPortHeight) {
vscroll.SetValues (0, Math.Max (1, document.Height), -1,
document.ViewPortHeight < 0 ? 0 : document.ViewPortHeight);
if (document.multiline)
@@ -2109,16 +2113,16 @@ namespace System.Windows.Forms
PositionControls ();
SizeControls (); //Update sizings now we've decided whats visible
- }
- private void document_WidthChanged (object sender, EventArgs e)
- {
- CalculateScrollBars();
+ return (canvas_width != old_canvas_width);
}
- private void document_HeightChanged (object sender, EventArgs e)
+ private void document_SizeChanged (object sender, Document.SizeChangedEventArgs e)
{
- CalculateScrollBars();
+ var canvas_width_changed = CalculateScrollBars ();
+ if (e.HeightChanged && canvas_width_changed)
+ CalculateDocument (); // Viewport has changed due to the document change, update the document.
+ // TODO: technically the opposite situation could happen too, where a document width change causes a change in canvas height.
}
private void ScrollLinks (int xChange, int yChange)
@@ -2311,40 +2315,41 @@ namespace System.Windows.Forms
// If the caret moves to the left outside the visible area, we jump the document into view, not just one
// character, but 1/3 of the width of the document
// If the caret moves to the right outside the visible area, we scroll just enough to keep the caret visible
+ // For comparison, in Windows 8.1 / .Net 4:
+ // Multiline: as above, but 1/4
+ // Single line: either direction with the cursors jumps 1/4
+ // Both are irrespective of alignment.
// Handle horizontal scrolling
- if (document.CaretLine.alignment == HorizontalAlignment.Left) {
- // Check if we moved out of view to the left
- if (pos.X < (document.ViewPortX)) {
- do {
- if ((hscroll.Value - document.ViewPortWidth / 3) >= hscroll.Minimum) {
- hscroll.SafeValueSet (hscroll.Value - document.ViewPortWidth / 3);
- } else {
- hscroll.Value = hscroll.Minimum;
- }
- } while (hscroll.Value > pos.X);
- }
+ // Check if we moved out of view to the left
+ if (pos.X < (document.ViewPortX)) {
+ do {
+ var newVal = hscroll.Value - document.ViewPortWidth / 3 - 1; // - 1 so that we're guaranteed to move, even if document.ViewPortWidth is < 3.
+ if (newVal >= hscroll.Minimum) {
+ hscroll.SafeValueSet (newVal);
+ } else {
+ hscroll.Value = hscroll.Minimum;
+ }
+ } while (hscroll.Value > pos.X);
+ }
- // Check if we moved out of view to the right
- if ((pos.X >= (document.ViewPortWidth + document.ViewPortX)) && (hscroll.Value != hscroll.Maximum)) {
- if ((pos.X - document.ViewPortWidth + 1) <= hscroll.Maximum) {
- if (pos.X - document.ViewPortWidth >= 0) {
- hscroll.SafeValueSet (pos.X - document.ViewPortWidth + 1);
- } else {
- hscroll.Value = 0;
- }
+ // Check if we moved out of view to the right
+ if ((pos.X >= (document.ViewPortWidth + document.ViewPortX)) && (hscroll.Value != hscroll.Maximum)) {
+ int newVal;
+ if (Multiline) {
+ newVal = pos.X - document.ViewPortWidth + 1;
+ } else {
+ newVal = pos.X - document.ViewPortWidth * 2 / 3 + 1;
+ }
+ if (newVal <= hscroll.Maximum - document.ViewPortWidth + 1) {
+ if (newVal >= 0) {
+ hscroll.SafeValueSet (newVal);
} else {
- hscroll.Value = hscroll.Maximum;
+ hscroll.Value = 0;
}
+ } else {
+ hscroll.Value = hscroll.Maximum - document.ViewPortWidth + 1;
}
- } else if (document.CaretLine.alignment == HorizontalAlignment.Right) {
-// hscroll.Value = pos.X;
-
-// if ((pos.X > (this.canvas_width + document.ViewPortX)) && (hscroll.Enabled && (hscroll.Value != hscroll.Maximum))) {
-// hscroll.Value = hscroll.Maximum;
-// }
- } else {
- // FIXME - implement center cursor alignment
}
if (Text.Length > 0)
@@ -2354,7 +2359,10 @@ namespace System.Windows.Forms
return;
// Handle vertical scrolling
- height = document.CaretLine.Height + 1;
+ height = document.CaretLine.Height;
+
+ if (document.CaretLine.line_no < document.Lines)
+ height += 1; // Add a bit of room on the bottom if there are more lines - but don't scroll past the bottom when ther aren't.
if (pos.Y < document.ViewPortY)
vscroll.SafeValueSet (pos.Y);
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/TextControl.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/TextControl.cs
index 24859dbf3fb..cf65c990cbf 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/TextControl.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/TextControl.cs
@@ -21,6 +21,7 @@
//
// Authors:
// Peter Bartok pbartok@novell.com
+// Karl Scowen <contact@scowencomputers.co.nz>
//
//
@@ -47,6 +48,7 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.Text;
@@ -71,6 +73,17 @@ namespace System.Windows.Forms {
BackColor = 2,
Font = 4,
Color = 8,
+ TextPosition = 16,
+ CharOffset = 32,
+ Visibility = 64,
+
+ All = 126
+ }
+
+ internal enum TextPositioning {
+ Normal,
+ Superscript,
+ Subscript
}
internal enum CaretDirection {
@@ -103,7 +116,7 @@ namespace System.Windows.Forms {
None = 0
}
-
+
internal class Document : ICloneable, IEnumerable {
#region Structures
// FIXME - go through code and check for places where
@@ -224,7 +237,7 @@ namespace System.Windows.Forms {
internal int viewport_x;
internal int viewport_y; // The visible area of the document
internal int offset_x;
- internal int offset_y;
+ internal int offset_y; // Never assigned to except in constructor, and a property that is also never assigned to?
internal int viewport_width;
internal int viewport_height;
@@ -240,6 +253,8 @@ namespace System.Windows.Forms {
internal int left_margin = 2; // A left margin for all lines
internal int top_margin = 2;
internal int right_margin = 2;
+
+ internal float dpi;
#endregion // Local Variables
#region Constructors
@@ -301,6 +316,15 @@ namespace System.Windows.Forms {
#endregion
#region Internal Properties
+
+ internal float Dpi {
+ get {
+ if (dpi > 0)
+ return dpi;
+ return TextRenderer.GetDpi ().Height;
+ }
+ }
+
internal Line Root {
get {
return document;
@@ -400,7 +424,8 @@ namespace System.Windows.Forms {
internal int Length {
get {
- return char_count + lines - 1; // Add \n for each line but the last
+ var lastLine = GetLine (lines);
+ return char_count - LineEndingLength (lastLine.ending);
}
}
@@ -683,12 +708,8 @@ namespace System.Windows.Forms {
}
private void IncrementLines(int line_no) {
- int current;
-
- current = this.lines;
- while (current >= line_no) {
- GetLine(current).line_no++;
- current--;
+ foreach (var line in TransverseLines(this.lines, line_no)) {
+ line.line_no++;
}
return;
}
@@ -868,19 +889,27 @@ namespace System.Windows.Forms {
return;
}
+ var prev_line_pos = new Point(line.X, line.Y);
+ var prev_line_bottom = line.Y + line.Height;
+ var prev_pos_width = line.widths[pos];
+ float prev_pos1_width = (line.widths.Length > pos + 1) ? line.widths[pos + 1] : prev_pos_width;
+
// Optimize invalidation based on Line alignment
bool height_changed;
using (var graphics = owner.CreateGraphics())
height_changed = RecalculateDocument(graphics, line.line_no, line.line_no, true);
+ var x = Math.Min(prev_line_pos.X, line.X);
+ var y = Math.Min(prev_line_pos.Y, line.Y);
+ var h = Math.Max(prev_line_bottom, line.Y + line.Height) - y;
if (height_changed) {
// Lineheight changed, invalidate the rest of the document
- if ((line.Y - viewport_y) >=0 ) {
+ if ((y - viewport_y) >=0 ) {
// We formatted something that's in view, only draw parts of the screen
owner.Invalidate(new Rectangle(
offset_x,
- line.Y - viewport_y + offset_y,
+ y - viewport_y + offset_y,
viewport_width,
- owner.Height - (line.Y - viewport_y)));
+ owner.Height - (y - viewport_y)));
} else {
// The tag was above the visible area, draw everything
owner.Invalidate();
@@ -889,28 +918,28 @@ namespace System.Windows.Forms {
switch(line.alignment) {
case HorizontalAlignment.Left: {
owner.Invalidate(new Rectangle(
- line.X + ((int)line.widths[pos] - viewport_x - 1) + offset_x,
- line.Y - viewport_y + offset_y,
+ x + ((int)Math.Max(line.widths[pos], prev_pos_width) - viewport_x - 1) + offset_x,
+ y - viewport_y + offset_y,
viewport_width,
- line.height + 1));
+ h + 1));
break;
}
case HorizontalAlignment.Center: {
owner.Invalidate(new Rectangle(
- line.X + offset_x,
- line.Y - viewport_y + offset_y,
+ x + offset_x,
+ y - viewport_y + offset_y,
viewport_width,
- line.height + 1));
+ h + 1));
break;
}
case HorizontalAlignment.Right: {
owner.Invalidate(new Rectangle(
- line.X + offset_x,
- line.Y - viewport_y + offset_y,
- (int)line.widths[pos + 1] - viewport_x + line.X,
- line.height + 1));
+ x + offset_x,
+ y - viewport_y + offset_y,
+ (int)Math.Max(line.widths[pos + ((line.widths.Length > pos + 1) ? 1 : 0)], prev_pos1_width) - viewport_x + line.X,
+ h + 1));
break;
}
}
@@ -1248,6 +1277,14 @@ namespace System.Windows.Forms {
internal void PositionCaret(Line line, int pos) {
caret.tag = line.FindTag (pos);
+ if (pos == caret.tag.Start - 1 && caret.tag.Length != 0 && caret.tag.Previous != null)
+ caret.tag = caret.tag.Previous;
+ // When we're at a tag boundary we want the cursor in the previous (left) tag
+ // whereas FindTag(pos) gets the next (right) tag. LineTag.Start is 1-based.
+
+ if (pos > line.TextLengthWithoutEnding())
+ pos = line.TextLengthWithoutEnding();
+ // We don't want the caret after the line ending.
MoveCaretToTextTag ();
@@ -1256,20 +1293,15 @@ namespace System.Windows.Forms {
if (owner.IsHandleCreated) {
if (owner.Focused) {
- if (caret.height != caret.tag.Height)
+ if (caret.height != caret.tag.DrawnHeight) {
+ caret.height = caret.tag.DrawnHeight;
XplatUI.CreateCaret (owner.Handle, caret_width, caret.height);
- XplatUI.SetCaretPos(owner.Handle,
- offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x,
- offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+ }
+ SetCaretPos();
}
if (CaretMoved != null) CaretMoved(this, EventArgs.Empty);
}
-
- // We set this at the end because we use the heights to determine whether or
- // not we need to recreate the caret
- caret.height = caret.tag.Height;
-
}
internal void PositionCaret(int x, int y) {
@@ -1278,17 +1310,20 @@ namespace System.Windows.Forms {
}
caret.tag = FindCursor(x, y, out caret.pos);
+
+ if (caret.pos > caret.tag.Line.TextLengthWithoutEnding())
+ caret.pos = caret.tag.Line.TextLengthWithoutEnding();
+ // Don't allow the caret to be positioned after the line ending.
+ // This was happening with the up and down arrows due to how FindCursor works.
MoveCaretToTextTag ();
caret.line = caret.tag.Line;
- caret.height = caret.tag.Height;
+ caret.height = caret.tag.DrawnHeight;
if (owner.ShowSelection && (!selection_visible || owner.show_caret_w_selection)) {
XplatUI.CreateCaret (owner.Handle, caret_width, caret.height);
- XplatUI.SetCaretPos(owner.Handle,
- (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x + offset_x,
- offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+ SetCaretPos();
}
if (CaretMoved != null) CaretMoved(this, EventArgs.Empty);
@@ -1297,9 +1332,7 @@ namespace System.Windows.Forms {
internal void CaretHasFocus() {
if ((caret.tag != null) && owner.IsHandleCreated) {
XplatUI.CreateCaret(owner.Handle, caret_width, caret.height);
- XplatUI.SetCaretPos(owner.Handle,
- offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x,
- offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+ SetCaretPos();
DisplayCaret ();
}
@@ -1337,17 +1370,15 @@ namespace System.Windows.Forms {
// font is larger than the line (line recalculations
// ignore empty tags) in which case we make it equal
// the line height and then when text is entered
- if (caret.tag.Height > caret.tag.Line.Height) {
- caret.height = caret.line.height;
+ if (caret.tag.DrawnHeight > caret.tag.Line.TextHeight) {
+ caret.height = caret.line.TextHeight;
} else {
- caret.height = caret.tag.Height;
+ caret.height = caret.tag.DrawnHeight;
}
if (owner.Focused) {
XplatUI.CreateCaret(owner.Handle, caret_width, caret.height);
- XplatUI.SetCaretPos (owner.Handle,
- offset_x + (int) caret.tag.Line.widths [caret.pos] + caret.line.X - viewport_x,
- offset_y + caret.line.Y + viewport_y + caret_shift);
+ SetCaretPos();
DisplayCaret ();
}
@@ -1361,23 +1392,30 @@ namespace System.Windows.Forms {
MoveCaretToTextTag ();
- if (caret.tag.Height != caret.height) {
- caret.height = caret.tag.Height;
+ if (caret.tag.DrawnHeight != caret.height) {
+ caret.height = caret.tag.DrawnHeight;
if (owner.Focused) {
XplatUI.CreateCaret(owner.Handle, caret_width, caret.height);
}
}
if (owner.Focused) {
- XplatUI.SetCaretPos(owner.Handle,
- offset_x + (int)caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x,
- offset_y + caret.line.Y + caret.tag.Shift - viewport_y + caret_shift);
+ SetCaretPos();
DisplayCaret ();
}
if (CaretMoved != null) CaretMoved(this, EventArgs.Empty);
}
+ void SetCaretPos ()
+ {
+ XplatUI.SetCaretPos (owner.Handle,
+ (int)Math.Min(offset_x + caret.tag.Line.widths[caret.pos] + caret.line.X - viewport_x,
+ viewport_width - caret.tag.Line.right_indent - caret_width), // Limit X, because whitespace can be outside this.
+ (int)(offset_y + caret.line.Y + caret.line.SpacingBefore + caret.tag.OffsetY -
+ caret.tag.CharOffset + caret.tag.Shift - viewport_y + caret_shift));
+ }
+
internal void DisplayCaret() {
if (!owner.IsHandleCreated) {
return;
@@ -1417,6 +1455,10 @@ namespace System.Windows.Forms {
// FIXME should we use IsWordSeparator to detect whitespace, instead
// of looking for actual spaces in the Word move cases?
+ Line currentLine = caret.line;
+ int currentPos = caret.pos;
+ LineTag currentTag = caret.tag;
+
bool nowrap = false;
switch(direction) {
case CaretDirection.CharForwardNoWrap:
@@ -1444,7 +1486,7 @@ namespace System.Windows.Forms {
}
}
UpdateCaret();
- return;
+ break;
}
case CaretDirection.CharBackNoWrap:
@@ -1452,12 +1494,10 @@ namespace System.Windows.Forms {
goto case CaretDirection.CharBack;
case CaretDirection.CharBack: {
if (caret.pos > 0) {
- // caret.pos--; // folded into the if below
+ caret.pos--;
- if (--caret.pos > 0) {
- if (caret.tag.Start > caret.pos) {
- caret.tag = caret.tag.Previous;
- }
+ if (caret.tag.Start > caret.pos && caret.tag.Previous != null) {
+ caret.tag = caret.tag.Previous;
}
} else {
if (caret.line.line_no > 1 && !nowrap) {
@@ -1467,7 +1507,7 @@ namespace System.Windows.Forms {
}
}
UpdateCaret();
- return;
+ break;
}
case CaretDirection.WordForward: {
@@ -1493,7 +1533,7 @@ namespace System.Windows.Forms {
}
}
UpdateCaret();
- return;
+ break;
}
case CaretDirection.WordBack: {
@@ -1525,31 +1565,31 @@ namespace System.Windows.Forms {
}
}
UpdateCaret();
- return;
+ break;
}
case CaretDirection.LineUp: {
if (caret.line.line_no > 1) {
int pixel;
- pixel = (int)caret.line.widths[caret.pos];
+ pixel = (int)caret.line.widths[caret.pos] + caret.line.align_shift;
PositionCaret(pixel, GetLine(caret.line.line_no - 1).Y);
DisplayCaret ();
}
- return;
+ break;
}
case CaretDirection.LineDown: {
if (caret.line.line_no < lines) {
int pixel;
- pixel = (int)caret.line.widths[caret.pos];
+ pixel = (int)caret.line.widths[caret.pos] + caret.line.align_shift;
PositionCaret(pixel, GetLine(caret.line.line_no + 1).Y);
DisplayCaret ();
}
- return;
+ break;
}
case CaretDirection.Home: {
@@ -1558,7 +1598,7 @@ namespace System.Windows.Forms {
caret.tag = caret.line.tags;
UpdateCaret();
}
- return;
+ break;
}
case CaretDirection.End: {
@@ -1567,7 +1607,7 @@ namespace System.Windows.Forms {
caret.tag = LineTag.FindTag(caret.line, caret.pos);
UpdateCaret();
}
- return;
+ break;
}
case CaretDirection.PgUp: {
@@ -1576,17 +1616,20 @@ namespace System.Windows.Forms {
owner.vscroll.Value = 0;
Line line = GetLine (1);
PositionCaret (line, 0);
+ break;
}
int y_offset = caret.line.Y + caret.line.height - 1 - viewport_y;
+ int expected_y = viewport_y - viewport_height;
int index;
- LineTag top = FindCursor ((int) caret.line.widths [caret.pos],
- viewport_y - viewport_height, out index);
+ LineTag top = FindCursor ((int) caret.line.widths [caret.pos] + caret.line.align_shift,
+ expected_y, out index);
owner.vscroll.Value = Math.Min (top.Line.Y, owner.vscroll.Maximum - viewport_height);
- PositionCaret ((int) caret.line.widths [caret.pos], y_offset + viewport_y);
+ PositionCaret ((int) caret.line.widths [caret.pos] + caret.line.align_shift,
+ (expected_y >= 0) ? y_offset + viewport_y : 0);
- return;
+ break;
}
case CaretDirection.PgDn: {
@@ -1595,23 +1638,26 @@ namespace System.Windows.Forms {
owner.vscroll.Value = owner.vscroll.Maximum - viewport_height + 1;
Line line = GetLine (lines);
PositionCaret (line, line.TextLengthWithoutEnding());
+ break;
}
int y_offset = caret.line.Y - viewport_y;
+ int expected_y = viewport_y + viewport_height;
int index;
- LineTag top = FindCursor ((int) caret.line.widths [caret.pos],
- viewport_y + viewport_height, out index);
+ LineTag top = FindCursor ((int) caret.line.widths [caret.pos] + caret.line.align_shift,
+ expected_y, out index);
owner.vscroll.Value = Math.Min (top.Line.Y, owner.vscroll.Maximum - viewport_height);
- PositionCaret ((int) caret.line.widths [caret.pos], y_offset + viewport_y);
+ PositionCaret ((int) caret.line.widths [caret.pos] + caret.line.align_shift,
+ (expected_y <= document_y - viewport_height) ? y_offset + viewport_y : document_y);
- return;
+ break;
}
case CaretDirection.CtrlPgUp: {
PositionCaret(0, viewport_y);
DisplayCaret ();
- return;
+ break;
}
case CaretDirection.CtrlPgDn: {
@@ -1627,7 +1673,7 @@ namespace System.Windows.Forms {
}
PositionCaret(line, line.Text.Length);
DisplayCaret ();
- return;
+ break;
}
case CaretDirection.CtrlHome: {
@@ -1636,7 +1682,7 @@ namespace System.Windows.Forms {
caret.tag = caret.line.tags;
UpdateCaret();
- return;
+ break;
}
case CaretDirection.CtrlEnd: {
@@ -1645,7 +1691,7 @@ namespace System.Windows.Forms {
caret.tag = LineTag.FindTag(caret.line, caret.pos);
UpdateCaret();
- return;
+ break;
}
case CaretDirection.SelectionStart: {
@@ -1654,7 +1700,7 @@ namespace System.Windows.Forms {
caret.tag = selection_start.tag;
UpdateCaret();
- return;
+ break;
}
case CaretDirection.SelectionEnd: {
@@ -1663,22 +1709,38 @@ namespace System.Windows.Forms {
caret.tag = selection_end.tag;
UpdateCaret();
- return;
+ break;
}
}
+
+ if ((caret.pos != currentPos || caret.line != currentLine) && currentTag.Length == 0) {
+ // Remove the empty tag it was previously on.
+ if (currentTag.Previous != null) {
+ currentTag.Previous.Next = currentTag.Next;
+ } else if (currentTag.Next != null) {
+ // update line.tags, but don't set it to null!
+ currentLine.tags = currentTag.Next;
+ }
+ if (currentTag.Next != null)
+ currentTag.Next.Previous = currentTag.Previous;
+ }
}
internal void DumpDoc ()
{
- Console.WriteLine ("<doc lines='{0}'>", lines);
+ Console.WriteLine ("<doc lines='{0}' width='{1}' height='{2}' ownerwidth='{3}' ownerheight='{4}'>",
+ lines, document_x, document_y, owner.Width, owner.Height);
for (int i = 1; i <= lines ; i++) {
Line line = GetLine (i);
- Console.WriteLine ("<line no='{0}' ending='{1}'>", line.line_no, line.ending);
+ Console.WriteLine ("<line no='{0}' ending='{1}' x='{2}' y='{3}' width='{4}' height='{5}' indent='{6}' hanging-indent='{7}' right-indent='{8}'>",
+ line.line_no, line.ending, line.X, line.Y, line.Width, line.Height, line.Indent, line.HangingIndent, line.RightIndent);
LineTag tag = line.tags;
while (tag != null) {
- Console.Write ("\t<tag type='{0}' span='{1}->{2}' font='{3}' color='{4}'>",
- tag.GetType (), tag.Start, tag.Length, tag.Font, tag.Color);
+ Console.Write ("\t<tag type='{0}' span='{1}->{2}' font='{3}' color='{4}' position='{5}' " +
+ "charoffset='{6}' x='{7}' width='{8}' height='{11}' ascent='{9}' descent='{10}'>",
+ tag.GetType (), tag.Start, tag.Length, tag.Font, tag.Color, tag.TextPosition,
+ tag.CharOffset, tag.X, tag.Width, tag.Ascent, tag.Descent, tag.MaxHeight());
Console.Write (tag.Text ());
Console.WriteLine ("</tag>");
tag = tag.Next;
@@ -1713,7 +1775,9 @@ namespace System.Windows.Forms {
StringBuilder text; // String representing the current line
int line_no;
Color tag_color;
+ Color tag_backcolor;
Color current_color;
+ Color current_backcolor;
// First, figure out from what line to what line we need to draw
GetVisibleLineIndexes (clip, out start, out end);
@@ -1730,7 +1794,7 @@ namespace System.Windows.Forms {
/// Make sure that we aren't drawing one more line then we need to
line = GetLine (end - 1);
- if (line != null && clip.Bottom == offset_y + line.Y + line.height - viewport_y)
+ if (line != null && clip.Bottom == offset_y + line.Y + (int)line.SpacingBefore + line.height - viewport_y)
end--;
line_no = start;
@@ -1748,15 +1812,15 @@ namespace System.Windows.Forms {
g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorHighlight),
offset_x + selection_start.line.widths [selection_start.pos] +
selection_start.line.X - viewport_x,
- offset_y + selection_start.line.Y,
+ offset_y + selection_start.line.Y,
(selection_end.line.X + selection_end.line.widths [selection_end.pos]) -
(selection_start.line.X + selection_start.line.widths [selection_start.pos]),
- selection_start.line.height);
+ selection_start.line.height);
}
while (line_no <= end) {
line = GetLine (line_no);
- float line_y = line.Y - viewport_y + offset_y;
+ float line_y = line.Y - viewport_y + offset_y + line.SpacingBefore;
tag = line.tags;
if (!calc_pass) {
@@ -1792,35 +1856,28 @@ namespace System.Windows.Forms {
} else if (multiline) {
// lets draw some selection baby!! (non multiline selection is drawn outside the loop)
g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (ThemeEngine.Current.ColorHighlight),
- offset_x + line.widths [line_selection_start - 1] + line.X - viewport_x,
- line_y, line.widths [line_selection_end - 1] - line.widths [line_selection_start - 1],
- line.height);
+ offset_x + line.widths [line_selection_start - 1] + line.X - viewport_x, line_y - line.SpacingBefore,
+ line.widths [line_selection_end - 1] - line.widths [line_selection_start - 1], line.height);
}
}
- current_color = line.tags.ColorToDisplay;
while (tag != null) {
// Skip empty tags
- if (tag.Length == 0) {
+ if (tag.Length == 0 || !tag.Visible) {
tag = tag.Next;
continue;
}
- if (((tag.X + tag.Width) < (clip.Left - viewport_x - offset_x)) &&
- (tag.X > (clip.Right - viewport_x - offset_x))) {
+ if (((tag.X + tag.Width) < (clip.Left + viewport_x - offset_x)) ||
+ (tag.X > (clip.Right + viewport_x - offset_x))) {
+ // Don't draw a tag that is horizontally outside the visible region.
tag = tag.Next;
continue;
}
- if (tag.BackColor != Color.Empty) {
- g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (tag.BackColor),
- offset_x + tag.X + line.X - viewport_x,
- line_y + tag.Shift, tag.Width, line.height);
- }
-
tag_color = tag.ColorToDisplay;
- current_color = tag_color;
+ tag_backcolor = tag.BackColor;
if (!owner.Enabled) {
Color a = tag.Color;
@@ -1832,26 +1889,36 @@ namespace System.Windows.Forms {
}
int tag_pos = tag.Start;
- current_color = tag_color;
while (tag_pos < tag.Start + tag.Length) {
int old_tag_pos = tag_pos;
if (tag_pos >= line_selection_start && tag_pos < line_selection_end) {
current_color = ThemeEngine.Current.ColorHighlightText;
tag_pos = Math.Min (tag.End, line_selection_end);
+ current_backcolor = Color.Empty;
} else if (tag_pos < line_selection_start) {
current_color = tag_color;
tag_pos = Math.Min (tag.End, line_selection_start);
+ current_backcolor = tag_backcolor;
} else {
current_color = tag_color;
tag_pos = tag.End;
+ current_backcolor = tag_backcolor;
+ }
+
+ if (current_backcolor != Color.Empty && current_backcolor != owner.BackColor) {
+ g.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (current_backcolor),
+ offset_x + line.widths [old_tag_pos - 1] + line.X - viewport_x,
+ line_y - line.SpacingBefore,
+ line.widths [Math.Min (tag.Start + tag.Length, tag_pos) - 1] - line.widths [old_tag_pos - 1],
+ line.height);
}
Rectangle text_size;
tag.Draw (g, current_color,
offset_x + line.X - viewport_x,
- line_y + tag.Shift,
+ line_y + tag.Shift - tag.CharOffset,
old_tag_pos - 1, Math.Min (tag.Start + tag.Length, tag_pos) - 1,
text.ToString (), out text_size, tag.IsLink);
@@ -1975,7 +2042,21 @@ namespace System.Windows.Forms {
internal void Insert (Line line, int pos, bool update_caret, string s)
{
- Insert (line, pos, update_caret, s, line.FindTag (pos));
+ LineTag tag = line.FindTag(pos);
+ if (tag.Length != 0) {
+ if (tag.Start == pos + 1) { // pos is zero-based, tag.Start and tag.End are one-based.
+ // Check for empty tags before this one at the same position
+ var t = tag.Previous;
+ while (t != null && t.End == pos + 1) {
+ if (t.Length == 0) {
+ tag = t;
+ break;
+ }
+ t = t.Previous;
+ }
+ } // There will never be empty tags after this one, because FindTag gets the last tag at the position.
+ }
+ Insert (line, pos, update_caret, s, tag);
}
// Insert text at the given position; use formatting at insertion point for inserted text
@@ -2004,9 +2085,11 @@ namespace System.Windows.Forms {
// There are no line feeds in our text to be pasted
if (break_index == s.Length) {
line.InsertString (pos, s, tag);
+ CharCount += s.Length;
} else {
// Add up to the first line feed to our current position
line.InsertString (pos, s.Substring (0, break_index + LineEndingLength (ending)), tag);
+ CharCount += break_index + LineEndingLength (ending);
// Split the rest of the original line to a new line
Split (line, pos + (break_index + LineEndingLength (ending)));
@@ -2035,15 +2118,13 @@ namespace System.Windows.Forms {
// Add the remainder of the insert text to the split
// part of the original line
+ CharCount += s.Length - break_index;
split_line.InsertString (0, s.Substring (break_index));
}
// Allow the document to recalculate things
ResumeRecalc (false);
- // Update our character count
- CharCount += s.Length;
-
UpdateView (line, lines - old_line_count + 1, pos);
// Move the caret to the end of the inserted text if requested
@@ -2191,8 +2272,15 @@ namespace System.Windows.Forms {
if (!multiline) {
UpdateView (line, lines, pos);
owner.Invalidate ();
- } else
+ } else {
+ if (line.line_no > 1) {
+ // If the previous line is wrapped, we update that too in case the wrap point has changed.
+ var l = GetLine(line.line_no - 1);
+ if (l != null && (l.ending == LineEnding.None || l.ending == LineEnding.Wrap))
+ line = l;
+ }
UpdateView (line, pos);
+ }
}
// Deletes a character at or after the given position (depending on forward); it will not delete past line limits
@@ -2349,7 +2437,9 @@ namespace System.Windows.Forms {
// cover the easy case first
if (pos == line.text.Length) {
- Add (line.line_no + 1, String.Empty, line.alignment, tag.Font, tag.Color, line.ending);
+ Add (line.line_no + 1, String.Empty, line.alignment, tag.Font, tag.Color, tag.BackColor, tag.TextPosition,
+ tag.CharOffset, line.Indent, line.HangingIndent, line.RightIndent, line.spacing_before, line.spacing_after,
+ line.line_spacing, line.line_spacing_multiple, line.tab_stops, tag.Visible, line.ending);
new_line = GetLine (line.line_no + 1);
@@ -2382,7 +2472,10 @@ namespace System.Windows.Forms {
}
// We need to move the rest of the text into the new line
- Add (line.line_no + 1, line.text.ToString (pos, line.text.Length - pos), line.alignment, tag.Font, tag.Color, line.ending);
+ Add (line.line_no + 1, line.text.ToString (pos, line.text.Length - pos), line.alignment, tag.Font, tag.Color,
+ tag.BackColor, tag.TextPosition, tag.CharOffset, line.Indent, line.HangingIndent, line.RightIndent,
+ line.spacing_before, line.spacing_after, line.line_spacing, line.line_spacing_multiple, line.tab_stops,
+ tag.Visible, line.ending);
// Now transfer our tags from this line to the next
new_line = GetLine(line.line_no + 1);
@@ -2515,12 +2608,19 @@ namespace System.Windows.Forms {
internal void Add (int LineNo, string Text, HorizontalAlignment align, Font font, Color color, LineEnding ending)
{
+ Add (LineNo, Text, align, font, color, Color.Empty, TextPositioning.Normal,
+ 0, 0, 0, 0, 0, 0, 0, false, new TabStopCollection(), true, ending);
+ }
+
+ internal void Add (int LineNo, string Text, HorizontalAlignment align, Font font, Color color, Color back_color,
+ TextPositioning text_position, float char_offset, float left_indent, float hanging_indent,
+ float right_indent, float spacing_before, float spacing_after, float line_spacing,
+ bool line_spacing_multiple, TabStopCollection tab_stops, bool visible, LineEnding ending)
+ {
Line add;
Line line;
int line_no;
- CharCount += Text.Length;
-
if (LineNo<1 || Text == null) {
if (LineNo<1) {
throw new ArgumentNullException("LineNo", "Line numbers must be positive");
@@ -2529,7 +2629,10 @@ namespace System.Windows.Forms {
}
}
- add = new Line (this, LineNo, Text, align, font, color, ending);
+ CharCount += Text.Length;
+
+ add = new Line (this, LineNo, Text, align, font, color, back_color, text_position, char_offset, left_indent,
+ hanging_indent, right_indent, spacing_before, spacing_after, line_spacing, line_spacing_multiple, tab_stops, visible, ending);
line = document;
while (line != sentinel) {
@@ -2598,7 +2701,7 @@ namespace System.Windows.Forms {
Delete (line);
}
- private void Delete(Line line1) {
+ internal void Delete(Line line1) {
Line line2;// = new Line();
Line line3;
@@ -3202,7 +3305,9 @@ namespace System.Windows.Forms {
int selection_start_pos = LineTagToCharIndex (selection_start.line, selection_start.pos);
SuspendRecalc ();
- // First, delete any selected text
+ var formatTag = selection_start.tag;
+
+ // Delete any selected text
if ((selection_start.pos != selection_end.pos) || (selection_start.line != selection_end.line)) {
if (selection_start.line == selection_end.line) {
undo.RecordDeleteString (selection_start.line, selection_start.pos, selection_end.line, selection_end.pos);
@@ -3244,9 +3349,23 @@ namespace System.Windows.Forms {
}
}
+ if (!String.IsNullOrEmpty(s)) {
+ int old_line_count = lines;
+ Insert(selection_start.line, selection_start.pos, false, s);
+ Line end_line;
+ int end_pos;
+ if (lines == old_line_count) {
+ end_line = selection_start.line;
+ end_pos = selection_start.pos + s.Length + 1;
+ } else {
+ end_line = GetLine(selection_start.line.line_no + lines - old_line_count);
+ end_pos = end_line.text.Length;
+ }
+ FormatText(selection_start.line, selection_start.pos + 1, end_line, end_pos, formatTag); // 0-base to 1-base...
+ undo.RecordInsertString(selection_start.line, selection_start.pos, s);
+ }
+
- Insert(selection_start.line, selection_start.pos, false, s);
- undo.RecordInsertString (selection_start.line, selection_start.pos, s);
Line begin_update_line = selection_start.line;
int begin_update_pos = selection_start.pos;
@@ -3279,6 +3398,11 @@ namespace System.Windows.Forms {
ResumeRecalc (false);
PositionCaret (selection_start.line, selection_start.pos);
+
+ if (begin_update_line.line_no > selection_start.line.line_no) {
+ begin_update_line = selection_start.line;
+ begin_update_pos = selection_start.pos;
+ }
UpdateView (begin_update_line, selection_end.line.line_no - begin_update_line.line_no, begin_update_pos);
}
@@ -3297,7 +3421,7 @@ namespace System.Windows.Forms {
start = chars;
chars += line.text.Length;
- if (index <= chars) {
+ if (index < chars) {
// we found the line
tag = line.tags;
@@ -3410,6 +3534,56 @@ namespace System.Windows.Forms {
return null;
}
+ internal IEnumerable<Line> TransverseLines (int start, int end)
+ {
+ Line l, c, r, prev = null;
+ bool r2l = start > end;
+ int number;
+ if (r2l) {
+ // swap start and end so that start is less than end
+ int s = start;
+ start = end;
+ end = s;
+ }
+ c = document;
+ while (c != null && c != sentinel) {
+ l = c.left;
+ r = c.right;
+
+ if (((r2l && c.line_no < end) || (!r2l && c.line_no > start)) && (r2l ? r : l) != sentinel && (r2l ? r : l) != prev) {
+ // There's no point going further this way if we're just finding lines we don't want!
+ c = r2l ? r : l;
+ continue;
+ }
+
+ number = c.line_no;
+ if (number >= start && number <= end)
+ yield return c;
+
+ if ((r2l && number <= start) || (!r2l && number >= end))
+ yield break; // We're done here, no need to look further.
+
+ if ((r2l ? l : r) != sentinel) {
+ c = r2l ? l : r;
+ } else {
+ // If we're on the first-side node, the parent is finished with too (continues up tree), otherwise we're only done with the current node.
+ // We don't want to come back to first-side nodes we've already done when we do the new parent.
+ // The highest node we discard is going to be a first-side node, because we're discarding all second-side nodes we run into.
+ // The exception is when we run off the top, which is just fine too, because we're done.
+ // But the highest node we discard is already visited, so that is the one we're not allowed back to -- anything higher needs visiting still.
+ prev = c;
+ c = c.parent;
+ // The xor inverts the condition when we're going right-to-left, and therefore trims non-right (i.e. left) branches.
+ // With both forwards and reverse transversal, prev will be given the first-side node.
+ while (c != null && c.parent != null && c.right == prev ^ r2l) {
+ prev = c;
+ c = c.parent;
+ }
+ // And prev is now the previous first-side node, unless we happen to have none remaining!
+ }
+ }
+ }
+
/// <summary>Retrieve the previous tag; walks line boundaries</summary>
internal LineTag PreviousTag(LineTag tag) {
Line l;
@@ -3539,30 +3713,45 @@ namespace System.Windows.Forms {
return tag;
}
+ public void FormatText (Line start_line, int start_pos, Line end_line, int end_pos, LineTag copyFrom) {
+ FormatText(start_line, start_pos, end_line, end_pos, copyFrom.Font, copyFrom.Color,
+ copyFrom.BackColor, copyFrom.TextPosition, copyFrom.CharOffset, copyFrom.Visible, FormatSpecified.All);
+ }
+
+ internal void FormatText (Line start_line, int start_pos, Line end_line, int end_pos, Font font,
+ Color color, Color back_color, FormatSpecified specified)
+ {
+ FormatText (start_line, start_pos, end_line, end_pos, font, color, back_color,
+ TextPositioning.Normal, 0, true, specified);
+ }
+
/// <summary>Format area of document in specified font and color</summary>
/// <param name="start_pos">1-based start position on start_line</param>
/// <param name="end_pos">1-based end position on end_line </param>
internal void FormatText (Line start_line, int start_pos, Line end_line, int end_pos, Font font,
- Color color, Color back_color, FormatSpecified specified)
+ Color color, Color back_color, TextPositioning text_position, float char_offset,
+ bool visible, FormatSpecified specified)
{
Line l;
// First, format the first line
if (start_line != end_line) {
// First line
- LineTag.FormatText(start_line, start_pos, start_line.text.Length - start_pos + 1, font, color, back_color, specified);
+ LineTag.FormatText(start_line, start_pos, start_line.text.Length - start_pos + 1, font, color,
+ back_color, text_position, char_offset, visible, specified);
// Format last line
- LineTag.FormatText(end_line, 1, end_pos, font, color, back_color, specified);
+ LineTag.FormatText(end_line, 1, end_pos - 1, font, color, back_color, text_position, char_offset, visible, specified);
// Now all the lines inbetween
for (int i = start_line.line_no + 1; i < end_line.line_no; i++) {
l = GetLine(i);
- LineTag.FormatText(l, 1, l.text.Length, font, color, back_color, specified);
+ LineTag.FormatText(l, 1, l.text.Length, font, color, back_color, text_position, char_offset, visible, specified);
}
} else {
// Special case, single line
- LineTag.FormatText(start_line, start_pos, end_pos - start_pos, font, color, back_color, specified);
+ LineTag.FormatText(start_line, start_pos, end_pos - start_pos, font, color, back_color,
+ text_position, char_offset, visible, specified);
if ((end_pos - start_pos) == 0 && CaretTag.Length != 0)
CaretTag = CaretTag.Next;
@@ -3582,17 +3771,7 @@ namespace System.Windows.Forms {
line = GetLine(line_no);
if (line != null) {
- switch (line.alignment) {
- case HorizontalAlignment.Left:
- line.align_shift = 0;
- break;
- case HorizontalAlignment.Center:
- line.align_shift = (viewport_width - (int)line.widths[line.text.Length]) / 2;
- break;
- case HorizontalAlignment.Right:
- line.align_shift = viewport_width - (int)line.widths[line.text.Length] - right_margin;
- break;
- }
+ line.CalculateAlignment();
}
line_no++;
@@ -3623,6 +3802,8 @@ namespace System.Windows.Forms {
int new_width;
bool changed;
int shift;
+ bool width_changed;
+ bool height_changed;
if (recalc_suspended > 0) {
recalc_pending = true;
@@ -3641,6 +3822,8 @@ namespace System.Windows.Forms {
line_no = start;
new_width = 0;
shift = this.lines;
+ width_changed = false;
+ height_changed = false;
if (!optimize) {
changed = true; // We always return true if we run non-optimized
} else {
@@ -3677,17 +3860,10 @@ namespace System.Windows.Forms {
}
if (line.widths[line.text.Length] > new_width) {
- new_width = (int)line.widths[line.text.Length];
+ new_width = (int)Math.Ceiling(line.widths[line.text.Length]);
}
- // Calculate alignment
- if (line.alignment != HorizontalAlignment.Left) {
- if (line.alignment == HorizontalAlignment.Center) {
- line.align_shift = (viewport_width - (int)line.widths[line.text.Length]) / 2;
- } else {
- line.align_shift = viewport_width - (int)line.widths[line.text.Length] - 1;
- }
- }
+ line.CalculateAlignment ();
if (multiline)
offset += line.height;
@@ -3701,22 +3877,22 @@ namespace System.Windows.Forms {
if (document_x != new_width) {
document_x = new_width;
- if (WidthChanged != null) {
- WidthChanged(this, null);
- }
+ width_changed = true;
}
- RecalculateAlignments();
-
line = GetLine(lines);
if (document_y != line.Y + line.height) {
document_y = line.Y + line.height;
- if (HeightChanged != null) {
- HeightChanged(this, null);
- }
+ height_changed = true;
+ }
+
+ if (height_changed || width_changed) {
+ SizeChanged?.Invoke (this, new SizeChangedEventArgs(height_changed));
}
+ RecalculateAlignments ();
+
// scan for links and tell us if its all
// changed, so we can update everything
if (EnableLinks)
@@ -3731,13 +3907,15 @@ namespace System.Windows.Forms {
}
private void owner_HandleCreated(object sender, EventArgs e) {
- using (var graphics = owner.CreateGraphics())
+ using (var graphics = owner.CreateGraphics()) {
+ dpi = (graphics.DpiX + graphics.DpiY) / 2;
RecalculateDocument(graphics);
+ }
AlignCaret();
}
private void owner_VisibleChanged(object sender, EventArgs e) {
- if (owner.Visible) {
+ if (owner.Visible && owner.IsHandleCreated) {
using (var graphics = owner.CreateGraphics())
RecalculateDocument(graphics);
}
@@ -4031,9 +4209,17 @@ namespace System.Windows.Forms {
#endregion // Internal Methods
#region Events
+ internal class SizeChangedEventArgs : EventArgs {
+ public bool HeightChanged { get; }
+
+ public SizeChangedEventArgs (bool HeightChanged)
+ {
+ this.HeightChanged = HeightChanged;
+ }
+ }
+
internal event EventHandler CaretMoved;
- internal event EventHandler WidthChanged;
- internal event EventHandler HeightChanged;
+ internal event EventHandler<SizeChangedEventArgs> SizeChanged;
internal event EventHandler LengthChanged;
internal event EventHandler UIASelectionChanged;
#endregion // Events
@@ -4089,7 +4275,10 @@ namespace System.Windows.Forms {
public override SizeF SizeOfPosition (Graphics dc, int pos)
{
- return picture.Size;
+ if (Visible)
+ return picture.Size;
+ else
+ return SizeF.Empty;
}
internal override int MaxHeight ()
@@ -4099,12 +4288,24 @@ namespace System.Windows.Forms {
public override void Draw (Graphics dc, Color color, float xoff, float y, int start, int end)
{
- picture.DrawImage (dc, xoff + Line.widths [start], y, false);
+ if (Visible)
+ picture.DrawImage (dc, (xoff + Line.widths [start]), y, false);
}
public override void Draw (Graphics dc, Color color, float xoff, float y, int start, int end, string text)
{
- picture.DrawImage (dc, xoff + + Line.widths [start], y, false);
+ Draw (dc, color, xoff, y, start, end);
+ }
+
+ public override void Draw (Graphics dc, Color color, float xoff, float y, int start, int end,
+ string text, out Rectangle measuredText, bool measureText)
+ {
+ Draw (dc, color, xoff, y, start, end);
+ if (measureText && Visible) {
+ measuredText = new Rectangle (Point.Round (new PointF (xoff + Line.widths [start], y)), Size.Round (picture.Size));
+ } else {
+ measuredText = new Rectangle ();
+ }
}
public override string Text ()
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripDropDown.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripDropDown.cs
index 33eb3c50b99..2bf32495378 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripDropDown.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripDropDown.cs
@@ -383,26 +383,36 @@ namespace System.Windows.Forms
[EditorBrowsable (EditorBrowsableState.Never)]
public new void Show ()
{
- Show (Location, DefaultDropDownDirection);
+ Show (Location);
+ }
+
+ public void Show (int x, int y)
+ {
+ Show (new Point (x, y));
}
public void Show (Point screenLocation)
{
+ SetOwnerControl (null);
Show (screenLocation, DefaultDropDownDirection);
}
-
+
+ public void Show (Control control, int x, int y)
+ {
+ Show (control, new Point (x, y));
+ }
+
public void Show (Control control, Point position)
{
- if (control == null)
- throw new ArgumentNullException ("control");
-
- XplatUI.SetOwner (Handle, control.Handle);
- Show (control.PointToScreen (position), DefaultDropDownDirection);
+ Show (control, position, DefaultDropDownDirection);
}
- public void Show (int x, int y)
+ public void Show (Control control, Point position, ToolStripDropDownDirection direction)
{
- Show (new Point (x, y), DefaultDropDownDirection);
+ if (control == null)
+ throw new ArgumentNullException ("control");
+ SetOwnerControl (control);
+ Show (control.PointToScreen (position), direction);
}
public void Show (Point position, ToolStripDropDownDirection direction)
@@ -522,26 +532,17 @@ namespace System.Windows.Forms
this.OnOpened (EventArgs.Empty);
}
-
- public void Show (Control control, int x, int y)
- {
- if (control == null)
- throw new ArgumentNullException ("control");
- Show (control, new Point (x, y));
- }
-
- public void Show (Control control, Point position, ToolStripDropDownDirection direction)
- {
- if (control == null)
- throw new ArgumentNullException ("control");
-
- XplatUI.SetOwner (Handle, control.Handle);
- Show (control.PointToScreen (position), direction);
- }
#endregion
#region Protected Methods
+
+ protected virtual void SetOwnerControl (Control ownerControl)
+ {
+ var ownerControlHandle = (ownerControl == null) ? IntPtr.Zero : ownerControl.Handle;
+ XplatUI.SetOwner (Handle, ownerControlHandle);
+ }
+
protected override AccessibleObject CreateAccessibilityInstance ()
{
return new ToolStripDropDownAccessibleObject (this);
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs
index 4df33979088..7a60ac82f29 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/ToolStripMenuItem.cs
@@ -419,10 +419,8 @@ namespace System.Windows.Forms
if (item.Owner == null)
return null;
- if (item.Owner is ContextMenuStrip) {
- Control container = ((ContextMenuStrip)item.Owner).container;
- return container == null ? null : container.TopLevelControl;
- }
+ if (item.Owner is ContextMenuStrip ownerContextMenuStrip)
+ return ownerContextMenuStrip.SourceControl?.TopLevelControl;
// MainMenuStrip
return item.Owner.TopLevelControl;
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms/TreeView.cs b/mcs/class/System.Windows.Forms/System.Windows.Forms/TreeView.cs
index 74d77f5f80f..a66f82ccc36 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms/TreeView.cs
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms/TreeView.cs
@@ -1419,7 +1419,7 @@ namespace System.Windows.Forms {
private void Draw (Rectangle clip, Graphics dc)
{
- dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (BackColor), clip);
+ dc.FillRectangle (BackColorBrush, clip);
if (dash == null)
CreateDashPen ();
@@ -1670,7 +1670,6 @@ namespace System.Windows.Forms {
{
if (!full_row_select || show_lines)
DrawSelectionAndFocus(node, dc, node.Bounds);
-
Font font = node.NodeFont;
if (node.NodeFont == null)
@@ -1691,7 +1690,7 @@ namespace System.Windows.Forms {
int middle = y + (ActualItemHeight / 2);
if (full_row_select && !show_lines) {
- Rectangle r = new Rectangle (1, y, ViewportRectangle.Width - 2, ActualItemHeight);
+ var r = new Rectangle (1, y, ViewportRectangle.Width - 2, ActualItemHeight);
DrawSelectionAndFocus (node, dc, r);
}
@@ -1716,26 +1715,25 @@ namespace System.Windows.Forms {
}
if (draw_mode != TreeViewDrawMode.Normal) {
- dc.FillRectangle (Brushes.White, node.Bounds);
- TreeNodeStates tree_node_state = TreeNodeStates.Default;;
+ dc.FillRectangle (BackColorBrush, node.Bounds);
+
+ var tree_node_state = TreeNodeStates.Default;;
if (node.IsSelected)
tree_node_state = TreeNodeStates.Selected;
if (node.Checked)
tree_node_state |= TreeNodeStates.Checked;
if (node == focused_node)
tree_node_state |= TreeNodeStates.Focused;
- Rectangle node_bounds = node.Bounds;
- if (draw_mode == TreeViewDrawMode.OwnerDrawText) {
- node_bounds.X += 3;
- node_bounds.Y += 1;
- } else {
+
+ var node_bounds = node.Bounds;
+ if (draw_mode != TreeViewDrawMode.OwnerDrawText) {
node_bounds.X = 0;
node_bounds.Width = Width;
}
- DrawTreeNodeEventArgs e = new DrawTreeNodeEventArgs (dc, node, node_bounds, tree_node_state);
+ var e = new DrawTreeNodeEventArgs (dc, node, node_bounds, tree_node_state);
- OnDrawNode (e);
+ OnDrawNode (e);
if (!e.DrawDefault)
return;
}
diff --git a/mcs/class/System.Windows.Forms/System.Windows.Forms_test.dll.sources b/mcs/class/System.Windows.Forms/System.Windows.Forms_test.dll.sources
index a4045f284ea..c9eb6898556 100644
--- a/mcs/class/System.Windows.Forms/System.Windows.Forms_test.dll.sources
+++ b/mcs/class/System.Windows.Forms/System.Windows.Forms_test.dll.sources
@@ -26,6 +26,7 @@ System.Windows.Forms/Common.cs
System.Windows.Forms/CommonDialogsTest.cs
System.Windows.Forms/ContainerControlTest.cs
System.Windows.Forms/ContextMenuTest.cs
+System.Windows.Forms/ContextMenuStripTest.cs
System.Windows.Forms/ControlBindingsCollectionTest.cs
System.Windows.Forms/ControlBindingsConverterTest.cs
System.Windows.Forms/ControlCollectionTest.cs
diff --git a/mcs/class/System.Windows.Forms/Test/System.Windows.Forms/ContextMenuStripTest.cs b/mcs/class/System.Windows.Forms/Test/System.Windows.Forms/ContextMenuStripTest.cs
new file mode 100644
index 00000000000..f5f62d6d330
--- /dev/null
+++ b/mcs/class/System.Windows.Forms/Test/System.Windows.Forms/ContextMenuStripTest.cs
@@ -0,0 +1,166 @@
+//
+// ContextMenuTestStrip.cs: Test cases for ContextMenuStrip
+//
+// Author:
+// Nikita Voronchev (nikita.voronchev@ru.axxonsoft.com)
+//
+// (C) 2020 AxxonSoft (https://www.axxonsoft.com/)
+//
+
+using System;
+using System.Drawing;
+using System.Windows.Forms;
+using NUnit.Framework;
+
+namespace MonoTests.System.Windows.Forms
+{
+ // TODO:
+ // -- Tests around `OwnerItem`.
+
+ [TestFixture]
+ public class ContextMenuStripTest : TestHelper
+ {
+ static TestExtendedForm form;
+ static Label explicitMenuSrcLabel;
+ static TestExtendedLabel testExtendedLabel;
+ static ContextMenuStrip contextMenuStrip;
+
+ static readonly Lazy<Control>[] testCaseExplicitMenuSources = new Lazy<Control>[] {
+ new Lazy<Control>(() => null),
+ new Lazy<Control>(() => explicitMenuSrcLabel)
+ }; // Involve `Lazy` to use `TestCaseSource` attribute.
+
+ static readonly Lazy<ITestExtendedControl>[] testCaseAssociatedControls = new Lazy<ITestExtendedControl>[] {
+ new Lazy<ITestExtendedControl>(() => form),
+ new Lazy<ITestExtendedControl>(() => testExtendedLabel)
+ }; // Involve `Lazy` to use `TestCaseSource` attribute.
+
+ [SetUp]
+ public void SetUp()
+ {
+ form = new TestExtendedForm ();
+ explicitMenuSrcLabel = new Label ();
+ testExtendedLabel = new TestExtendedLabel ();
+ contextMenuStrip = new ContextMenuStrip ();
+
+ form.ShowInTaskbar = false;
+ form.Controls.Add (explicitMenuSrcLabel);
+ form.Controls.Add (testExtendedLabel);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ contextMenuStrip.Close ();
+ form.Controls.Clear ();
+
+ contextMenuStrip.Dispose ();
+ testExtendedLabel.Dispose ();
+ explicitMenuSrcLabel.Dispose ();
+ form.Dispose ();
+ }
+
+ [Test, TestCaseSource ("testCaseExplicitMenuSources")]
+ public void DirectShowTest01 (Lazy<Control> explicitMenuSrc)
+ {
+ AssingOwner (explicitMenuSrc.Value);
+ contextMenuStrip.Show ();
+ Assert.IsNull (contextMenuStrip.SourceControl, "SourceControl");
+ }
+
+ [Test, TestCaseSource ("testCaseExplicitMenuSources")]
+ public void DirectShowTest02 (Lazy<Control> explicitMenuSrc)
+ {
+ AssingOwner (explicitMenuSrc.Value);
+ contextMenuStrip.Show (form, Point.Empty);
+ Assert.AreEqual (form, contextMenuStrip.SourceControl, "SourceControl");
+ }
+
+ [Test, TestCaseSource ("testCaseExplicitMenuSources")]
+ public void DirectShowTest03 (Lazy<Control> explicitMenuSrc)
+ {
+ AssingOwner (explicitMenuSrc.Value);
+ contextMenuStrip.Show (explicitMenuSrcLabel, Point.Empty);
+ Assert.AreEqual (explicitMenuSrcLabel, contextMenuStrip.SourceControl, "SourceControl");
+ }
+
+ [Test, TestCaseSource ("testCaseExplicitMenuSources")]
+ public void DirectShowTest04 (Lazy<Control> explicitMenuSrc)
+ {
+ AssingOwner (explicitMenuSrc.Value);
+ contextMenuStrip.Show (testExtendedLabel, Point.Empty);
+ Assert.AreEqual (testExtendedLabel, contextMenuStrip.SourceControl, "SourceControl");
+ }
+
+ [Test, TestCaseSource ("testCaseExplicitMenuSources")]
+ public void DirectShowTest05 (Lazy<Control> explicitMenuSrc)
+ {
+ AssingOwner (explicitMenuSrc.Value);
+ contextMenuStrip.Show (form, Point.Empty);
+ contextMenuStrip.Close ();
+ contextMenuStrip.Show ();
+ Assert.IsNull (contextMenuStrip.SourceControl, "SourceControl");
+ }
+
+ [Test, TestCaseSource("testCaseAssociatedControls")]
+ public void ContextShowTest (Lazy<ITestExtendedControl> associatedControl)
+ {
+ bool menuHasBeenOpened = false;
+ contextMenuStrip.Opened += (sender, args) => { menuHasBeenOpened = true; };
+
+ var assCtrl = associatedControl.Value;
+ assCtrl.ContextMenuStrip = contextMenuStrip;
+
+ Assert.IsFalse (menuHasBeenOpened, "menuHasBeenOpened");
+ assCtrl.EmulateWmContextMenu ();
+ Assert.IsTrue (menuHasBeenOpened, "menuHasBeenOpened");
+ Assert.AreEqual (assCtrl, contextMenuStrip.SourceControl, "SourceControl");
+
+ }
+
+ #region Helpers
+
+ private void AssingOwner (Control explicitMenuSrc)
+ {
+ if (explicitMenuSrc != null)
+ explicitMenuSrc.ContextMenuStrip = contextMenuStrip;
+ }
+
+ public interface ITestExtendedControl
+ {
+ void EmulateWmContextMenu ();
+ ContextMenuStrip ContextMenuStrip { set; }
+ }
+
+ class TestExtendedForm : Form, ITestExtendedControl
+ {
+ public void EmulateWmContextMenu ()
+ {
+ var m = TestExtendedControlHelper.MakeWmContextMenu ();
+ WndProc (ref m);
+ }
+ }
+
+ class TestExtendedLabel : Label, ITestExtendedControl
+ {
+ public void EmulateWmContextMenu ()
+ {
+ var m = TestExtendedControlHelper.MakeWmContextMenu ();
+ WndProc (ref m);
+ }
+ }
+
+ static class TestExtendedControlHelper
+ {
+ public static Message MakeWmContextMenu ()
+ {
+ return new Message () {
+ Msg = (int)Msg.WM_CONTEXTMENU,
+ LParam = IntPtr.Zero
+ };
+ }
+ }
+
+ #endregion // end of Helpers
+ }
+}
diff --git a/mcs/class/corlib/ReferenceSources/Buffer.cs b/mcs/class/corlib/ReferenceSources/Buffer.cs
index f89199219b5..5c83291cf5c 100644
--- a/mcs/class/corlib/ReferenceSources/Buffer.cs
+++ b/mcs/class/corlib/ReferenceSources/Buffer.cs
@@ -86,14 +86,14 @@ namespace System
var src = (byte*)source;
var dst = (byte*)destination;
- while (sourceBytesToCopy > int.MaxValue) {
- Memcpy (dst, src, int.MaxValue);
- sourceBytesToCopy -= int.MaxValue;
- src += int.MaxValue;
- dst += int.MaxValue;
+ while (sourceBytesToCopy > uint.MaxValue) {
+ Memmove (dst, src, uint.MaxValue);
+ sourceBytesToCopy -= uint.MaxValue;
+ src += uint.MaxValue;
+ dst += uint.MaxValue;
}
- Memcpy (dst, src, (int) sourceBytesToCopy);
+ Memmove (dst, src, (uint) sourceBytesToCopy);
}
[CLSCompliantAttribute (false)]
@@ -105,14 +105,14 @@ namespace System
var src = (byte*)source;
var dst = (byte*)destination;
- while (sourceBytesToCopy > int.MaxValue) {
- Memcpy (dst, src, int.MaxValue);
- sourceBytesToCopy -= int.MaxValue;
- src += int.MaxValue;
- dst += int.MaxValue;
+ while (sourceBytesToCopy > uint.MaxValue) {
+ Memmove (dst, src, uint.MaxValue);
+ sourceBytesToCopy -= uint.MaxValue;
+ src += uint.MaxValue;
+ dst += uint.MaxValue;
}
- Memcpy (dst, src, (int) sourceBytesToCopy);
+ Memmove (dst, src, (uint) sourceBytesToCopy);
}
internal static unsafe void memcpy4 (byte *dest, byte *src, int size) {
diff --git a/mcs/class/corlib/Test/System/BufferTest.cs b/mcs/class/corlib/Test/System/BufferTest.cs
index 120f75bd435..06ad188180d 100644
--- a/mcs/class/corlib/Test/System/BufferTest.cs
+++ b/mcs/class/corlib/Test/System/BufferTest.cs
@@ -297,5 +297,27 @@ namespace MonoTests.System {
Assert.AreEqual (0xAABB0000, b, "#2");
}
}
+
+ [Test] // https://github.com/mono/mono/issues/18516
+ public unsafe void MemoryCopy_Overlapped ()
+ {
+ byte [] buffer = new byte [5];
+ for (int i = 0; i < buffer.Length; i++)
+ buffer [i] = (byte)i;
+
+ int bytesToCopy = buffer.Length - 1;
+ fixed (byte* pBuffer = buffer)
+ Buffer.MemoryCopy (pBuffer, pBuffer + 1, buffer.Length - 1, bytesToCopy);
+
+ bool failed = false;
+ for (int i = 0; i < buffer.Length; i++)
+ {
+ byte expectedByte = (byte)(i == 0 ? 0 : i - 1);
+ if (buffer [i] != expectedByte)
+ failed = true;
+ }
+
+ Assert.IsFalse (failed);
+ }
}
}
diff --git a/sdks/wasm/Mono.WebAssembly.DebuggerProxy/DebugStore.cs b/sdks/wasm/Mono.WebAssembly.DebuggerProxy/DebugStore.cs
index c8494518ad7..1088307b338 100644
--- a/sdks/wasm/Mono.WebAssembly.DebuggerProxy/DebugStore.cs
+++ b/sdks/wasm/Mono.WebAssembly.DebuggerProxy/DebugStore.cs
@@ -10,6 +10,7 @@ using Mono.Cecil.Pdb;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using System.Threading;
namespace WebAssembly.Net.Debugging {
internal class BreakPointRequest {
@@ -24,7 +25,9 @@ namespace WebAssembly.Net.Debugging {
public static BreakPointRequest Parse (JObject args, DebugStore store)
{
- if (args == null)
+ // Events can potentially come out of order, so DebugStore may not be initialized
+ // The BP being set in these cases are JS ones, which we can safely ignore
+ if (args == null || store == null)
return null;
var url = args? ["url"]?.Value<string> ();
@@ -492,6 +495,7 @@ namespace WebAssembly.Net.Debugging {
}
internal class DebugStore {
+ MonoProxy proxy;
List<AssemblyInfo> assemblies = new List<AssemblyInfo> ();
HttpClient client = new HttpClient ();
@@ -500,7 +504,7 @@ namespace WebAssembly.Net.Debugging {
public Task<byte[][]> Data { get; set; }
}
- public async Task Load (string [] loaded_files)
+ public async Task Load (SessionId sessionId, string [] loaded_files, CancellationToken token)
{
static bool MatchPdb (string asm, string pdb)
=> Path.ChangeExtension (asm, "pdb") == pdb;
@@ -525,6 +529,15 @@ namespace WebAssembly.Net.Debugging {
});
} catch (Exception e) {
Console.WriteLine ($"Failed to read {url} ({e.Message})");
+ var o = JObject.FromObject (new {
+ entry = new {
+ source = "other",
+ level = "warning",
+ text = $"Failed to read {url} ({e.Message})"
+ }
+ });
+ proxy.SendEvent (sessionId, "Log.entryAdded", o, token);
+
}
}
@@ -547,7 +560,7 @@ namespace WebAssembly.Net.Debugging {
public AssemblyInfo GetAssemblyByName (string name)
=> assemblies.FirstOrDefault (a => a.Name.Equals (name, StringComparison.InvariantCultureIgnoreCase));
- /*
+ /*
V8 uses zero based indexing for both line and column.
PPDBs uses one based indexing for both line and column.
*/
@@ -600,7 +613,7 @@ namespace WebAssembly.Net.Debugging {
PPDBs uses one based indexing for both line and column.
*/
static bool Match (SequencePoint sp, int line, int column)
- {
+ {
var bp = (line: line + 1, column: column + 1);
if (sp.StartLine > bp.line || sp.EndLine < bp.line)
diff --git a/sdks/wasm/Mono.WebAssembly.DebuggerProxy/MonoProxy.cs b/sdks/wasm/Mono.WebAssembly.DebuggerProxy/MonoProxy.cs
index 9cdb0549002..623cdeb0353 100644
--- a/sdks/wasm/Mono.WebAssembly.DebuggerProxy/MonoProxy.cs
+++ b/sdks/wasm/Mono.WebAssembly.DebuggerProxy/MonoProxy.cs
@@ -596,7 +596,7 @@ namespace WebAssembly.Net.Debugging {
var the_pdbs = the_value?.ToObject<string[]> ();
store = new DebugStore ();
- await store.Load(the_pdbs);
+ await store.Load(sessionId, the_pdbs, token);
}
async Task RuntimeReady (SessionId sessionId, CancellationToken token)