Ejemplo n.º 1
0
        internal void Render(IntPtr hdc, RenderParameter param, RenderProfile prof, int y)
        {
            if (_text[0] == '\0')
            {
                return;                            //何も描かなくてよい
            }
            float fx = (float)param.TargetRect.Left;

            RectangleF rect = new RectangleF();

            rect.Y      = param.TargetRect.Top + y;
            rect.Height = prof.Pitch.Height;

            GWord word = _firstWord;

            while (word != null)
            {
                rect.X     = fx /*- prof.CharGap*/;             //Nativeな描画では不要?
                rect.Width = param.TargetRect.Right - rect.X;
                int ix = (int)rect.X;
                int iy = (int)rect.Y;

                TextDecoration dec = word.Decoration;

                //Brush brush = prof.CalcTextBrush(dec);
                uint   forecolorref = DrawUtil.ToCOLORREF(prof.CalcTextColor(dec));
                Color  bkcolor      = prof.CalcBackColor(dec);
                uint   bkcolorref   = DrawUtil.ToCOLORREF(bkcolor);
                IntPtr hfont        = prof.CalcHFONT_NoUnderline(dec, word.CharGroup);
                Win32.SelectObject(hdc, hfont);
                Win32.SetTextColor(hdc, forecolorref);
                Win32.SetBkColor(hdc, bkcolorref);
                Win32.SetBkMode(hdc, bkcolor == prof.BackColor? 1 : 2);               //基本背景色と一緒ならTRANSPARENT, 異なればOPAQUE
                IntPtr bkbrush = bkcolor == prof.BackColor? IntPtr.Zero : Win32.CreateSolidBrush(bkcolorref);

                int display_length = WordDisplayLength(word);
                if (word.Decoration == null)                //装飾なし
                //g.DrawString(WordText(word), font, brush, rect);
                {
                    DrawWord(hdc, ix, iy, word);
                }
                else
                {
                    //if(dec.Bold || (!prof.UsingIdenticalFont && word.CharGroup==CharGroup.TwoBytes))
                    if (dec.Bold || word.CharGroup == CharGroup.TwoBytes)                  //同じフォント指定でも日本語が半角の2倍でない場合あり。パフォーマンス問題はクリアされつつあるので確実に1文字ずつ描画
                    {
                        DrawStringByOneChar2(hdc, word, display_length, bkbrush, rect.X, iy, prof);
                    }
                    else
                    {
                        DrawWord(hdc, ix, iy, word);                         //いまやアホな描画エンジンの問題からは解放された!
                    }
                }
                //Debug.WriteLine("PW="+p.Pitch.Width+",TL="+(pb.Text.Length*p.Pitch.Width)+", real="+g.MeasureString(pb.Text, p.Font).Width);
                if (dec.Underline)
                {
                    DrawUnderline(hdc, forecolorref, ix, iy + (int)prof.Pitch.Height - 1, (int)(prof.Pitch.Width * display_length));
                }

                fx  += prof.Pitch.Width * display_length;
                word = word.Next;
                if (bkbrush != IntPtr.Zero)
                {
                    Win32.DeleteObject(bkbrush);
                }
            }
        }
Ejemplo n.º 2
0
        internal void Render(IntPtr hdc, RenderProfile prof, Color baseBackColor, int x, int y)
        {
            if (_text.Length == 0 || _text[0] == '\0')
            {
                return; //何も描かなくてよい。これはよくあるケース
            }
            float fx0 = (float)x;
            float fx1 = fx0;
            int   y1  = y;
            int   y2  = y1 + (int)prof.Pitch.Height;

            float pitch = prof.Pitch.Width;
            int   defaultBackColorArgb = baseBackColor.ToArgb();

            Win32.SetBkMode(hdc, Win32.TRANSPARENT);

            GWord word = _firstWord;

            while (word != null)
            {
                TextDecoration dec = word.Decoration;

                IntPtr hFont = prof.CalcHFONT_NoUnderline(dec, word.CharGroup);
                Win32.SelectObject(hdc, hFont);

                uint foreColorRef = DrawUtil.ToCOLORREF(prof.CalcTextColor(dec));
                Win32.SetTextColor(hdc, foreColorRef);

                Color bkColor  = prof.CalcBackColor(dec);
                bool  isOpaque = (bkColor.ToArgb() != defaultBackColorArgb);
                if (isOpaque)
                {
                    uint bkColorRef = DrawUtil.ToCOLORREF(bkColor);
                    Win32.SetBkColor(hdc, bkColorRef);
                }

                int nextOffset = GetNextOffset(word);

                float fx2 = fx0 + pitch * nextOffset;

                if (prof.CalcBold(dec) || CharGroupUtil.IsCJK(word.CharGroup))
                {
                    // It is not always true that width of a character in the CJK font is twice of a character in the ASCII font.
                    // Characters are drawn one by one to adjust pitch.

                    int   step      = CharGroupUtil.GetColumnsPerCharacter(word.CharGroup);
                    float charPitch = pitch * step;
                    int   offset    = word.Offset;
                    float fx        = fx1;
                    if (isOpaque)
                    {
                        // If background fill is required, we call ExtTextOut() with ETO_OPAQUE to draw the first character.
                        if (offset < nextOffset)
                        {
                            Win32.RECT rect = new Win32.RECT((int)fx1, y1, (int)fx2, y2);
                            char       ch   = _text[offset];
                            Debug.Assert(ch != GLine.WIDECHAR_PAD);
                            unsafe {
                                Win32.ExtTextOut(hdc, rect.left, rect.top, Win32.ETO_OPAQUE, &rect, &ch, 1, null);
                            }
                        }
                        offset += step;
                        fx     += charPitch;
                    }

                    for (; offset < nextOffset; offset += step)
                    {
                        char ch = _text[offset];
                        Debug.Assert(ch != GLine.WIDECHAR_PAD);
                        unsafe {
                            Win32.ExtTextOut(hdc, (int)fx, y1, 0, null, &ch, 1, null);
                        }
                        fx += charPitch;
                    }
                }
                else
                {
                    int offset        = word.Offset;
                    int displayLength = nextOffset - offset;
                    if (isOpaque)
                    {
                        Win32.RECT rect = new Win32.RECT((int)fx1, y1, (int)fx2, y2);
                        unsafe
                        {
                            fixed(char *p = &_text[offset])
                            {
                                Win32.ExtTextOut(hdc, rect.left, rect.top, Win32.ETO_OPAQUE, &rect, p, displayLength, null);
                            }
                        }
                    }
                    else
                    {
                        unsafe
                        {
                            fixed(char *p = &_text[offset])
                            {
                                Win32.ExtTextOut(hdc, (int)fx1, y1, 0, null, p, displayLength, null);
                            }
                        }
                    }
                }

                if (dec.Underline)
                {
                    DrawUnderline(hdc, foreColorRef, (int)fx1, y2 - 1, (int)fx2 - (int)fx1);
                }

                fx1  = fx2;
                word = word.Next;
            }
        }