Exemple #1
0
        //------------------------------------------------------------------- 
        //
        // Connstructors
        //
        //---------------------------------------------------------------------- 

        #region Constructors 
        internal FlowPosition(FixedTextContainer container, FlowNode node, int offset) 
        {
            Debug.Assert(!FlowNode.IsNull(node)); 
            _container  = container;
            _flowNode   = node;
            _offset     = offset;
        } 
        //-------------------------------------------------------------------
        // 
        // Constructors
        //
        //----------------------------------------------------------------------
 
        #region Constructors
        internal FixedPageStructure(int pageIndex) 
        { 
            Debug.Assert(pageIndex >= 0);
            _pageIndex = pageIndex; 

            // Initialize to virtual
            _flowStart = new FlowNode(FixedFlowMap.FlowOrderVirtualScopeId, FlowNodeType.Virtual, pageIndex);
            _flowEnd   = _flowStart; 

            // 
            _fixedStart = FixedNode.Create(pageIndex, 1, FixedFlowMap.FixedOrderStartVisual, -1, null); 
            _fixedEnd   = FixedNode.Create(pageIndex, 1, FixedFlowMap.FixedOrderEndVisual, -1, null);
        } 
         //-------------------------------------------------------
        // Flow Order Helper Functions
        //-------------------------------------------------------

        // Insert a flow position before a given flow position
        // NOTE: flow fp will be modified
        internal void _FlowOrderInsertBefore(FlowNode nextFlow, FlowNode newFlow)
        {
            newFlow.SetFp(nextFlow.Fp);
            _flowOrder.Insert(newFlow.Fp, newFlow);

            // update all subsequent fps
            for (int i = newFlow.Fp + 1, n = _flowOrder.Count; i < n; i++)
            {
                _flowOrder[i].IncreaseFp();
            }
        }
        //--------------------------------------------------------------------
        //
        // Private Methods
        //
        //---------------------------------------------------------------------

        #region Private Methods

        // initialize the maps and edge nodes
        private void _Init()
        {
            // mutable boundary flow nodes
            _flowStart  = new FlowNode(FlowOrderBoundaryScopeId, FlowNodeType.Boundary, null);
            _flowEnd    = new FlowNode(FlowOrderBoundaryScopeId, FlowNodeType.Boundary, null);

            //_fixedOrder   = new List<FixedOrderEntry>();
            _flowOrder    = new List<FlowNode>();

            _flowOrder.Add(_flowStart);
            _flowStart.SetFp(0);
            _flowOrder.Add(_flowEnd);
            _flowEnd.SetFp(1);

            _mapping = new Hashtable();
        }
        //-------------------------------------------------------
        // Flow Order
        //-------------------------------------------------------

        // Insert a FlowNode before a given FlowNode
        // NOTE: FlowNode's Fp will be modified
        internal FlowNode FlowOrderInsertBefore(FlowNode nextFlow, FlowNode newFlow)
        {
            _FlowOrderInsertBefore(nextFlow, newFlow);
            return newFlow;
        }
        //--------------------------------------------------------------------
        //
        // Public Properties
        //
        //---------------------------------------------------------------------

        //--------------------------------------------------------------------
        //
        // Public Events
        //
        //---------------------------------------------------------------------

        //--------------------------------------------------------------------
        //
        // Internal Methods
        //
        //---------------------------------------------------------------------

        #region Internal Methods

        //-------------------------------------------------------
        // Mapping
        //-------------------------------------------------------
        
        // Replace an existing FlowNode with a new set of FlowNode
        // Each has a mapped FixedNode set. 
        internal void MappingReplace(FlowNode flowOld, List<FlowNode> flowNew)
        {
            Debug.Assert(flowOld.Type == FlowNodeType.Virtual || flowNew != null);

            // Insert a new entry into Flow Order for each new FlowNode
            int index = flowOld.Fp;
            _flowOrder.RemoveAt(index);
            _flowOrder.InsertRange(index, flowNew);
            for (int i = index; i < _flowOrder.Count; i++)
            {
                _flowOrder[i].SetFp(i);
            }
        }
Exemple #7
0
 internal bool IsVirtual(FlowNode flowNode) 
 {
     return (flowNode.Type == FlowNodeType.Virtual); 
 }
Exemple #8
0
        // return FlowNode within this range 
        internal void GetFlowNodes(FlowPosition pEnd, out FlowNode[] flowNodes, out int offsetStart, out int offsetEnd)
        {
            Debug.Assert(this._OverlapAwareCompare(pEnd) < 0);
            flowNodes = null; 
            offsetStart = 0;
            offsetEnd = 0; 
 
            FlowPosition flowScan = GetClingPosition(LogicalDirection.Forward);
            offsetStart = flowScan._offset; 

            ArrayList ar = new ArrayList();
            int distance = GetDistance(pEnd);
            // keep moving until we hit distance 
            while (distance > 0)
            { 
                int scan = flowScan._vScan(LogicalDirection.Forward, distance); 

                distance -= scan; 
                if (flowScan.IsRun || flowScan.IsObject)
                {
                    ar.Add(flowScan._flowNode);
                    offsetEnd = flowScan._offset; 
                }
            } 
            flowNodes = (FlowNode [])ar.ToArray(typeof(FlowNode)); 
        }
Exemple #9
0
        internal void GetFlowNode(LogicalDirection direction, out FlowNode flowNode, out int offsetStart)
        {
            FlowPosition fp = GetClingPosition(direction);
 
            offsetStart = fp._offset;
            flowNode = fp._flowNode; 
        } 
        //--------------------------------------------------------------------
        //
        // Public Methods
        //
        //---------------------------------------------------------------------
          
        #region Public Methods

        // force object comparision
        public static bool IsNull(FlowNode flow)
        {
            return (object)flow == null;
        }
 //------------------------------------- 
 // Flow Order
 //-------------------------------------
 internal void SetFlowBoundary(FlowNode flowStart, FlowNode flowEnd)
 { 
     Debug.Assert(flowStart != null && flowStart.Type != FlowNodeType.Virtual);
     Debug.Assert(flowEnd   != null && flowEnd.Type != FlowNodeType.Virtual); 
     _flowStart = flowStart; 
     _flowEnd = flowEnd;
 } 
 // Token: 0x06002D2D RID: 11565 RVA: 0x000CC0C0 File Offset: 0x000CA2C0
 internal FlowNode FlowOrderInsertBefore(FlowNode nextFlow, FlowNode newFlow)
 {
     this._FlowOrderInsertBefore(nextFlow, newFlow);
     return(newFlow);
 }
Exemple #13
0
        //--------------------------------------------------------------------
        //
        // Public Methods
        //
        //---------------------------------------------------------------------

        #region Public Methods

        // force object comparision
        public static bool IsNull(FlowNode flow)
        {
            return((object)flow == null);
        }
Exemple #14
0
        //--------------------------------------------------------------------
        //
        // Private Methods
        //
        //---------------------------------------------------------------------

        #region Private Methods
        //--------------------------------------------------------------------
        //  Helper functions that could result in de-virtualization
        //---------------------------------------------------------------------

        // scan one node forward, return characters/symbols passed
        // limit < 0 means scan entire node.
        private int _vScan(LogicalDirection dir, int limit)
        {
            if (limit == 0)
            {
                return(0);
            }

            FlowNode flowNode = _flowNode;
            int      scanned  = 0;

            if (dir == LogicalDirection.Forward)
            {
                if (_offset == _NodeLength || flowNode.Type == FlowNodeType.Boundary)
                {
                    // This position is at right side of a FlowNode
                    flowNode = _xGetNextFlowNode();
                    if (FlowNode.IsNull(flowNode))
                    {
                        return(scanned);
                    }
                    _flowNode = flowNode;
                    scanned   = _NodeLength;
                }
                else
                {
                    scanned = _NodeLength - _offset;
                }

                _offset = _NodeLength;
                if (limit > 0 && scanned > limit)
                {
                    int back = scanned - limit;
                    scanned  = limit;
                    _offset -= back;
                }
            }
            else
            {
                Debug.Assert(dir == LogicalDirection.Backward);
                if (_offset == 0 || flowNode.Type == FlowNodeType.Boundary)
                {
                    // This position is at left side of a FlowNode
                    // look for previous run
                    flowNode = _xGetPreviousFlowNode();
                    if (FlowNode.IsNull(flowNode))
                    {
                        return(scanned);
                    }

                    _flowNode = flowNode;
                    scanned   = _NodeLength;
                }
                else
                {
                    scanned = _offset;
                }

                _offset = 0;
                if (limit > 0 && scanned > limit)
                {
                    int back = scanned - limit;
                    scanned  = limit;
                    _offset += back;
                }
            }
            return(scanned);
        }
Exemple #15
0
 internal bool IsVirtual(FlowNode flowNode)
 {
     return(flowNode.Type == FlowNodeType.Virtual);
 }
Exemple #16
0
        internal void RenderFlowNode(DrawingContext dc)
        {
            FormattedText ft;
            FixedNode     fixedNode;

            FixedSOMElement[] somElements;
            String            ouptputString;
            FixedElement      fixedElement;
            Random            random = new Random();

            CultureInfo EnglishCulture = System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS;

            FixedPage fp = _fixedTextBuilder.FixedTextContainer.FixedDocument.GetFixedPage(PageIndex);
            //
            //Iterate through flow node to draw Transparent Rect and draw its index
            //
            Point    prevTextPoint = new Point(0, 0);
            DpiScale dpi           = fp.GetDpi();

            for (int i = FlowStart.Fp; i <= FlowEnd.Fp; i++)
            {
                FlowNode fn = _fixedTextBuilder.FixedFlowMap[i];
                switch (fn.Type)
                {
                case FlowNodeType.Boundary:
                case FlowNodeType.Virtual:
                    // this two cases won't happen.
                    Debug.Assert(false);
                    break;

                case FlowNodeType.Start:
                case FlowNodeType.End:
                {
                    fixedElement = fn.Cookie as FixedElement;
                    String typeString = fixedElement.Type.ToString();
                    int    indexofDot = typeString.LastIndexOf('.');
                    ouptputString = String.Format("{0}-{1}",
                                                  fn.ToString(),
                                                  typeString.Substring(indexofDot + 1));

                    ft = new FormattedText(ouptputString,
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkGreen,
                                           dpi.PixelsPerDip);
                    // Ideally, for FlowNodeType.Start, this should find next FlowNode with physical location,
                    // and draw it around the physical location.
                    prevTextPoint = CreateFromLastTextPoint(prevTextPoint);

                    dc.DrawText(ft, prevTextPoint);
                    break;
                }

                case FlowNodeType.Noop:
                    ft = new FormattedText(fn.ToString(),
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkGreen,
                                           dpi.PixelsPerDip);
                    prevTextPoint = CreateFromLastTextPoint(prevTextPoint);
                    dc.DrawText(ft, prevTextPoint);
                    break;

                case FlowNodeType.Run:
                    //
                    // Paint the region. The rect is the union of child glyphs.
                    //

                    Glyphs glyphs;
                    Rect   flowRunBox = Rect.Empty;
                    Rect   glyphBox;
                    somElements = _fixedTextBuilder.FixedFlowMap.FlowNodes[fn.Fp].FixedSOMElements;

                    foreach (FixedSOMElement currentSomeElement in somElements)
                    {
                        FixedNode currentFixedNode = currentSomeElement.FixedNode;
                        int       startIndex       = currentSomeElement.StartIndex;
                        int       endIndex         = currentSomeElement.EndIndex;

                        // same as (_IsBoundaryFixedNode(currentFixedNode))
                        if (currentFixedNode.Page == FixedFlowMap.FixedOrderStartPage ||
                            currentFixedNode.Page == FixedFlowMap.FixedOrderEndPage ||
                            currentFixedNode[1] == FixedFlowMap.FixedOrderStartVisual ||
                            currentFixedNode[1] == FixedFlowMap.FixedOrderEndVisual)
                        {
                            continue;
                        }

                        glyphs = fp.GetGlyphsElement(currentFixedNode);
                        Debug.Assert(glyphs != null);

                        glyphBox = FixedTextView._GetGlyphRunDesignRect(glyphs, startIndex, endIndex);
                        if (!glyphBox.IsEmpty)
                        {
                            GeneralTransform g = glyphs.TransformToAncestor(fp);

                            glyphBox = g.TransformBounds(glyphBox);
                        }

                        flowRunBox.Union(glyphBox);
                    }

                    if (flowRunBox.IsEmpty)
                    {
                        Debug.Assert(false);
                    }
                    prevTextPoint.X = flowRunBox.Right;
                    prevTextPoint.Y = flowRunBox.Bottom - random.Next(15);

                    // Draw something the upper left corner of region.
                    ft = new FormattedText(fn.ToString() + "-" + Convert.ToString((int)(fn.Cookie)) +
                                           "-" + Convert.ToString(somElements.Length),
                                           EnglishCulture,
                                           FlowDirection.LeftToRight,
                                           new Typeface("Courier New"),
                                           8,
                                           Brushes.DarkBlue,
                                           dpi.PixelsPerDip);
                    dc.DrawText(ft, prevTextPoint);

                    Pen pen = new Pen(Brushes.Blue, 2);
                    flowRunBox.Inflate(random.Next(3), random.Next(3));
                    DrawRectOutline(dc, pen, flowRunBox);
                    break;

                case FlowNodeType.Object:
                    //
                    // Find the mapping fixed node
                    //
                    somElements = _fixedTextBuilder.FixedFlowMap.FlowNodes[fn.Fp].FixedSOMElements;

                    foreach (FixedSOMElement currentSomeElement in somElements)
                    {
                        fixedNode = currentSomeElement.FixedNode;

                        DependencyObject dependencyObject = fp.GetElement(fixedNode);

                        Image image = dependencyObject as Image;
                        Path  path  = dependencyObject as Path;

                        if (image != null || path != null)
                        {
                            Rect imageRect, boundingRect = Rect.Empty;
                            //
                            // Get Image bounding box.
                            //
                            GeneralTransform transform = ((Visual)dependencyObject).TransformToAncestor(fp);
                            // You can't use GetContentBounds inside OnRender
                            if (image != null)
                            {
                                boundingRect = new Rect(0, 0, image.Width, image.Height);
                            }
                            else
                            {
                                boundingRect = path.Data.Bounds;
                            }

                            if (!boundingRect.IsEmpty)
                            {
                                imageRect = transform.TransformBounds(boundingRect);

                                // Image might overlap, inflate the box.
                                imageRect.Inflate(3, 3);
                                dc.DrawRectangle(Brushes.CadetBlue, null, imageRect);

                                prevTextPoint.X = imageRect.Right;
                                prevTextPoint.Y = imageRect.Top;
                            }
                        }
                        else
                        {
                            //
                            // If the object is the Image type(that is not likey).
                            // Use the last Point to infer a comment area!
                            //
                            Debug.Assert(false);
                        }

                        fixedElement = fn.Cookie as FixedElement;
                        ft           = new FormattedText(fn.ToString(),
                                                         EnglishCulture,
                                                         FlowDirection.LeftToRight,
                                                         new Typeface("Courier New"),
                                                         8,
                                                         Brushes.DarkGreen,
                                                         dpi.PixelsPerDip);
                        dc.DrawText(ft, prevTextPoint);
                    }

                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
            }
        }