File: src\Framework\MS\Internal\Text\LineMetrics.cs
Project: wpf\PresentationFramework.csproj (PresentationFramework)
//---------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
// 
// File: LineMetrics.cs
//
// Description: Cached metrics of a text line. 
//
// History:  
//  04/25/2003 : Microsoft - moving from Avalon branch.
//
//---------------------------------------------------------------------------
 
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.TextFormatting;
namespace MS.Internal.Text
{
    // ----------------------------------------------------------------------
    // Storage for metrics of a formatted line.
    // ----------------------------------------------------------------------
    internal struct LineMetrics
    {
        // ------------------------------------------------------------------
        // Constructor.
        //
        //      wrappingWidth - wrapping width for the line
        //      length - number or characters in the line
        //      width - width of the line 
        //      height - height of the line 
        //      baseline - baseline of the line 
        //      hasInlineObjects - has inline objects? 
        // ------------------------------------------------------------------
        internal LineMetrics(
#if DEBUG
                    double wrappingWidth, 
#endif
                    int length, 
                    double width, 
                    double height, 
                    double baseline, 
                    bool hasInlineObjects, 
                    TextLineBreak textLineBreak)
        {
#if DEBUG
            _wrappingWidth = wrappingWidth;
#endif
            _start = 0;
            _width  = width;
            _height = height;
            _baseline = baseline;
            _textLineBreak = textLineBreak;
 
            _packedData = ((uint) length & LengthMask) | (hasInlineObjects ? HasInlineObjectsMask : 0);
        }
 
        internal LineMetrics(LineMetrics source, double start, double width)
        {
#if DEBUG
            _wrappingWidth = source.WrappingWidth;
#endif
            _start = start;
            _width = width;
            
            _height = source.Height;
            _baseline = source.Baseline;
            _textLineBreak = source.TextLineBreak;
 
            _packedData = source._packedData | HasBeenUpdatedMask;
        }
        
        /// <summary>
        /// Disposes linebreak object
        /// </summary>
        internal LineMetrics Dispose(bool returnUpdatedMetrics)
        {
            if(_textLineBreak != null)
            {
                _textLineBreak.Dispose();
                if (returnUpdatedMetrics)
                {
                    return new LineMetrics(
#if DEBUG
                        _wrappingWidth,
#endif
                        Length,
                        _width,
                        _height,
                        _baseline,
                        HasInlineObjects,
                        null);
                }
            }
            return this;
        }
 
 
#if DEBUG
        // ------------------------------------------------------------------
        // Wrapping width for the line.
        // ------------------------------------------------------------------
        internal double WrappingWidth { get { return _wrappingWidth; } }
        private double _wrappingWidth;
#endif
 
        // ------------------------------------------------------------------
        // Number or characters in the line.
        // ------------------------------------------------------------------
        internal int Length { get { return (int) (_packedData & LengthMask); } }
        private uint _packedData;
 
        // ------------------------------------------------------------------
        // Width of the line.
        // ------------------------------------------------------------------
        internal double Width
        {
            get { Debug.Assert((_packedData & HasBeenUpdatedMask) != 0); return _width; }
        }
        private double _width;
 
        // ------------------------------------------------------------------
        // Height of the line.
        // ------------------------------------------------------------------
        internal double Height { get { return _height; } }
        private double _height;
 
        // ------------------------------------------------------------------
        // Start of the line. Distance from paragraph edge to line start.
        // ------------------------------------------------------------------
        internal double Start
        {
            get { Debug.Assert((_packedData & HasBeenUpdatedMask) != 0); return _start; }
        }
        private double _start;
 
        // ------------------------------------------------------------------
        // Baseline offset of the line.
        // ------------------------------------------------------------------
        internal double Baseline { get { return _baseline; } }
        private double _baseline;
 
        // ------------------------------------------------------------------
        // Has inline objects?
        // ------------------------------------------------------------------
        internal bool HasInlineObjects { get { return (_packedData & HasInlineObjectsMask) != 0; } }
 
        // ------------------------------------------------------------------
        // Line break for formatting. (Line Break In)
        // ------------------------------------------------------------------
        internal TextLineBreak TextLineBreak { get { return _textLineBreak; } }
        private TextLineBreak _textLineBreak;
       
        private static readonly uint HasBeenUpdatedMask = 0x40000000;
        private static readonly uint LengthMask = 0x3FFFFFFF;
        private static readonly uint HasInlineObjectsMask = 0x80000000;
    }
}