Esempio n. 1
0
        /// <summary>
        /// Client to acquire a state at the point where line is broken by line breaking process;
        /// can be null when the line ends by the ending of the paragraph. Client may pass this
        /// value back to TextFormatter as an input argument to TextFormatter.FormatLine when
        /// formatting the next line within the same paragraph.
        /// </summary>
        /// <remarks>
        /// TextLineBreak is a finalizable object which may contain a reference to an unmanaged
        /// structure called break record. Break record can be acquired thru ploline. This method
        /// acquire break record only when the passing ploline object is not NULL.
        ///
        /// Not all situations requires break record. Single-line formatting without complex text
        /// object does not need it, but optimal break session does. For performance reason, we
        /// should not produce break record unnecessarily because it makes TextLineBreak become
        /// finalizable, which therefore unnecessarily put additional pressure to GC since each
        /// finalizable object wakes finalizer thread and requires double GC collections.
        /// </remarks>
        internal TextLineBreak GetTextLineBreak(IntPtr ploline)
        {
            IntPtr pbreakrec = IntPtr.Zero;

            if (ploline != IntPtr.Zero)
            {
                LsErr lserr = UnsafeNativeMethods.LoAcquireBreakRecord(ploline, out pbreakrec);

                if (lserr != LsErr.None)
                {
                    TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.AcquireBreakRecordFailure, lserr), lserr);
                }
            }

            if (_lastRun != null &&
                _lastRun.TextModifierScope != null &&
                !(_lastRun.TextRun is TextEndOfParagraph))
            {
                return(new TextLineBreak(
                           _lastRun.TextModifierScope,
                           new SecurityCriticalDataForSet <IntPtr>(pbreakrec)
                           ));
            }
            return((pbreakrec != IntPtr.Zero) ? new TextLineBreak(null, new SecurityCriticalDataForSet <IntPtr>(pbreakrec)) : null);
        }
        static internal void ThrowExceptionFromLsError(string message, LsErr lserr)
        {
            if (lserr == LsErr.OutOfMemory)
            {
                throw new OutOfMemoryException(message);
            }

            throw new Exception(message);
        }
Esempio n. 3
0
        private bool _penalizedAsJustified;                                     // flag indicating whether the paragraph should be penalized as fully-justified one


        /// <summary>
        /// Construct a paragraph cache to be used during optimal paragraph formatting
        /// </summary>
        internal TextParagraphCache(
            FormatSettings settings,
            int firstCharIndex,
            int paragraphWidth
            )
        {
            Invariant.Assert(settings != null);

            // create full text
            _finiteFormatWidth = settings.GetFiniteFormatWidth(paragraphWidth);
            _fullText          = FullTextState.Create(settings, firstCharIndex, _finiteFormatWidth);

            // acquiring LS context
            TextFormatterContext context = settings.Formatter.AcquireContext(_fullText, IntPtr.Zero);

            _fullText.SetTabs(context);

            IntPtr ploparabreakValue = IntPtr.Zero;

            LsErr lserr = context.CreateParaBreakingSession(
                firstCharIndex,
                _finiteFormatWidth,
                // breakrec is not needed before the first cp of para cache
                // since we handle Bidi break ourselves.
                IntPtr.Zero,
                ref ploparabreakValue,
                ref _penalizedAsJustified
                );

            // get the exception in context before it is released
            Exception callbackException = context.CallbackException;

            // release the context
            context.Release();

            if (lserr != LsErr.None)
            {
                GC.SuppressFinalize(this);
                if (callbackException != null)
                {
                    // rethrow exception thrown in callbacks
                    throw new InvalidOperationException(SR.Get(SRID.CreateParaBreakingSessionFailure, lserr), callbackException);
                }
                else
                {
                    // throw with LS error codes
                    TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.CreateParaBreakingSessionFailure, lserr), lserr);
                }
            }

            _ploparabreak.Value = ploparabreakValue;

            // keep context alive till here
            GC.KeepAlive(context);
        }
Esempio n. 4
0
        internal TextPenaltyModule(SecurityCriticalDataForSet <IntPtr> ploc)
        {
            IntPtr ploPenaltyModule;
            LsErr  lserr = UnsafeNativeMethods.LoAcquirePenaltyModule(ploc.Value, out ploPenaltyModule);

            if (lserr != LsErr.None)
            {
                TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.AcquirePenaltyModuleFailure, lserr), lserr);
            }

            _ploPenaltyModule.Value = ploPenaltyModule;
        }
        internal void SetBreaking(BreakStrategies breaking)
        {
            if (_state == State.Uninitialized || breaking != _breaking)
            {
                Invariant.Assert(_ploc.Value != System.IntPtr.Zero);
                LsErr lserr = UnsafeNativeMethods.LoSetBreaking(_ploc.Value, (int)breaking);

                if (lserr != LsErr.None)
                {
                    ThrowExceptionFromLsError(SR.Get(SRID.SetBreakingFailure, lserr), lserr);
                }

                _breaking = breaking;
            }
            _state = State.Initialized;
        }
Esempio n. 6
0
        internal override SecurityCriticalDataForSet <IntPtr> GetTextPenaltyResource()
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(SR.Get(SRID.TextBreakpointHasBeenDisposed));
            }

            LsErr lserr = UnsafeNativeMethods.LoRelievePenaltyResource(_ploline.Value);

            if (lserr != LsErr.None)
            {
                TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.RelievePenaltyResourceFailure, lserr), lserr);
            }

            return(_penaltyResource);
        }
Esempio n. 7
0
        public TextLineBreak Clone()
        {
            IntPtr pbreakrec = IntPtr.Zero;

            if (_breakRecord.Value != IntPtr.Zero)
            {
                LsErr lserr = UnsafeNativeMethods.LoCloneBreakRecord(_breakRecord.Value, out pbreakrec);

                if (lserr != LsErr.None)
                {
                    TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.CloneBreakRecordFailure, lserr), lserr);
                }
            }

            return(new TextLineBreak(_currentScope, new SecurityCriticalDataForSet <IntPtr>(pbreakrec)));
        }
Esempio n. 8
0
        internal IntPtr DangerousGetHandle()
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(SR.Get(SRID.TextPenaltyModuleHasBeenDisposed));
            }

            IntPtr penaltyModuleInternalHandle;
            LsErr  lserr = UnsafeNativeMethods.LoGetPenaltyModuleInternalHandle(_ploPenaltyModule.Value, out penaltyModuleInternalHandle);

            if (lserr != LsErr.None)
            {
                TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.GetPenaltyModuleHandleFailure, lserr), lserr);
            }

            GC.KeepAlive(this);
            return(penaltyModuleInternalHandle);
        }
        internal unsafe void SetTabs(
            int incrementalTab,
            LsTbd *tabStops,
            int tabStopCount
            )
        {
            Invariant.Assert(_ploc.Value != System.IntPtr.Zero);
            LsErr lserr = UnsafeNativeMethods.LoSetTabs(
                _ploc.Value,
                incrementalTab,
                tabStopCount,
                tabStops
                );

            if (lserr != LsErr.None)
            {
                ThrowExceptionFromLsError(SR.Get(SRID.SetTabsFailure, lserr), lserr);
            }
        }
        internal void SetDoc(
            bool isDisplay,
            bool isReferencePresentationEqual,
            ref LsDevRes deviceInfo
            )
        {
            Invariant.Assert(_ploc.Value != System.IntPtr.Zero);
            LsErr lserr = UnsafeNativeMethods.LoSetDoc(
                _ploc.Value,
                isDisplay ? 1 : 0,
                isReferencePresentationEqual ? 1 : 0,
                ref deviceInfo
                );

            if (lserr != LsErr.None)
            {
                ThrowExceptionFromLsError(SR.Get(SRID.SetDocFailure, lserr), lserr);
            }
        }
        private void Init()
        {
            if (_ploc.Value == System.IntPtr.Zero)
            {
                // Initializing context
                LsErr lserr = LsErr.None;

                LsContextInfo  contextInfo = new LsContextInfo();
                LscbkRedefined lscbkRedef  = new LscbkRedefined();

                _callbacks = new LineServicesCallbacks();
                _callbacks.PopulateContextInfo(ref contextInfo, ref lscbkRedef);


                contextInfo.version = 4;                // we should set this right, they might check it in the future
                contextInfo.pols    = IntPtr.Zero;      // This will be filled in the un-managed code
                contextInfo.cEstimatedCharsPerLine = TextStore.TypicalCharactersPerLine;
                contextInfo.fDontReleaseRuns       = 1; // dont waste time

                // There are 3 justification priorities right now with one considered good
                // and the other two provided for emergency expansion.
                // Future development to enable international justification will likely change this.
                // e.g. Kashida justification would require more than one good priorities.
                contextInfo.cJustPriorityLim = 3;

                // Fill up text configuration
                contextInfo.wchNull     = '\u0000';
                contextInfo.wchUndef    = '\u0001';
                contextInfo.wchTab      = '\u0009';
                contextInfo.wchPosTab   = contextInfo.wchUndef;
                contextInfo.wchEndPara1 = TextStore.CharParaSeparator;              // Unicode para separator
                contextInfo.wchEndPara2 = contextInfo.wchUndef;
                contextInfo.wchSpace    = '\u0020';

                contextInfo.wchHyphen             = MS.Internal.Text.TextInterface.TextAnalyzer.CharHyphen;   //'\x002d';
                contextInfo.wchNonReqHyphen       = '\u00AD';
                contextInfo.wchNonBreakHyphen     = '\u2011';
                contextInfo.wchEnDash             = '\u2013';
                contextInfo.wchEmDash             = '\u2014';
                contextInfo.wchEnSpace            = '\u2002';
                contextInfo.wchEmSpace            = '\u2003';
                contextInfo.wchNarrowSpace        = '\u2009';
                contextInfo.wchJoiner             = '\u200D';
                contextInfo.wchNonJoiner          = '\u200C';
                contextInfo.wchVisiNull           = '\u2050';
                contextInfo.wchVisiAltEndPara     = '\u2051';
                contextInfo.wchVisiEndLineInPara  = '\u2052';
                contextInfo.wchVisiEndPara        = '\u2053';
                contextInfo.wchVisiSpace          = '\u2054';
                contextInfo.wchVisiNonBreakSpace  = '\u2055';
                contextInfo.wchVisiNonBreakHyphen = '\u2056';
                contextInfo.wchVisiNonReqHyphen   = '\u2057';
                contextInfo.wchVisiTab            = '\u2058';
                contextInfo.wchVisiPosTab         = contextInfo.wchUndef;
                contextInfo.wchVisiEmSpace        = '\u2059';
                contextInfo.wchVisiEnSpace        = '\u205A';
                contextInfo.wchVisiNarrowSpace    = '\u205B';
                contextInfo.wchVisiOptBreak       = '\u205C';
                contextInfo.wchVisiNoBreak        = '\u205D';
                contextInfo.wchVisiFESpace        = '\u205E';
                contextInfo.wchFESpace            = '\u3000';
                contextInfo.wchEscAnmRun          = TextStore.CharParaSeparator;
                contextInfo.wchAltEndPara         = contextInfo.wchUndef;
                contextInfo.wchEndLineInPara      = TextStore.CharLineSeparator;
                contextInfo.wchSectionBreak       = contextInfo.wchUndef;
                contextInfo.wchNonBreakSpace      = '\u00A0';
                contextInfo.wchNoBreak            = contextInfo.wchUndef;
                contextInfo.wchColumnBreak        = contextInfo.wchUndef;
                contextInfo.wchPageBreak          = contextInfo.wchUndef;
                contextInfo.wchOptBreak           = contextInfo.wchUndef;
                contextInfo.wchToReplace          = contextInfo.wchUndef;
                contextInfo.wchReplace            = contextInfo.wchUndef;

                IntPtr ploc           = IntPtr.Zero;
                IntPtr ppenaltyModule = IntPtr.Zero;

                lserr = UnsafeNativeMethods.LoCreateContext(
                    ref contextInfo,
                    ref lscbkRedef,
                    out ploc
                    );

                if (lserr != LsErr.None)
                {
                    ThrowExceptionFromLsError(SR.Get(SRID.CreateContextFailure, lserr), lserr);
                }

                _ploc.Value = ploc;
                GC.KeepAlive(contextInfo);

                //  There is a trick here to pass in this resolution as in twips
                //  (1/1440 an inch).
                //
                //  LSCreateLine assumes the max width passed in is in twips so to
                //  allow its client to express their width in page unit. However
                //  it asks client to set up the real device resolution here so
                //  that it can internally translate the "twips" width into client
                //  actual device unit.
                //
                //  We are not device dependent anyway, so instead of following the
                //  rule which will cause us to validate the context every time. We
                //  choose to cheat LS to think that our unit is twips.
                //
                LsDevRes devRes;
                devRes.dxpInch = devRes.dxrInch = TwipsPerInch;
                devRes.dypInch = devRes.dyrInch = TwipsPerInch;

                SetDoc(
                    true,           // Yes, we will be displaying
                    true,           // Yes, reference and presentation are the same device
                    ref devRes      // Device resolutions
                    );

                SetBreaking(BreakStrategies.BreakCJK);
            }
        }
Esempio n. 12
0
        static internal void ThrowExceptionFromLsError(string message, LsErr lserr)
        { 
            if (lserr == LsErr.OutOfMemory)
                throw new OutOfMemoryException (message);

            throw new Exception(message); 
        }
Esempio n. 13
0
        internal static IList <TextBreakpoint> CreateMultiple(
            TextParagraphCache paragraphCache,
            int firstCharIndex,
            int maxLineWidth,
            TextLineBreak previousLineBreak,
            IntPtr penaltyRestriction,
            out int bestFitIndex
            )
        {
            Invariant.Assert(paragraphCache != null);

            // grab full text state from paragraph cache
            FullTextState fullText = paragraphCache.FullText;

            Invariant.Assert(fullText != null);

            FormatSettings settings = fullText.TextStore.Settings;

            Invariant.Assert(settings != null);

            // update formatting parameters at line start
            settings.UpdateSettingsForCurrentLine(
                maxLineWidth,
                previousLineBreak,
                (firstCharIndex == fullText.TextStore.CpFirst)
                );

            Invariant.Assert(settings.Formatter != null);

            // acquiring LS context
            TextFormatterContext context = settings.Formatter.AcquireContext(fullText, IntPtr.Zero);

            IntPtr previousBreakRecord = IntPtr.Zero;

            if (settings.PreviousLineBreak != null)
            {
                previousBreakRecord = settings.PreviousLineBreak.BreakRecord.Value;
            }

            // need not consider marker as tab since marker does not affect line metrics and it wasnt drawn.
            fullText.SetTabs(context);

            LsBreaks lsbreaks = new LsBreaks();

            LsErr lserr = context.CreateBreaks(
                fullText.GetBreakpointInternalCp(firstCharIndex),
                previousBreakRecord,
                paragraphCache.Ploparabreak.Value,  // para breaking session
                penaltyRestriction,
                ref lsbreaks,
                out bestFitIndex
                );

            // get the exception in context before it is released
            Exception callbackException = context.CallbackException;

            // release the context
            context.Release();

            if (lserr != LsErr.None)
            {
                if (callbackException != null)
                {
                    // rethrow exception thrown in callbacks
                    throw callbackException;
                }
                else
                {
                    // throw with LS error codes
                    TextFormatterContext.ThrowExceptionFromLsError(SR.Get(SRID.CreateBreaksFailure, lserr), lserr);
                }
            }

            // keep context alive at least till here
            GC.KeepAlive(context);

            TextBreakpoint[] breakpoints = new TextBreakpoint[lsbreaks.cBreaks];

            for (int i = 0; i < lsbreaks.cBreaks; i++)
            {
                breakpoints[i] = new FullTextBreakpoint(
                    fullText,
                    firstCharIndex,
                    maxLineWidth,
                    ref lsbreaks,
                    i   // the current break
                    );
            }

            return(breakpoints);
        }