internal void PopulateContextInfo(ref LsContextInfo contextInfo, ref LscbkRedefined lscbkRedef)
 {
     lscbkRedef.pfnFetchRunRedefined                 = _pfnFetchRunRedefined;
     lscbkRedef.pfnGetGlyphsRedefined                = _pfnGetGlyphsRedefined;
     lscbkRedef.pfnFetchLineProps                    = _pfnFetchLineProps;
     contextInfo.pfnFetchLineProps                   = _pfnFetchLineProps;
     contextInfo.pfnFetchPap                         = _pfnFetchPap;
     contextInfo.pfnGetRunTextMetrics                = _pfnGetRunTextMetrics;
     contextInfo.pfnGetRunCharWidths                 = _pfnGetRunCharWidths;
     contextInfo.pfnGetDurMaxExpandRagged            = _pfnGetDurMaxExpandRagged;
     contextInfo.pfnDrawTextRun                      = _pfnDrawTextRun;
     contextInfo.pfnGetGlyphPositions                = _pfnGetGlyphPositions;
     contextInfo.pfnGetAutoNumberInfo                = _pfnGetAutoNumberInfo;
     contextInfo.pfnDrawGlyphs                       = _pfnDrawGlyphs;
     contextInfo.pfnGetObjectHandlerInfo             = _pfnGetObjectHandlerInfo;
     contextInfo.pfnGetRunUnderlineInfo              = _pfnGetRunUnderlineInfo;
     contextInfo.pfnGetRunStrikethroughInfo          = _pfnGetRunStrikethroughInfo;
     contextInfo.pfnHyphenate                        = _pfnHyphenate;
     contextInfo.pfnGetNextHyphenOpp                 = _pfnGetNextHyphenOpp;
     contextInfo.pfnGetPrevHyphenOpp                 = _pfnGetPrevHyphenOpp;
     contextInfo.pfnDrawUnderline                    = _pfnDrawUnderline;
     contextInfo.pfnDrawStrikethrough                = _pfnDrawStrikethrough;
     contextInfo.pfnFInterruptShaping                = _pfnFInterruptShaping;
     contextInfo.pfnGetCharCompressionInfoFullMixed  = _pfnGetCharCompressionInfoFullMixed;
     contextInfo.pfnGetCharExpansionInfoFullMixed    = _pfnGetCharExpansionInfoFullMixed;
     contextInfo.pfnGetGlyphCompressionInfoFullMixed = _pfnGetGlyphCompressionInfoFullMixed;
     contextInfo.pfnGetGlyphExpansionInfoFullMixed   = _pfnGetGlyphExpansionInfoFullMixed;
     contextInfo.pfnEnumText                         = _pfnEnumText;
     contextInfo.pfnEnumTab                          = _pfnEnumTab;
 }
        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); 
            }
        }
 internal static extern LsErr LoCreateContext(
     ref LsContextInfo               contextInfo,      // const
     ref LscbkRedefined              lscbkRedef,
     out IntPtr                      ploc
     );