コード例 #1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Does the find.
        /// </summary>
        /// <param name="tss">The original string.</param>
        /// <param name="tag">Tag</param>
        /// ------------------------------------------------------------------------------------
        protected virtual void DoFind(ITsString tss, int tag)
        {
            m_textSourceInit.SetString(tss, m_vc, m_sda.WritingSystemFactory);

            IVwTextSource textSource = m_textSourceInit as IVwTextSource;
            int           ichBegin   = 0;

            if (m_StartLocation != null)
            {
                Debug.Assert(m_StartLocation.TopLevelHvo == m_hvoCurr && m_StartLocation.m_tag == tag);
                ichBegin = m_StartLocation.m_ichLim;
            }

            int ichMin, ichLim;

            // When we re-wrote the find stuff to use this FindCollectorEnv, we removed some
            // whacky code from the FwFindReplaceDlg to try to deal with a sporadic failure
            // reported as TE-4085. We're no longer even calling the same method on vwPattern,
            // but if this failure ever recurs, this is probably the place where we'd want to
            // put a try/catch block so we could retry the find.
            m_Pattern.FindIn(textSource, ichBegin, tss.Length, true, out ichMin,
                             out ichLim, null);
            if (PassedLimit(tag, ichMin))
            {
                m_fHitLimit = true;
                return;
            }
            if (ichMin >= 0)
            {
                m_LocationFound = new LocationInfo(m_stack, CountOfPrevPropAtRoot, tag,
                                                   ichMin, ichLim);
            }
        }
コード例 #2
0
ファイル: ParaBuilder.cs プロジェクト: vkarthim/FieldWorks
        /// <summary>
        /// Return the writing system of the character at the specified offset in the source.
        /// </summary>
        static int WsInSource(int ich, IVwTextSource source)
        {
            LgCharRenderProps chrp;
            int ichMin, ichLim;

            source.GetCharProps(ich, out chrp, out ichMin, out ichLim);
            return(chrp.ws);
        }
コード例 #3
0
        public void FindBreakPoint(IVwGraphics vg, IVwTextSource _ts, IVwJustifier _vjus, int ichMin, int ichLim,
                                   int ichLimBacktrack, bool fNeedFinalBreak, bool fStartLine, int dxMaxWidth, LgLineBreak lbPref,
                                   LgLineBreak lbMax, LgTrailingWsHandling twsh, bool fParaRightToLeft,
                                   out ILgSegment segRet, out int dichLimSeg, out int dxWidth, out LgEndSegmentType est, ILgSegment _segPrev)
        {
            MockSegment seg;
            var         key = new MockSegKey(ichMin, ichLim);

            if (lbPref != LgLineBreak.klbClipBreak && m_failOnPartialLine.Contains(key))
            {
                // fail.
                segRet     = null;
                dichLimSeg = 0;
                dxWidth    = 0;
                est        = LgEndSegmentType.kestNothingFit;
                return;
            }
            if (m_potentialSegs.TryGetValue(key, out seg))
            {
                if (seg.Width < dxMaxWidth)                 // otherwise we meant it for the next line.
                {
                    segRet     = seg;
                    dichLimSeg = seg.get_Lim(ichMin);
                    dxWidth    = seg.get_Width(ichMin, vg);
                    est        = seg.EndSegType;
                    return;
                }
            }
            switch (OtherSegPolicy)
            {
            case UnexpectedSegments.DontFit:
            default:                     // to make compiler happy
                Assert.AreNotEqual(LgLineBreak.klbClipBreak, lbMax,
                                   "FindBreakPoint called with unexpected arguments.");
                // If we aren't pre-prepared for the requested break, assume nothing fits with these arguments.
                segRet     = null;
                dichLimSeg = 0;
                dxWidth    = 0;
                est        = LgEndSegmentType.kestNothingFit;
                break;

            case UnexpectedSegments.MakeOneCharSeg:
                // Make a very narrow segment that will fit and allow more stuff. This will usually give a test failure if not intentional.
                seg = new MockSegment(1, 2, 1, LgEndSegmentType.kestOkayBreak);
                // If we aren't pre-prepared for the requested break, assume nothing fits with these arguments.
                segRet     = seg;
                dichLimSeg = 1;
                dxWidth    = 2;
                est        = LgEndSegmentType.kestOkayBreak;
                break;
            }
        }
コード例 #4
0
		public void FindBreakPoint(IVwGraphics vg, IVwTextSource _ts, IVwJustifier _vjus, int ichMin, int ichLim,
			int ichLimBacktrack, bool fNeedFinalBreak, bool fStartLine, int dxMaxWidth, LgLineBreak lbPref,
			LgLineBreak lbMax, LgTrailingWsHandling twsh, bool fParaRightToLeft,
			out ILgSegment segRet, out int dichLimSeg, out int dxWidth, out LgEndSegmentType est, ILgSegment _segPrev)
		{

			MockSegment seg;
			var key = new MockSegKey(ichMin, ichLim);
			if (lbPref != LgLineBreak.klbClipBreak && m_failOnPartialLine.Contains(key))
			{
				// fail.
				segRet = null;
				dichLimSeg = 0;
				dxWidth = 0;
				est = LgEndSegmentType.kestNothingFit;
				return;
			}
			if (m_potentialSegs.TryGetValue(key, out seg))
			{
				if (seg.Width < dxMaxWidth) // otherwise we meant it for the next line.
				{
					segRet = seg;
					dichLimSeg = seg.get_Lim(ichMin);
					dxWidth = seg.get_Width(ichMin, vg);
					est = seg.EndSegType;
					return;
				}
			}
			switch(OtherSegPolicy)
			{
				case UnexpectedSegments.DontFit:
				default: // to make compiler happy
					Assert.AreNotEqual(LgLineBreak.klbClipBreak, lbMax,
									   "FindBreakPoint called with unexpected arguments.");
					// If we aren't pre-prepared for the requested break, assume nothing fits with these arguments.
					segRet = null;
					dichLimSeg = 0;
					dxWidth = 0;
					est = LgEndSegmentType.kestNothingFit;
					break;
				case UnexpectedSegments.MakeOneCharSeg:
					// Make a very narrow segment that will fit and allow more stuff. This will usually give a test failure if not intentional.
					seg = new MockSegment(1, 2, 1, LgEndSegmentType.kestOkayBreak);
					// If we aren't pre-prepared for the requested break, assume nothing fits with these arguments.
					segRet = seg;
					dichLimSeg = 1;
					dxWidth = 2;
					est = LgEndSegmentType.kestOkayBreak;
					break;
			}
		}
コード例 #5
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Does the find or replace.
        /// </summary>
        /// <param name="tss">The original string.</param>
        /// <returns>The replaced string.</returns>
        /// ------------------------------------------------------------------------------------
        private ITsString DoReplace(ITsString tss)
        {
            if (tss == null || tss.Length == 0)
            {
                return(null);
            }

            m_textSourceInit.SetString(tss, m_vc, m_sda.WritingSystemFactory);

            IVwTextSource textSource = m_textSourceInit as IVwTextSource;
            int           ichMinLog, ichLimLog;
            ITsStrBldr    tsb   = null;
            int           cch   = tss.Length; // length of old string
            int           delta = 0;          // length difference between new and old string

            for (int ichStartLog = 0; ichStartLog <= cch;)
            {
                m_Pattern.FindIn(textSource, ichStartLog, cch, true, out ichMinLog, out ichLimLog, null);
                if (ichMinLog < 0)
                {
                    break;
                }
                if (tsb == null)
                {
                    tsb = tss.GetBldr();
                }

                if (IsEditable(tss, ichMinLog, ichLimLog))
                {
                    delta += ReplaceString(tsb, tss, ichMinLog, ichLimLog, m_Pattern.ReplacementText,
                                           delta, m_fEmptySearch, m_Pattern.MatchOldWritingSystem);
                    m_cReplace++;
                }
                ichStartLog = ichLimLog;
            }

            if (tsb == null)
            {
                return(null);
            }

            return(tsb.GetString().get_NormalizedForm(FwNormalizationMode.knmNFD));
        }
コード例 #6
0
        private int GetLimInSameWs(int ichMin, IVwTextSource source, int ichLimBacktrack)
        {
            LgCharRenderProps chrpThis;
            int ichMinRun, ichLimWs;

            source.GetCharProps(ichMin, out chrpThis, out ichMinRun, out ichLimWs);
            while (ichLimWs < ichLimBacktrack)
            {
                int ichLimRunNext;
                LgCharRenderProps chrpNext;
                source.GetCharProps(ichMinRun, out chrpNext, out ichMinRun, out ichLimRunNext);
                if (chrpNext.ws != chrpThis.ws)
                {
                    break;
                }
                ichLimWs  = ichLimRunNext;
                ichMinRun = ichLimRunNext;
            }
            return(ichLimWs);
        }
コード例 #7
0
ファイル: BulkEditBar.cs プロジェクト: sillsdev/FieldWorks
		public ReplaceWithMethod(FdoCache cache, ISilDataAccessManaged sda, FieldReadWriter accessor, XmlNode spec, IVwPattern pattern, ITsString replacement)
			: base(cache, sda, accessor, spec)
		{
			m_pattern = pattern;
			m_replacement = replacement;
			m_pattern.ReplaceWith = m_replacement;
			m_textSourceInit = VwStringTextSourceClass.Create();
			m_ts = m_textSourceInit as IVwTextSource;
		}
コード例 #8
0
ファイル: ParaBuilder.cs プロジェクト: sillsdev/FieldWorks
		/// <summary>
		/// Return the writing system of the character at the specified offset in the source.
		/// </summary>
		static int WsInSource(int ich, IVwTextSource source)
		{
			LgCharRenderProps chrp;
			int ichMin, ichLim;
			source.GetCharProps(ich, out chrp, out ichMin, out ichLim);
			return chrp.ws;
		}
コード例 #9
0
ファイル: RecordFilter.cs プロジェクト: sillsdev/WorldPad
		private void Init()
		{
			m_textSourceInit = VwStringTextSourceClass.Create();
			m_ts = m_textSourceInit as IVwTextSource;

			if(m_pattern == null)
				m_pattern = VwPatternClass.Create();
		}
コード例 #10
0
        /// <summary>
        /// Emulate what a real renderer will do, assuming character widths are as determined by CharWidth,
        /// and only space is a valid line break.
        /// Including width of white space:
        /// Basically, if the white space is known to end the line, we don't count its width.
        /// - If we stopped mid-line because of a hard break, ichLim{backtracking} != source length, etc.,
        /// we will try to put more on line, so must include space width.
        /// - If we stop at the very end of the whole paragraph, don't include it? But then how can IP be after
        /// final space?
        /// - If we know next stuff must go on another line leave out its width.
        /// </summary>
        public void FindBreakPoint(IVwGraphics vg, IVwTextSource source, IVwJustifier justifier,
                                   int ichMin, int ichLim, int ichLimBacktrack, bool fNeedFinalBreak, bool fStartLine, int dxMaxWidth,
                                   LgLineBreak lbPref, LgLineBreak lbMax, LgTrailingWsHandling twsh, bool fParaRightToLeft,
                                   out ILgSegment segRet, out int dichLimSeg, out int dxWidth, out LgEndSegmentType est, ILgSegment segPrev)
        {
            // Default return values in case we cannot make a segment.
            segRet     = null;
            dichLimSeg = 0;
            dxWidth    = 0;
            est        = LgEndSegmentType.kestNothingFit;

            int    width     = 0;
            int    lastSpace = -1;
            string input;
            int    cchRead = ichLim - ichMin;

            if (fNeedFinalBreak)
            {
                cchRead++;
            }
            using (ArrayPtr ptr = new ArrayPtr((cchRead) * 2 + 2))
            {
                source.Fetch(ichMin, ichMin + cchRead, ptr.IntPtr);
                input = MarshalEx.NativeToString(ptr, cchRead, true);
            }
            int widthAtLastSpace = 0;

            int ichLimWs = GetLimInSameWs(ichMin, source, ichLimBacktrack);

            FakeSegment result = null;
            // limit in input of characters we may include in segment.
            int limit         = Math.Min(ichLimBacktrack, ichLimWs) - ichMin;
            int limWholeInput = ichLim - ichMin;
            int ichInput      = 0;

            if (twsh == LgTrailingWsHandling.ktwshOnlyWs)
            {
                result = MakeWhiteSpaceOnlySegment(input, width, ichInput, limit);
            }
            else             // mixed allowed or no-white-space
            {
                // Advance past what will fit, keeping track of the last good break position (white space).
                for (; ichInput < limit; ichInput++)
                {
                    if (input[ichInput] == ' ')
                    {
                        lastSpace        = ichInput;
                        widthAtLastSpace = width;
                    }
                    var charWidth = CharWidth(input[ichInput]);
                    if (width + charWidth > dxMaxWidth)
                    {
                        break;
                    }
                    width += charWidth;
                }
                Debug.Assert(width <= dxMaxWidth);                 // loop never allows it to exceed max
                if (ichInput < input.Length && input[ichInput] == ' ')
                {
                    // good break exactly at limit
                    lastSpace        = ichInput;
                    widthAtLastSpace = width;
                }

                if (ichInput == limit && ichLimBacktrack >= ichLimWs)                 // all the text in our WS fit; also handles special case of zero-char range
                {
                    // everything we were allowed to include fit; if it wasn't absolutely everything caller needs to decide
                    // about break.
                    if (twsh == LgTrailingWsHandling.ktwshAll)
                    {
                        result = new FakeSegment(input.Substring(0, limit), width, Ws,
                                                 ichInput == limWholeInput ? LgEndSegmentType.kestNoMore : LgEndSegmentType.kestWsBreak);
                    }
                    else
                    {
                        // must be no-trailing-white-space (all WS is handled above). strip off any trailing spaces.
                        while (ichInput > 0 && input[ichInput - 1] == ' ')
                        {
                            ichInput--;
                            width -= CharWidth(' ');
                        }
                        if (ichInput == limit)                         // no trailing ws removed (also handles empty run)
                        {
                            result = new FakeSegment(input.Substring(0, limit), width, Ws,
                                                     ichInput == limWholeInput ? LgEndSegmentType.kestNoMore : LgEndSegmentType.kestWsBreak); // all fit
                        }
                        else if (ichInput > 0)                                                                                                // got some text, stripped some white space
                        {
                            result = new FakeSegment(input.Substring(0, ichInput), width, Ws, LgEndSegmentType.kestMoreWhtsp);
                        }
                        else
                        {
                            // we're not done with the whole input, but no non-white at start
                            return;
                        }
                    }
                }
                else                 // some stuff we wanted to put on line didn't fit;
                if (lastSpace >= 0)  // there's a good break we can use
                {
                    int end = lastSpace;
                    if (twsh == LgTrailingWsHandling.ktwshAll)
                    {
                        // include trailing spaces without increasing width; they 'disappear' into line break.
                        while (end < limit && input[end] == ' ')
                        {
                            end++;
                        }
                    }
                    result = new FakeSegment(input.Substring(0, end), widthAtLastSpace, Ws,
                                             LgEndSegmentType.kestMoreLines);
                }
                else if (lbMax == LgLineBreak.klbWordBreak)
                {
                    // we needed a word break and didn't get one.
                    return;
                }
                else
                {
                    // remaining possibility is that we need to make some sort of segment with at least one character.
                    // (if we don't have any i = limit = 0 and we take another branch).
                    if (ichInput == 0)
                    {
                        width += CharWidth(input[ichInput]);
                        ichInput++;                                 // must have at least one character
                    }
                    result = new FakeSegment(input.Substring(ichInput), width, Ws, LgEndSegmentType.kestMoreLines);
                }
            }
            if (result == null)
            {
                return;
            }
            segRet        = result;
            dichLimSeg    = result.Length;
            dxWidth       = result.Width;
            est           = result.EndSegType;
            result.Height = SegmentHeight;
            result.Ascent = SegmentAscent;
            // DirectionDepth is usually 0 for LTR text in an LTR paragraph.
            // For RTL text, however, it is always 1.
            // And for UPSTREAM LTR text (in an RTL paragraph) it has to be 2.
            if (RightToLeft)
            {
                result.DirectionDepth = 1;
            }
            else if (fParaRightToLeft)
            {
                result.DirectionDepth = 2;
            }
        }