예제 #1
0
        public static void DrawTextRun(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, int x, int baselineY, Underline underline)
        {
            uint crColor = 0u;

            try
            {
                uint colorInt = run.ColorInt;
                if (underline != null)
                {
                    underline.Draw(hdc, (int)((double)run.UnderlineHeight * 0.085), colorInt);
                }
                crColor = Win32.SetTextColor(hdc, colorInt);
                GlyphData      glyphData            = run.GetGlyphData(hdc, fontCache);
                GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData;
                CachedFont     cachedFont           = run.GetCachedFont(hdc, fontCache);
                fontCache.SelectFontObject(hdc, cachedFont.Hfont);
                int num = Win32.ScriptTextOut(hdc, ref cachedFont.ScriptCache, x, baselineY, 4u, IntPtr.Zero, ref run.SCRIPT_ANALYSIS, IntPtr.Zero, 0, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphData.Advances, (int[])null, glyphData.GOffsets);
                if (Win32.Failed(num))
                {
                    Marshal.ThrowExceptionForHR(num);
                }
            }
            finally
            {
                crColor = Win32.SetTextColor(hdc, crColor);
            }
        }
예제 #2
0
        private void TextScriptPlace(Win32DCSafeHandle hdc, bool fontSelected, FontCache fontCache)
        {
            int            num = 0;
            GlyphShapeData glyphScriptShapeData = this.m_cachedGlyphData.GlyphScriptShapeData;

            if (fontSelected)
            {
                num = Win32.ScriptPlace(hdc, ref this.m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref this.SCRIPT_ANALYSIS, this.m_cachedGlyphData.RawAdvances, this.m_cachedGlyphData.RawGOffsets, ref this.m_cachedGlyphData.ABC);
            }
            else
            {
                num = Win32.ScriptPlace(IntPtr.Zero, ref this.m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref this.SCRIPT_ANALYSIS, this.m_cachedGlyphData.RawAdvances, this.m_cachedGlyphData.RawGOffsets, ref this.m_cachedGlyphData.ABC);
                if (num == -2147483638)
                {
                    fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont);
                    num = Win32.ScriptPlace(hdc, ref this.m_cachedFont.ScriptCache, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.VisAttrs, ref this.SCRIPT_ANALYSIS, this.m_cachedGlyphData.RawAdvances, this.m_cachedGlyphData.RawGOffsets, ref this.m_cachedGlyphData.ABC);
                }
            }
            if (Win32.Failed(num))
            {
                Marshal.ThrowExceptionForHR(num);
            }
            if (this.m_cachedGlyphData.ABC.Width > 0 && this.m_text.Length == 1 && TextBox.IsWhitespaceControlChar(this.m_text[0]))
            {
                this.m_cachedGlyphData.ABC.SetToZeroWidth();
            }
        }
예제 #3
0
        public TextBoxContext MapPoint(Graphics g, PointF pt, out bool atEndOfLine)
        {
            TextBoxContext textBoxContext = null;

            atEndOfLine = false;
            TextRun textRun = default(TextRun);
            int     iX      = default(int);

            textBoxContext = this.GetParagraphAndRunIndex(g, (int)pt.X, (int)pt.Y, out textRun, out iX, out atEndOfLine);
            if (textRun != null)
            {
                GlyphData      glyphData            = textRun.GlyphData;
                GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData;
                if (glyphData != null && textRun.CharacterCount > 0)
                {
                    int num  = 0;
                    int num2 = 0;
                    int num3 = Win32.ScriptXtoCP(iX, textRun.CharacterCount, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, glyphData.Advances, ref textRun.SCRIPT_ANALYSIS, ref num, ref num2);
                    if (Win32.Failed(num3))
                    {
                        Marshal.ThrowExceptionForHR(num3);
                    }
                    if (textRun.ScriptAnalysis.fLayoutRTL == 1)
                    {
                        if (num == -1)
                        {
                            textBoxContext.TextRunCharacterIndex += textRun.CharacterCount;
                        }
                        else if (pt.X <= 0.0)
                        {
                            TextBoxContext textBoxContext2 = textBoxContext;
                            textBoxContext2.TextRunCharacterIndex = textBoxContext2.TextRunCharacterIndex;
                        }
                        else
                        {
                            textBoxContext.TextRunCharacterIndex += num + num2;
                        }
                    }
                    else
                    {
                        textBoxContext.TextRunCharacterIndex += num + num2;
                    }
                }
            }
            if (textBoxContext == null)
            {
                textBoxContext = new TextBoxContext();
            }
            return(textBoxContext);
        }
예제 #4
0
        private CaretInfo MapLocation(Win32DCSafeHandle hdc, TextBoxContext location, bool relativeToRun, bool moveCaretToNextLine, out TextRun run)
        {
            CaretInfo caretInfo = null;

            run = null;
            int   lineYOffset = default(int);
            int   lineHeight  = default(int);
            int   iCP         = default(int);
            bool  isFirstLine = default(bool);
            bool  isLastLine  = default(bool);
            Point paragraphAndRunCoordinates = this.GetParagraphAndRunCoordinates(hdc, location, moveCaretToNextLine, out lineYOffset, out lineHeight, out run, out iCP, out isFirstLine, out isLastLine);

            if (run != null)
            {
                GlyphData      glyphData            = run.GlyphData;
                GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData;
                int            num = 0;
                if (glyphData != null && run.CharacterCount > 0)
                {
                    int num2 = Win32.ScriptCPtoX(iCP, false, run.CharacterCount, glyphScriptShapeData.GlyphCount, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, glyphData.Advances, ref run.SCRIPT_ANALYSIS, ref num);
                    if (Win32.Failed(num2))
                    {
                        Marshal.ThrowExceptionForHR(num2);
                    }
                }
                caretInfo = new CaretInfo();
                CachedFont cachedFont = run.GetCachedFont(hdc, this.FontCache);
                caretInfo.Height      = cachedFont.GetHeight(hdc, this.FontCache);
                caretInfo.Ascent      = cachedFont.GetAscent(hdc, this.FontCache);
                caretInfo.Descent     = cachedFont.GetDescent(hdc, this.FontCache);
                caretInfo.LineHeight  = lineHeight;
                caretInfo.LineYOffset = lineYOffset;
                caretInfo.IsFirstLine = isFirstLine;
                caretInfo.IsLastLine  = isLastLine;
                List <Paragraph> rTParagraph = this.RTParagraphs;
                int y = paragraphAndRunCoordinates.Y - caretInfo.Ascent;
                if (relativeToRun)
                {
                    caretInfo.Position = new Point(num, y);
                }
                else
                {
                    caretInfo.Position = new Point(paragraphAndRunCoordinates.X + num, y);
                }
            }
            return(caretInfo);
        }
        static ScriptProperties()
        {
            IntPtr ptr  = default(IntPtr);
            int    num  = default(int);
            int    num2 = Win32.ScriptGetProperties(out ptr, out num);

            if (Win32.Failed(num2))
            {
                Marshal.ThrowExceptionForHR(num2);
            }
            ScriptProperties.ScriptsProps = new ScriptProperties[num];
            for (int i = 0; i < num; i++)
            {
                IntPtr ptr2  = Marshal.ReadIntPtr(ptr, i * IntPtr.Size);
                long   value = Marshal.ReadInt64(ptr2);
                ScriptProperties.ScriptsProps[i] = new ScriptProperties(value);
            }
        }
예제 #6
0
        public int[] GetLogicalWidths(Win32DCSafeHandle hdc, FontCache fontCache)
        {
            GlyphData glyphData = this.GetGlyphData(hdc, fontCache);

            int[] array = new int[this.m_text.Length];
            int   num   = Win32.ScriptGetLogicalWidths(ref this.SCRIPT_ANALYSIS, this.m_text.Length, glyphData.GlyphScriptShapeData.GlyphCount, glyphData.ScaledAdvances, glyphData.GlyphScriptShapeData.Clusters, glyphData.GlyphScriptShapeData.VisAttrs, array);

            if (Win32.Failed(num))
            {
                Marshal.ThrowExceptionForHR(num);
            }
            if (glyphData.Scaled)
            {
                for (int i = 0; i < array.Length; i++)
                {
                    array[i] = glyphData.Scale(array[i]);
                }
            }
            return(array);
        }
예제 #7
0
        public static void DrawClippedTextRun(TextRun run, Win32DCSafeHandle hdc, FontCache fontCache, int x, int baselineY, uint fontColorOverride, Rectangle clipRect, Underline underline)
        {
            uint   crColor = 0u;
            IntPtr intPtr  = IntPtr.Zero;

            try
            {
                if (underline != null)
                {
                    underline.Draw(hdc, (int)((double)run.UnderlineHeight * 0.085), fontColorOverride);
                }
                RECT rECT = default(RECT);
                rECT.left   = clipRect.Left;
                rECT.right  = clipRect.Right;
                rECT.top    = clipRect.Top;
                rECT.bottom = clipRect.Bottom;
                crColor     = Win32.SetTextColor(hdc, fontColorOverride);
                GlyphData      glyphData            = run.GetGlyphData(hdc, fontCache);
                GlyphShapeData glyphScriptShapeData = glyphData.GlyphScriptShapeData;
                CachedFont     cachedFont           = run.GetCachedFont(hdc, fontCache);
                fontCache.SelectFontObject(hdc, cachedFont.Hfont);
                intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(rECT));
                Marshal.StructureToPtr(rECT, intPtr, false);
                int num = Win32.ScriptTextOut(hdc, ref cachedFont.ScriptCache, x, baselineY, 4u, intPtr, ref run.SCRIPT_ANALYSIS, IntPtr.Zero, 0, glyphScriptShapeData.Glyphs, glyphScriptShapeData.GlyphCount, glyphData.Advances, (int[])null, glyphData.GOffsets);
                if (Win32.Failed(num))
                {
                    Marshal.ThrowExceptionForHR(num);
                }
            }
            finally
            {
                if (intPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(intPtr);
                }
                crColor = Win32.SetTextColor(hdc, crColor);
            }
        }
예제 #8
0
 private static void AnalyzeForBreakPositions(List <TextRun> itemRuns, string itemsText)
 {
     if (itemsText.Length != 0)
     {
         SCRIPT_ANALYSIS  sCRIPT_ANALYSIS = itemRuns[0].SCRIPT_ANALYSIS;
         SCRIPT_LOGATTR[] array           = new SCRIPT_LOGATTR[itemsText.Length];
         int num = Win32.ScriptBreak(itemsText, itemsText.Length, ref sCRIPT_ANALYSIS, array);
         if (Win32.Failed(num))
         {
             Marshal.ThrowExceptionForHR(num);
         }
         int num2 = 0;
         for (int i = 0; i < itemRuns.Count; i++)
         {
             TextRun          textRun = itemRuns[i];
             int              length  = textRun.Text.Length;
             SCRIPT_LOGATTR[] array2  = new SCRIPT_LOGATTR[length];
             Array.Copy(array, num2, array2, 0, length);
             textRun.ScriptLogAttr = array2;
             num2 += length;
         }
     }
 }
예제 #9
0
        public void ScriptItemize(RPLFormat.Directions direction)
        {
            SCRIPT_ITEM[] array         = null;
            int           num           = 0;
            StringBuilder stringBuilder = new StringBuilder();
            string        nextTextBlock;

            while ((nextTextBlock = this.GetNextTextBlock()) != null)
            {
                if (nextTextBlock.Length > 0)
                {
                    SCRIPT_CONTROL sCRIPT_CONTROL = default(SCRIPT_CONTROL);
                    sCRIPT_CONTROL.dword1 = 16777216u;
                    ScriptState scriptState = new ScriptState();
                    scriptState.uBidiLevel = ((direction != 0) ? 1 : 0);
                    SCRIPT_STATE  as_SCRIPT_STATE = scriptState.GetAs_SCRIPT_STATE();
                    SCRIPT_ITEM[] array2          = new SCRIPT_ITEM[nextTextBlock.Length + 1];
                    int           num2            = 0;
                    int           num3            = Win32.ScriptItemize(nextTextBlock, nextTextBlock.Length, array2.Length, ref sCRIPT_CONTROL, ref as_SCRIPT_STATE, array2, ref num2);
                    if (Win32.Failed(num3))
                    {
                        Marshal.ThrowExceptionForHR(num3);
                    }
                    if (array == null)
                    {
                        array = array2;
                        num   = num2;
                    }
                    else
                    {
                        SCRIPT_ITEM[] array3 = new SCRIPT_ITEM[num + array2.Length];
                        Array.Copy(array, 0, array3, 0, num);
                        for (int i = 0; i < array2.Length; i++)
                        {
                            SCRIPT_ITEM sCRIPT_ITEM = array2[i];
                            sCRIPT_ITEM.iCharPos += stringBuilder.Length;
                            array3[num + i]       = sCRIPT_ITEM;
                        }
                        array = array3;
                        num  += num2;
                    }
                    stringBuilder.Append(nextTextBlock);
                }
            }
            if (num > 0)
            {
                List <SCRIPT_ITEM> list = new List <SCRIPT_ITEM>();
                int  num4 = -1;
                bool flag = false;
                for (int j = 0; j < num; j++)
                {
                    int bidiLevel  = ScriptState.GetBidiLevel(array[j].analysis.state.word1);
                    int bidiLevel2 = ScriptState.GetBidiLevel(array[j + 1].analysis.state.word1);
                    if (bidiLevel == bidiLevel2 && this.CanMergeItemizedRuns(array[j].iCharPos, array[j + 1].iCharPos - 1, stringBuilder))
                    {
                        if (num4 < 0)
                        {
                            num4 = j;
                        }
                    }
                    else
                    {
                        if (num4 >= 0)
                        {
                            list.Add(array[num4]);
                        }
                        list.Add(array[j]);
                        num4 = -1;
                    }
                }
                if (num4 >= 0)
                {
                    list.Add(array[num4]);
                }
                list.Add(array[num]);
                array = null;
                num   = list.Count - 1;
                if (num == 1)
                {
                    for (int k = 0; k < this.m_runs.Count; k++)
                    {
                        this.m_runs[k].SCRIPT_ANALYSIS = list[0].analysis;
                    }
                    Paragraph.AnalyzeForBreakPositions(this.m_runs, stringBuilder.ToString());
                }
                else
                {
                    List <TextRun> list2 = new List <TextRun>();
                    for (int l = 0; l < num; l++)
                    {
                        int            iCharPos            = list[l].iCharPos;
                        int            endingParaCharIndex = list[l + 1].iCharPos - 1;
                        List <TextRun> collection          = this.ExtractRuns(iCharPos, endingParaCharIndex, list[l].analysis);
                        list2.AddRange(collection);
                    }
                    this.m_runs = list2;
                }
            }
        }
예제 #10
0
        public void ShapeAndPlace(Win32DCSafeHandle hdc, FontCache fontCache)
        {
            bool verticalFont = false;

            if (fontCache.AllowVerticalFont)
            {
                verticalFont = this.HasEastAsianChars;
            }
            if (this.m_cachedFont == null)
            {
                this.m_cachedFont = fontCache.GetFont(this.m_textRunProps, this.GetCharset(), verticalFont);
                this.FallbackFont = false;
            }
            CachedFont cachedFont = this.m_cachedFont;
            bool       flag       = false;
            bool       flag2      = false;
            string     text       = this.m_text;
            int        num        = Convert.ToInt32((double)text.Length * 1.5 + 16.0);

            this.m_cachedGlyphData = new GlyphData(num, text.Length);
            GlyphShapeData glyphScriptShapeData = this.m_cachedGlyphData.GlyphScriptShapeData;
            int            num2 = Win32.ScriptShape(IntPtr.Zero, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount);

            if (num2 == -2147483638)
            {
                flag = true;
                fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont);
                num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount);
            }
            if (num2 == -2147024882)
            {
                num = text.Length * 3;
                this.m_cachedGlyphData = new GlyphData(num, text.Length);
                glyphScriptShapeData   = this.m_cachedGlyphData.GlyphScriptShapeData;
                num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount);
            }
            if (!this.FallbackFont)
            {
                if (num2 == -2147220992)
                {
                    int num3 = 0;
                    num3 = ((!this.m_itemizedScriptId.HasValue) ? this.ScriptAnalysis.eScript : this.m_itemizedScriptId.Value);
                    this.m_cachedFont = fontCache.GetFallbackFont(this.m_textRunProps, this.GetCharset(), num3, verticalFont);
                    fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont);
                    flag  = true;
                    flag2 = true;
                    num2  = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount);
                }
                else if (this.HasEastAsianChars)
                {
                    if (!flag)
                    {
                        fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont);
                        flag = true;
                    }
                    Win32.SCRIPT_FONTPROPERTIES sCRIPT_FONTPROPERTIES = default(Win32.SCRIPT_FONTPROPERTIES);
                    sCRIPT_FONTPROPERTIES.cBytes = 16;
                    num2 = Win32.ScriptGetFontProperties(hdc, ref this.m_cachedFont.ScriptCache, ref sCRIPT_FONTPROPERTIES);
                    short wgDefault = sCRIPT_FONTPROPERTIES.wgDefault;
                    int   num4      = 0;
                    num4 = ((!this.m_itemizedScriptId.HasValue) ? this.ScriptAnalysis.eScript : this.m_itemizedScriptId.Value);
                    int num5 = 0;
                    while (num5 < glyphScriptShapeData.GlyphCount)
                    {
                        if (glyphScriptShapeData.Glyphs[num5] != wgDefault)
                        {
                            num5++;
                            continue;
                        }
                        this.m_cachedFont = fontCache.GetFallbackFont(this.m_textRunProps, this.GetCharset(), num4, verticalFont);
                        this.m_cachedFont.DefaultGlyph = wgDefault;
                        fontCache.SelectFontObject(hdc, this.m_cachedFont.Hfont);
                        flag  = true;
                        flag2 = true;
                        num2  = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount);
                        break;
                    }
                }
            }
            if (num2 == -2147220992)
            {
                this.m_cachedFont = cachedFont;
                if (!flag || flag2)
                {
                    Win32ObjectSafeHandle win32ObjectSafeHandle = Win32.SelectObject(hdc, this.m_cachedFont.Hfont);
                    win32ObjectSafeHandle.SetHandleAsInvalid();
                    flag = true;
                }
                flag2 = false;
                this.SetUndefinedScript();
                num2 = Win32.ScriptShape(hdc, ref this.m_cachedFont.ScriptCache, text, text.Length, num, ref this.SCRIPT_ANALYSIS, glyphScriptShapeData.Glyphs, glyphScriptShapeData.Clusters, glyphScriptShapeData.VisAttrs, ref glyphScriptShapeData.GlyphCount);
            }
            if (Win32.Failed(num2))
            {
                Marshal.ThrowExceptionForHR(num2);
            }
            if (flag2)
            {
                this.FallbackFont = true;
            }
            this.m_cachedGlyphData.TrimToGlyphCount();
            this.m_cachedGlyphData.ScaleFactor = this.m_cachedFont.ScaleFactor;
            this.TextScriptPlace(hdc, flag, fontCache);
        }
예제 #11
0
 public void ScriptLayout(Win32DCSafeHandle hdc, FontCache fontCache)
 {
     if (this.m_visualRuns == null)
     {
         int count = this.m_logicalRuns.Count;
         if (count != 0)
         {
             byte[] array  = new byte[count];
             int[]  array2 = new int[count];
             for (int i = 0; i < count; i++)
             {
                 array[i] = (byte)this.m_logicalRuns[i].ScriptAnalysis.s.uBidiLevel;
             }
             int num = Win32.ScriptLayout(count, array, null, array2);
             if (Win32.Failed(num))
             {
                 Marshal.ThrowExceptionForHR(num);
             }
             this.m_visualRuns = new List <TextRun>(count);
             for (int j = 0; j < count; j++)
             {
                 this.m_visualRuns.Add(null);
             }
             for (int k = 0; k < count; k++)
             {
                 this.m_visualRuns[array2[k]] = this.m_logicalRuns[k];
             }
             int num2 = 0;
             int l    = -1;
             for (int m = 0; m < count; m++)
             {
                 TextRun textRun = this.m_visualRuns[m];
                 textRun.UnderlineHeight = 0;
                 if (textRun.TextRunProperties.TextDecoration == RPLFormat.TextDecorations.Underline)
                 {
                     if (l < 0)
                     {
                         l = m;
                     }
                     int height = textRun.GetHeight(hdc, fontCache);
                     if (height > num2)
                     {
                         num2 = height;
                     }
                 }
                 else if (l >= 0)
                 {
                     for (; l < m; l++)
                     {
                         this.m_visualRuns[l].UnderlineHeight = num2;
                     }
                     num2 = 0;
                     l    = -1;
                 }
             }
             if (l >= 0)
             {
                 for (; l < count; l++)
                 {
                     this.m_visualRuns[l].UnderlineHeight = num2;
                 }
             }
         }
     }
 }