Ejemplo n.º 1
0
        private static bool GetRangeLocationInBox(Box box, IVwGraphics vg, PaintTransform ptrans, int top, int bottom, int ichMin, int ichLim,
                                                  bool first, ref Rect bounds)
        {
            var sb = box as StringBox;

            if (sb == null)
            {
                return(first);                // didn't get one here, no change to first
            }
            PaintTransform segTrans = ptrans.PaintTransformOffsetBy(sb.Left, sb.Top);
            Rect           bounds1;

            if (sb.Segment.PositionOfRange(sb.IchMin, vg, segTrans.SourceRect,
                                           segTrans.DestRect, ichMin, ichLim, top, bottom, true, out bounds1) &&
                bounds1.right > bounds1.left)
            {
                if (first)
                {
                    bounds = bounds1;
                }
                else
                {
                    bounds = new Rect(Math.Min(bounds.left, bounds1.left),
                                      Math.Min(bounds.top, bounds1.top),
                                      Math.Max(bounds.right, bounds1.right),
                                      Math.Max(bounds.bottom, bounds1.bottom));
                }
                return(false);        // got first rectangle, no longer looking for first one
            }
            return(first);            // didn't get one yet, no change to first.
        }
Ejemplo n.º 2
0
        internal void DrawIp(InsertionPoint ip, IVwGraphics vg, PaintTransform ptrans)
        {
            PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);

            Segment.DrawInsertionPoint(IchMin, vg, segTrans.SourceRect, segTrans.DestRect,
                                       ip.RenderParaPosition, ip.AssociatePrevious, true, LgIPDrawMode.kdmNormal);
        }
Ejemplo n.º 3
0
        // Do a range-painting operation (actual painting, or measuring, which involve much of the same work
        // except for the innermost step) for a given range of rendered characters.
        // This may be called for an actual range, or for an insertion point rendered as a substitute prompt.
        private void DoRangePaintingOp(int ichMin, int ichLim, IVwGraphics vg, PaintTransform ptrans, RangePaintingOp op)
        {
            if (Lines.Count == 0)
            {
                return;
            }
            PaintTransform childTrans     = ptrans.PaintTransformOffsetBy(Left, Top);
            var            previousBottom = childTrans.ToPaintY(Lines[0].Top);

            for (int i = 0; i < Lines.Count; i++)
            {
                var line   = Lines[i];
                var bottom = line.Bottom;
                if (i != Lines.Count - 1)
                {
                    bottom = (Lines[i + 1].Top + bottom) / 2;                     // split the difference between this line and the next
                }
                bottom = childTrans.ToPaintY(bottom);
                foreach (var box in line.Boxes)
                {
                    op(box, vg, childTrans, previousBottom, bottom, ichMin, ichLim);
                }
                previousBottom = bottom;
            }
        }
Ejemplo n.º 4
0
        internal override Selection MakeSelectionAt(Point where, IVwGraphics vg, PaintTransform ptrans)
        {
            var  segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
            int  ich;
            bool assocPrev;

            Segment.PointToChar(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, where, out ich, out assocPrev);
            return(Paragraph.SelectAt(ich, assocPrev));
        }
Ejemplo n.º 5
0
        internal void DrawRange(int ichMin, int ichLim, IVwGraphics vg, PaintTransform ptrans, int topOfLine, int bottomOfLine)
        {
            PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);

            // Todo JohnT: here or in client we need to handle ranges that don't start and end in this paragraph.
            // Todo JohnT: the last true appears to be what the old Views code normally passes, but there may be some case where
            // we should pass false.
            // Todo JohnT: passing the top and bottom of the string box as ydTop and ydBottom will not work when we have specified line spacing.
            Segment.DrawRange(IchMin, vg, segTrans.SourceRect, segTrans.DestRect,
                              ichMin, ichLim, topOfLine, bottomOfLine, true, true);
        }
Ejemplo n.º 6
0
        public override void PaintForeground(IVwGraphics vg, PaintTransform ptrans)
        {
            if (Segment == null)
            {
                return;
            }
            int            dxdWidth;
            PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);

            if (AnyColoredBackground)
            {
                Segment.DrawTextNoBackground(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, out dxdWidth);
            }
            else
            {
                Segment.DrawText(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, out dxdWidth);                 // more efficient.
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        ///  Get the IP location, if in this segment; if not return a dummy rectangle and 'here' will be false.
        /// </summary>
        public Rectangle GetIpLocation(InsertionPoint ip, IVwGraphics vg, PaintTransform ptrans, out bool here)
        {
            PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
            Rect           rectPrimary, rectSec;
            bool           fPrimaryHere, fSecHere;

            Segment.PositionsOfIP(IchMin, vg, segTrans.SourceRect, segTrans.DestRect,
                                  ip.RenderParaPosition, ip.AssociatePrevious, LgIPDrawMode.kdmNormal, out rectPrimary,
                                  out rectSec,
                                  out fPrimaryHere, out fSecHere);
            if (fPrimaryHere)
            {
                here = true;
                return(new Rectangle(rectPrimary.left, rectPrimary.top, rectPrimary.right - rectPrimary.left,
                                     rectPrimary.bottom - rectPrimary.top));
            }
            here = false;
            return(new Rectangle());
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Draw an insertion point. Currently every segment is given the chance to draw it, though typically only one will.
        /// Sometimes a split insertion point may be drawn at an unexpected place.
        /// Enhance JohnT: Support Graphite by passing other draw modes when there is a split cursor at segment boundaries.
        /// </summary>
        public void DrawIp(InsertionPoint ip, IVwGraphics vg, PaintTransform ptrans)
        {
            PaintTransform childTrans = ptrans.PaintTransformOffsetBy(Left, Top);
            int            ichMin     = ip.RenderParaPosition;
            int            ichLim     = ip.LastRenderParaPosition;

            if (ichLim > ichMin)
            {
                // Displaying a substitute string.
                DoRangePaintingOp(ichMin, ichLim, vg, ptrans, DrawSelectionInBox);
                return;
            }
            for (Box current = FirstBox; current != null; current = current.Next)
            {
                var sb = current as StringBox;
                if (sb == null)
                {
                    continue;
                }
                sb.DrawIp(ip, vg, childTrans);
            }
        }
Ejemplo n.º 9
0
		internal override Selection MakeSelectionAt(Point where, IVwGraphics vg, PaintTransform ptrans)
		{
			var segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			int ich;
			bool assocPrev;
			Segment.PointToChar(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, where, out ich, out assocPrev);
			return Paragraph.SelectAt(ich, assocPrev);
		}
Ejemplo n.º 10
0
		// Do a range-painting operation (actual painting, or measuring, which involve much of the same work
		// except for the innermost step) for a given range of rendered characters.
		// This may be called for an actual range, or for an insertion point rendered as a substitute prompt.
		private void DoRangePaintingOp(int ichMin, int ichLim, IVwGraphics vg, PaintTransform ptrans, RangePaintingOp op)
		{
			if (Lines.Count == 0)
				return;
			PaintTransform childTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			var previousBottom = childTrans.ToPaintY(Lines[0].Top);
			for (int i = 0; i < Lines.Count; i++)
			{
				var line = Lines[i];
				var bottom = line.Bottom;
				if (i != Lines.Count - 1)
					bottom = (Lines[i + 1].Top + bottom) / 2; // split the difference between this line and the next
				bottom = childTrans.ToPaintY(bottom);
				foreach (var box in line.Boxes)
				{
					op(box, vg, childTrans, previousBottom, bottom, ichMin, ichLim);
				}
				previousBottom = bottom;
			}
		}
Ejemplo n.º 11
0
		/// <summary>
		/// Draw an insertion point. Currently every segment is given the chance to draw it, though typically only one will.
		/// Sometimes a split insertion point may be drawn at an unexpected place.
		/// Enhance JohnT: Support Graphite by passing other draw modes when there is a split cursor at segment boundaries.
		/// </summary>
		public void DrawIp(InsertionPoint ip, IVwGraphics vg, PaintTransform ptrans)
		{
			PaintTransform childTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			int ichMin = ip.RenderParaPosition;
			int ichLim = ip.LastRenderParaPosition;
			if (ichLim > ichMin)
			{
				// Displaying a substitute string.
				DoRangePaintingOp(ichMin, ichLim, vg, ptrans, DrawSelectionInBox);
				return;
			}
			for (Box current = FirstBox; current != null; current = current.Next)
			{
				var sb = current as StringBox;
				if (sb == null)
					continue;
				sb.DrawIp(ip, vg, childTrans);
			}
		}
Ejemplo n.º 12
0
		internal void DrawIp(InsertionPoint ip, IVwGraphics vg, PaintTransform ptrans)
		{
			PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			Segment.DrawInsertionPoint(IchMin, vg, segTrans.SourceRect, segTrans.DestRect,
				ip.RenderParaPosition, ip.AssociatePrevious, true, LgIPDrawMode.kdmNormal);

		}
Ejemplo n.º 13
0
		private static bool GetRangeLocationInBox(Box box, IVwGraphics vg, PaintTransform ptrans, int top, int bottom, int ichMin, int ichLim,
			bool first, ref Rect bounds)
		{
			var sb = box as StringBox;
			if (sb == null)
				return first; // didn't get one here, no change to first
			PaintTransform segTrans = ptrans.PaintTransformOffsetBy(sb.Left, sb.Top);
			Rect bounds1;
			if (sb.Segment.PositionOfRange(sb.IchMin, vg, segTrans.SourceRect,
					segTrans.DestRect, ichMin, ichLim, top, bottom, true, out bounds1)
				&& bounds1.right > bounds1.left)
			{
				if (first)
				{
					bounds = bounds1;
				}
				else
				{
					bounds = new Rect(Math.Min(bounds.left, bounds1.left),
						Math.Min(bounds.top, bounds1.top),
						Math.Max(bounds.right, bounds1.right),
						Math.Max(bounds.bottom, bounds1.bottom));
				}
				return false; // got first rectangle, no longer looking for first one
			}
			return first; // didn't get one yet, no change to first.
		}
Ejemplo n.º 14
0
        public override void PaintBackground(IVwGraphics vg, PaintTransform ptrans)
        {
            // Review JohnT: do we want to allow individual strings to paint borders etc? Should we call base?
            // base.PaintBackground(vg, ptrans);
            if (Segment == null)
            {
                return;
            }

            int            dxdWidth;
            PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);

            // Ideally, we'd just draw the background, but we don't have that capability currently.
            // The current implementation of DrawTextNoBackground does a good job of redrawing
            // the foreground text, even if it's already been painted.
            if (AnyColoredBackground)
            {
                Segment.DrawText(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, out dxdWidth);
            }
            int dichLim   = Segment.get_Lim(IchMin);
            int ichLim    = IchMin + dichLim;
            int ichMinRun = IchMin;
            int ichLimRun;
            int dydOffset = Math.Max(1, segTrans.DpiY / 96);           // distance between double underline, also up and down for squiggle.

            for (; ichMinRun < ichLim; ichMinRun = ichLimRun)
            {
                int clrUnder;
                var unt = Paragraph.Source.GetUnderlineInfo(ichMinRun, out clrUnder, out ichLimRun);
                ichLimRun = Math.Min(ichLimRun, ichLim);
                Debug.Assert(ichLimRun > ichMinRun);
                if (unt == FwUnderlineType.kuntNone)
                {
                    continue;
                }
                // Get info about where to draw underlines for this run
                //int ydApproxUnderline = rcSrcChild.MapYTo(psbox->Ascent(), rcDst);
                //// GetCharPlacement seems to be the really expensive part of underlining; don't do it
                //// if the underline is nowhere near the clip rectangle. Times 2 and times 3 are both one more multiple
                //// than typically needed.
                //if (ydApproxUnderline - dydOffset * 2 < ydTopClip - 1 || ydApproxUnderline + dydOffset * 3 > ydBottomClip + 1)
                //    continue;
                int[] lefts, rights, tops;
                int   cxd;
                Segment.GetCharPlacement(IchMin, vg, ichMinRun,
                                         ichLimRun, segTrans.SourceRect, segTrans.DestRect, true, 0, out cxd,
                                         null, null, null);
                using (var rgxdLefts = MarshalEx.ArrayToNative <int>(cxd))
                    using (var rgxdRights = MarshalEx.ArrayToNative <int>(cxd))
                        using (var rgydTops = MarshalEx.ArrayToNative <int>(cxd))
                        {
                            Segment.GetCharPlacement(IchMin, vg, ichMinRun,
                                                     ichLimRun, segTrans.SourceRect, segTrans.DestRect, true, cxd, out cxd,
                                                     rgxdLefts, rgxdRights, rgydTops);
                            lefts  = MarshalEx.NativeToArray <int>(rgxdLefts, cxd);
                            rights = MarshalEx.NativeToArray <int>(rgxdRights, cxd);
                            tops   = MarshalEx.NativeToArray <int>(rgydTops, cxd);
                        }
                for (int ixd = 0; ixd < cxd; ixd++)
                {
                    // top of underline 1 pixel below baseline
                    int ydDrawAt = tops[ixd];
                    // underline is drawn at most one offset above ydDrawAt and at most 2 offsets below.
                    // Skip the work if it is clipped.
                    //if (ydDrawAt - dydOffset < ydBottomClip + 1 && ydDrawAt + dydOffset * 2 > ydTopClip - 1)
                    //{
                    //int xLeft = max(rgxdLefts[ixd], xdLeftClip - 1);
                    //int xRight = min(rgxdRights[ixd], xdRightClip + 1);
                    int xLeft  = lefts[ixd];
                    int xRight = rights[ixd];
                    DrawUnderline(vg, xLeft, xRight, ydDrawAt,
                                  segTrans.DpiX / 96, dydOffset,
                                  clrUnder, unt, segTrans.XOffsetScroll);
                    //}
                }
            }
        }
Ejemplo n.º 15
0
		public override void PaintBackground(IVwGraphics vg, PaintTransform ptrans)
		{
			// Review JohnT: do we want to allow individual strings to paint borders etc? Should we call base?
			// base.PaintBackground(vg, ptrans);
			if (Segment == null)
				return;

			int dxdWidth;
			PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			// Ideally, we'd just draw the background, but we don't have that capability currently.
			// The current implementation of DrawTextNoBackground does a good job of redrawing
			// the foreground text, even if it's already been painted.
			if (AnyColoredBackground)
				Segment.DrawText(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, out dxdWidth);
			int dichLim = Segment.get_Lim(IchMin);
			int ichLim = IchMin + dichLim;
			int ichMinRun = IchMin;
			int ichLimRun;
			int dydOffset = Math.Max(1, segTrans.DpiY/96); // distance between double underline, also up and down for squiggle.
			for (; ichMinRun < ichLim; ichMinRun = ichLimRun)
			{
				int clrUnder;
				var unt = Paragraph.Source.GetUnderlineInfo(ichMinRun, out clrUnder, out ichLimRun);
				ichLimRun = Math.Min(ichLimRun, ichLim);
				Debug.Assert(ichLimRun > ichMinRun);
				if (unt == FwUnderlineType.kuntNone)
					continue;
				// Get info about where to draw underlines for this run
				//int ydApproxUnderline = rcSrcChild.MapYTo(psbox->Ascent(), rcDst);
				//// GetCharPlacement seems to be the really expensive part of underlining; don't do it
				//// if the underline is nowhere near the clip rectangle. Times 2 and times 3 are both one more multiple
				//// than typically needed.
				//if (ydApproxUnderline - dydOffset * 2 < ydTopClip - 1 || ydApproxUnderline + dydOffset * 3 > ydBottomClip + 1)
				//    continue;
				int[] lefts, rights, tops;
				int cxd;
				Segment.GetCharPlacement(IchMin, vg, ichMinRun,
					ichLimRun, segTrans.SourceRect, segTrans.DestRect, true, 0, out cxd,
					null, null, null);
				using (var rgxdLefts = MarshalEx.ArrayToNative<int>(cxd))
				using (var rgxdRights = MarshalEx.ArrayToNative<int>(cxd))
				using (var rgydTops = MarshalEx.ArrayToNative<int>(cxd))
				{
					Segment.GetCharPlacement(IchMin, vg, ichMinRun,
						ichLimRun, segTrans.SourceRect, segTrans.DestRect, true, cxd, out cxd,
						rgxdLefts, rgxdRights, rgydTops);
					lefts = MarshalEx.NativeToArray<int>(rgxdLefts, cxd);
					rights = MarshalEx.NativeToArray<int>(rgxdRights, cxd);
					tops = MarshalEx.NativeToArray<int>(rgydTops, cxd);
				}
				for (int ixd = 0; ixd < cxd; ixd++)
				{
					// top of underline 1 pixel below baseline
					int ydDrawAt = tops[ixd];
					// underline is drawn at most one offset above ydDrawAt and at most 2 offsets below.
					// Skip the work if it is clipped.
					//if (ydDrawAt - dydOffset < ydBottomClip + 1 && ydDrawAt + dydOffset * 2 > ydTopClip - 1)
					//{
					//int xLeft = max(rgxdLefts[ixd], xdLeftClip - 1);
					//int xRight = min(rgxdRights[ixd], xdRightClip + 1);
					int xLeft = lefts[ixd];
					int xRight = rights[ixd];
					DrawUnderline(vg, xLeft, xRight, ydDrawAt,
						segTrans.DpiX/96, dydOffset,
						clrUnder, unt, segTrans.XOffsetScroll);
					//}
				}
			}
		}
Ejemplo n.º 16
0
		public override void PaintForeground(IVwGraphics vg, PaintTransform ptrans)
		{
			if (Segment == null)
				return;
			int dxdWidth;
			PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);

			if (AnyColoredBackground)
				Segment.DrawTextNoBackground(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, out dxdWidth);
			else
				Segment.DrawText(IchMin, vg, segTrans.SourceRect, segTrans.DestRect, out dxdWidth); // more efficient.
		}
Ejemplo n.º 17
0
		internal void DrawRange(int ichMin, int ichLim, IVwGraphics vg, PaintTransform ptrans, int topOfLine, int bottomOfLine)
		{
			PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			// Todo JohnT: here or in client we need to handle ranges that don't start and end in this paragraph.
			// Todo JohnT: the last true appears to be what the old Views code normally passes, but there may be some case where
			// we should pass false.
			// Todo JohnT: passing the top and bottom of the string box as ydTop and ydBottom will not work when we have specified line spacing.
			Segment.DrawRange(IchMin, vg, segTrans.SourceRect, segTrans.DestRect,
				ichMin, ichLim, topOfLine, bottomOfLine, true, true);
		}
Ejemplo n.º 18
0
		/// <summary>
		///  Get the IP location, if in this segment; if not return a dummy rectangle and 'here' will be false.
		/// </summary>
		public Rectangle GetIpLocation(InsertionPoint ip, IVwGraphics vg, PaintTransform ptrans, out bool here)
		{
			PaintTransform segTrans = ptrans.PaintTransformOffsetBy(Left, Top);
			Rect rectPrimary, rectSec;
			bool fPrimaryHere, fSecHere;
			Segment.PositionsOfIP(IchMin, vg, segTrans.SourceRect, segTrans.DestRect,
								  ip.RenderParaPosition, ip.AssociatePrevious, LgIPDrawMode.kdmNormal, out rectPrimary,
								  out rectSec,
								  out fPrimaryHere, out fSecHere);
			if (fPrimaryHere)
			{
				here = true;
				return new Rectangle(rectPrimary.left, rectPrimary.top, rectPrimary.right - rectPrimary.left,
									 rectPrimary.bottom - rectPrimary.top);
			}
			here = false;
			return new Rectangle();
		}