internal static void MeasureCharWidths(IntPtr hFont,
                                               out int[] charWidths,
                                               out NativeTextWin32.FontABC[] abcSizes)
        {
            //only in ascii range
            //current version
            charWidths = new int[MAX_CODEPOINT_NO + 1]; //
            MyWin32.SelectObject(win32MemDc.DC, hFont);
            unsafe
            {
                //see: https://msdn.microsoft.com/en-us/library/ms404377(v=vs.110).aspx
                //A code page contains 256 code points and is zero-based.
                //In most code pages, code points 0 through 127 represent the ASCII character set,
                //and code points 128 through 255 differ significantly between code pages
                abcSizes = new NativeTextWin32.FontABC[MAX_CODEPOINT_NO + 1];
                fixed(NativeTextWin32.FontABC *abc = abcSizes)
                {
                    NativeTextWin32.GetCharABCWidths(win32MemDc.DC, (uint)0, (uint)MAX_CODEPOINT_NO, abc);
                }

                for (int i = 0; i < (MAX_CODEPOINT_NO + 1); ++i)
                {
                    charWidths[i] = abcSizes[i].Sum;
                }
            }
        }
        /// <summary>
        /// Special draw logic to draw transparent text using GDI.<br/>
        /// 1. Create in-memory DC<br/>
        /// 2. Copy background to in-memory DC<br/>
        /// 3. Draw the text to in-memory DC<br/>
        /// 4. Copy the in-memory DC to the proper location with alpha blend<br/>
        /// </summary>
        static void DrawTransparentText(IntPtr hdc, string str, Font font, Point point, Size size, Color color)
        {
            IntPtr dib;
            var    memoryHdc = Win32Utils.CreateMemoryHdc(hdc, size.Width, size.Height, out dib);

            try
            {
                // copy target background to memory HDC so when copied back it will have the proper background
                Win32Utils.BitBlt(memoryHdc, 0, 0, size.Width, size.Height, hdc, point.X, point.Y, Win32Utils.BitBltCopy);

                // Create and select font
                Win32Utils.SelectObject(memoryHdc, FontStore.GetCachedHFont(font.InnerFont as System.Drawing.Font));
                Win32Utils.SetTextColor(memoryHdc, (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R);

                // Draw text to memory HDC
                NativeTextWin32.TextOut(memoryHdc, 0, 0, str, str.Length);

                // copy from memory HDC to normal HDC with alpha blend so achieve the transparent text
                Win32Utils.AlphaBlend(hdc, point.X, point.Y, size.Width, size.Height, memoryHdc, 0, 0, size.Width, size.Height, new BlendFunction(color.A));
            }
            finally
            {
                Win32Utils.ReleaseMemoryHdc(memoryHdc, dib);
            }
        }
        /// <summary>
        /// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
        /// using the given font <paramref name="font"/>.<br/>
        /// Restrict the width of the string and get the number of characters able to fit in the restriction and
        /// the width those characters take.
        /// </summary>
        /// <param name="str">the string to measure</param>
        /// <param name="font">the font to measure string with</param>
        /// <param name="maxWidth">the max width to render the string in</param>
        /// <param name="charFit">the number of characters that will fit under <see cref="maxWidth"/> restriction</param>
        /// <param name="charFitWidth"></param>
        /// <returns>the size of the string</returns>
        public static PixelFarm.Drawing.Size MeasureString(
            char[] buff, int startAt, int len, RequestFont font,
            float maxWidth, out int charFit, out int charFitWidth)
        {
            SetFont(font);
            if (buff.Length == 0)
            {
                charFit      = 0;
                charFitWidth = 0;
                return(PixelFarm.Drawing.Size.Empty);
            }

            var size = new Size(); //win32

            unsafe
            {
                fixed(char *startAddr = &buff[0])
                {
                    NativeTextWin32.UnsafeGetTextExtentExPoint(
                        win32MemDc.DC, startAddr + startAt, len,
                        (int)Math.Round(maxWidth), _charFit, _charFitWidth, ref size);
                }
            }
            charFit      = _charFit[0];
            charFitWidth = charFit > 0 ? _charFitWidth[charFit - 1] : 0;
            return(new PixelFarm.Drawing.Size(size.W, size.H));
            //}
        }
Exemple #4
0
        //======================================

        public Size MeasureString(char[] buff, int startAt, int len, Font font)
        {
            //if (_useGdiPlusTextRendering)
            //{
            //    ReleaseHdc();
            //    _characterRanges[0] = new System.Drawing.CharacterRange(0, len);
            //    _stringFormat.SetMeasurableCharacterRanges(_characterRanges);
            //    System.Drawing.Font font2 = (System.Drawing.Font)font.InnerFont;

            //    var size = gx.MeasureCharacterRanges(
            //        new string(buff, startAt, len),
            //        font2,
            //        System.Drawing.RectangleF.Empty,
            //        _stringFormat)[0].GetBounds(gx).Size;
            //    return new PixelFarm.Drawing.Size((int)Math.Round(size.Width), (int)Math.Round(size.Height));
            //}
            //else
            //{
            SetFont(font);
            PixelFarm.Drawing.Size size = new Size();
            unsafe
            {
                fixed(char *startAddr = &buff[0])
                {
                    NativeTextWin32.UnsafeGetTextExtentPoint32(tempDc, startAddr + startAt, len, ref size);
                }
            }
            return(size);
            //}
        }
Exemple #5
0
        /// <summary>
        /// Measure the width and height of string <paramref name="str"/> when drawn on device context HDC
        /// using the given font <paramref name="font"/>.<br/>
        /// Restrict the width of the string and get the number of characters able to fit in the restriction and
        /// the width those characters take.
        /// </summary>
        /// <param name="str">the string to measure</param>
        /// <param name="font">the font to measure string with</param>
        /// <param name="maxWidth">the max width to render the string in</param>
        /// <param name="charFit">the number of characters that will fit under <see cref="maxWidth"/> restriction</param>
        /// <param name="charFitWidth"></param>
        /// <returns>the size of the string</returns>
        public Size MeasureString(char[] buff, int startAt, int len, Font font, float maxWidth, out int charFit, out int charFitWidth)
        {
            //if (_useGdiPlusTextRendering)
            //{
            //    ReleaseHdc();
            //    throw new NotSupportedException("Char fit string measuring is not supported for GDI+ text rendering");
            //}
            //else
            //{
            SetFont(font);

            var size = new PixelFarm.Drawing.Size();

            unsafe
            {
                fixed(char *startAddr = &buff[0])
                {
                    NativeTextWin32.UnsafeGetTextExtentExPoint(
                        tempDc, startAddr + startAt, len,
                        (int)Math.Round(maxWidth), _charFit, _charFitWidth, ref size);
                }
            }
            charFit      = _charFit[0];
            charFitWidth = charFit > 0 ? _charFitWidth[charFit - 1] : 0;
            return(size);
            //}
        }
Exemple #6
0
        public override void DrawText(char[] buffer, Rectangle logicalTextBox, int textAlignment)
        {
            ReleaseHdc();
            IntPtr gxdc     = gx.GetHdc();
            var    clipRect = System.Drawing.Rectangle.Intersect(logicalTextBox.ToRect(), currentClipRect);

            clipRect.Offset(canvasOriginX, canvasOriginY);
            MyWin32.SetRectRgn(hRgn,
                               clipRect.Left,
                               clipRect.Top,
                               clipRect.Right,
                               clipRect.Bottom);
            MyWin32.SelectClipRgn(gxdc, hRgn);

            NativeTextWin32.TextOut(gxdc, CanvasOrgX + logicalTextBox.X, CanvasOrgY + logicalTextBox.Y, buffer, buffer.Length);

            MyWin32.SelectClipRgn(gxdc, IntPtr.Zero);
            gx.ReleaseHdc();

            //ReleaseHdc();
            //IntPtr gxdc = gx.GetHdc();
            //MyWin32.SetViewportOrgEx(gxdc, CanvasOrgX, CanvasOrgY, IntPtr.Zero);
            //System.Drawing.Rectangle clipRect =
            //    System.Drawing.Rectangle.Intersect(logicalTextBox.ToRect(), currentClipRect);
            //clipRect.Offset(CanvasOrgX, CanvasOrgY);
            //MyWin32.SetRectRgn(hRgn, clipRect.X, clipRect.Y, clipRect.Right, clipRect.Bottom);
            //MyWin32.SelectClipRgn(gxdc, hRgn);
            //NativeTextWin32.TextOut(gxdc, logicalTextBox.X, logicalTextBox.Y, buffer, buffer.Length);
            //MyWin32.SelectClipRgn(gxdc, IntPtr.Zero);
            //MyWin32.SetViewportOrgEx(gxdc, -CanvasOrgX, -CanvasOrgY, IntPtr.Zero);
            //gx.ReleaseHdc();
        }
Exemple #7
0
        public void MeasureCharWidths(IntPtr hFont, out int[] charWidths, out NativeTextWin32.FontABC[] abcSizes)
        {
            if (!isInit)
            {
                Init();
            }
            //only in ascii range
            //current version
            charWidths = new int[256];
            MyWin32.SelectObject(hdc, hFont);
            unsafe
            {
                abcSizes = new NativeTextWin32.FontABC[256];
                fixed(NativeTextWin32.FontABC *abc = abcSizes)
                {
                    NativeTextWin32.GetCharABCWidths(hdc, (uint)0, (uint)255, abc);
                }

                for (int i = 0; i < 161; i++)
                {
                    charWidths[i] = abcSizes[i].Sum;
                }
                for (int i = 161; i < 255; i++)
                {
                    charWidths[i] = abcSizes[i].Sum;
                }
            }
        }
Exemple #8
0
        void PrepareCharacterMapWhiteOnBlack(char[] buffer)
        {
            //-----------------------------------------------------------------------
            IntPtr gxdc = gx.GetHdc();
            int    len  = buffer.Length;
            //draw each character
            int curX = 0;
            int curY = 0;

            //1. clear with white color,
            MyWin32.PatBlt(gxdc, 0, 0, width, height, MyWin32.BLACKNESS);
            //2. transparent background
            MyWin32.SetBkMode(gxdc, MyWin32._SetBkMode_TRANSPARENT);
            //3. white brush
            //set user font to dc
            MyWin32.SelectObject(gxdc, this.hFont);
            int rgb = ((255 & 0xFF) << 16 | (255 & 0xFF) << 8 | 255);

            MyWin32.SetTextColor(gxdc, rgb);

            //TODO:correct white text on black bg for subpixel rendering
            //when draw with subpixel rendering
            //on white bg -> red come first from left ,end with blue
            //on black bg -> blue come first from left, end with red

            int fontHeight    = fontInfo.FontHeight;
            int maxLineHeight = fontHeight;

            for (int i = 0; i < len; ++i)
            {
                //-----------------------------------------------------------------------
                //measure string
                //and make simple character map
                //-----------------------------------------------------------------------
                //measure each character ***
                //not adjust kerning***

                char    c             = buffer[i];
                FontABC abcWidth      = fontInfo.GetCharABCWidth(c);
                int     glyphBoxWidth = Math.Abs(abcWidth.a) + (int)abcWidth.b + abcWidth.c;
                if (abcWidth.Sum + curX > this.width)
                {
                    //start newline
                    curX          = 0;
                    curY         += maxLineHeight;
                    maxLineHeight = fontHeight;
                }

                NativeTextWin32.TextOut(gxdc, curX, curY, new char[] { c }, 1);
                charMap.Add(c, new PixelFarm.Drawing.RectangleF(curX, curY, glyphBoxWidth, fontHeight));
                curX += glyphBoxWidth; //move next
            }
            gx.ReleaseHdc(gxdc);
            //myTextBoardBmp = new Bitmap(width, height, new LazyGdiBitmapBufferProvider(this.textBoardBmp));
            //myTextBoardBmp.InnerImage = GLBitmapTextureHelper.CreateBitmapTexture(this.textBoardBmp);
        }
Exemple #9
0
 public int MeasureStringWidth(IntPtr hFont, char[] buffer, int length)
 {
     if (!isInit)
     {
         Init();
     }
     MyWin32.SelectObject(this.hdc, hFont);
     NativeTextWin32.WIN32SIZE size;
     NativeTextWin32.GetTextExtentPoint32(hdc, buffer, length, out size);
     return(size.Width);
 }
Exemple #10
0
        //public override float GetCharWidth(RequestFont f, char c)
        //{
        //    WinGdiFont winFont = WinGdiFontSystem.GetWinGdiFont(f);
        //    return winFont.GetGlyph(c).horiz_adv_x >> 6;
        //}
        public override void DrawText(char[] buffer, int x, int y)
        {
            var clipRect = currentClipRect;

            clipRect.Offset(canvasOriginX, canvasOriginY);
            //1.
            win32MemDc.SetClipRect(clipRect.Left, clipRect.Top, clipRect.Width, clipRect.Height);
            //2.
            NativeTextWin32.TextOut(win32MemDc.DC, CanvasOrgX + x, CanvasOrgY + y, buffer, buffer.Length);
            //3
            win32MemDc.ClearClipRect();
        }
Exemple #11
0
 public static PixelFarm.Drawing.Size MeasureString(char[] buff, int startAt, int len, RequestFont font)
 {
     SetFont(font);
     Win32.Size win32_size = new Size();
     if (buff.Length > 0)
     {
         unsafe
         {
             fixed(char *startAddr = &buff[0])
             {
                 NativeTextWin32.UnsafeGetTextExtentPoint32(win32MemDc.DC, startAddr + startAt, len, ref win32_size);
             }
         }
     }
     return(new PixelFarm.Drawing.Size(win32_size.W, win32_size.H));
 }
Exemple #12
0
        void PrepareCharacterMapBlackOnWhite(char[] buffer)
        {
            //-----------------------------------------------------------------------
            IntPtr gxdc = gx.GetHdc();
            int    len  = buffer.Length;
            //draw each character
            int curX = 0;
            int curY = 0;

            //1. clear with white color,
            MyWin32.PatBlt(gxdc, 0, 0, width, height, MyWin32.WHITENESS);
            //2. transparent background
            MyWin32.SetBkMode(gxdc, MyWin32._SetBkMode_TRANSPARENT);

            //set user font to dc
            MyWin32.SelectObject(gxdc, this.hFont);
            int fontHeight    = fontInfo.FontHeight;
            int maxLineHeight = fontHeight;

            for (int i = 0; i < len; ++i)
            {
                //-----------------------------------------------------------------------
                //measure string
                //and make simple character map
                //-----------------------------------------------------------------------
                //measure each character ***
                //not adjust kerning***

                char    c             = buffer[i];
                FontABC abcWidth      = fontInfo.GetCharABCWidth(c);
                int     glyphBoxWidth = Math.Abs(abcWidth.a) + (int)abcWidth.b + abcWidth.c;
                if (abcWidth.Sum + curX > this.width)
                {
                    //start newline
                    curX          = 0;
                    curY         += maxLineHeight;
                    maxLineHeight = fontHeight;
                }

                NativeTextWin32.TextOut(gxdc, curX, curY, new char[] { c }, 1);
                charMap.Add(c, new PixelFarm.Drawing.RectangleF(curX, curY, glyphBoxWidth, fontHeight));
                curX += glyphBoxWidth; //move next
            }
            gx.ReleaseHdc(gxdc);
            //myTextBoardBmp = new Bitmap(width, height, new LazyGdiBitmapBufferProvider(this.textBoardBmp));
            //myTextBoardBmp.InnerImage = GLBitmapTextureHelper.CreateBitmapTexture(this.textBoardBmp);
        }
Exemple #13
0
        //==============================================



        public override void DrawText(char[] buffer, int x, int y)
        {
            ReleaseHdc();
            IntPtr gxdc     = gx.GetHdc();
            var    clipRect = currentClipRect;

            clipRect.Offset(canvasOriginX, canvasOriginY);
            MyWin32.SetRectRgn(hRgn,
                               clipRect.Left,
                               clipRect.Top,
                               clipRect.Right,
                               clipRect.Bottom);
            MyWin32.SelectClipRgn(gxdc, hRgn);
            NativeTextWin32.TextOut(gxdc, CanvasOrgX + x, CanvasOrgY + y, buffer, buffer.Length);
            MyWin32.SelectClipRgn(gxdc, IntPtr.Zero);
            gx.ReleaseHdc();
        }
Exemple #14
0
        public override void DrawText(char[] str, int startAt, int len, Rectangle logicalTextBox, int textAlignment)
        {
#if DEBUG
            dbugCounter.dbugDrawStringCount++;
#endif
            var color = this.CurrentTextColor;
            if (color.A == 255)
            {
                var clipRect = Rectangle.Intersect(logicalTextBox,
                                                   new Rectangle(currentClipRect.Left,
                                                                 currentClipRect.Top,
                                                                 currentClipRect.Width,
                                                                 currentClipRect.Height));
                clipRect.Offset(canvasOriginX, canvasOriginY);
                MyWin32.SetRectRgn(hRgn,
                                   clipRect.Left,
                                   clipRect.Top,
                                   clipRect.Right,
                                   clipRect.Bottom);
                MyWin32.SelectClipRgn(tempDc, hRgn);

                unsafe
                {
                    fixed(char *startAddr = &str[0])
                    {
                        NativeTextWin32.TextOutUnsafe(tempDc,
                                                      (int)logicalTextBox.X + canvasOriginX,
                                                      (int)logicalTextBox.Y + canvasOriginY,
                                                      (startAddr + startAt), len);
                    }
                }
                MyWin32.SelectClipRgn(tempDc, IntPtr.Zero);

#if DEBUG
                //NativeTextWin32.dbugDrawTextOrigin(tempDc,
                //        logicalTextBox.X + canvasOriginX,
                //        logicalTextBox.Y + canvasOriginY);
#endif
            }
            else
            {
                //translucent / transparent text
                InitHdc();

                var intersectRect = Rectangle.Intersect(logicalTextBox,
                                                        new Rectangle(currentClipRect.Left,
                                                                      currentClipRect.Top,
                                                                      currentClipRect.Width,
                                                                      currentClipRect.Height));
                intersectRect.Offset(canvasOriginX, canvasOriginY);
                MyWin32.SetRectRgn(hRgn,
                                   intersectRect.Left,
                                   intersectRect.Top,
                                   intersectRect.Right,
                                   intersectRect.Bottom);
                MyWin32.SelectClipRgn(tempDc, hRgn);


                unsafe
                {
                    fixed(char *startAddr = &str[0])
                    {
                        NativeTextWin32.TextOutUnsafe(tempDc,
                                                      logicalTextBox.X + canvasOriginX,
                                                      logicalTextBox.Y + canvasOriginY,
                                                      (startAddr + startAt), len);
                    }
                }
#if DEBUG
                //NativeTextWin32.dbugDrawTextOrigin(tempDc,
                //    logicalTextBox.X + canvasOriginX,
                //    logicalTextBox.Y + canvasOriginY);
#endif
            }
        }
Exemple #15
0
        public override void DrawText(char[] str, int startAt, int len, Rectangle logicalTextBox, int textAlignment)
        {
            //this is the most common used function for text drawing
            //return;
#if DEBUG
            dbugDrawStringCount++;
#endif
            var color = this.CurrentTextColor;
            if (color.A == 255)
            {
                //1. find clip rect
                var clipRect = Rectangle.Intersect(logicalTextBox,
                                                   new Rectangle(currentClipRect.Left,
                                                                 currentClipRect.Top,
                                                                 currentClipRect.Width,
                                                                 currentClipRect.Height));
                //2. offset to canvas origin
                clipRect.Offset(canvasOriginX, canvasOriginY);
                //3. set rect rgn
                win32MemDc.SetClipRect(clipRect);

                unsafe
                {
                    fixed(char *startAddr = &str[0])
                    {
                        //4.
                        NativeTextWin32.TextOutUnsafe(originalHdc,
                                                      (int)logicalTextBox.X + canvasOriginX,
                                                      (int)logicalTextBox.Y + canvasOriginY,
                                                      (startAddr + startAt), len);
                    }
                }
                //5. clear rect rgn
                win32MemDc.ClearClipRect();
#if DEBUG
                //NativeTextWin32.dbugDrawTextOrigin(tempDc,
                //        logicalTextBox.X + canvasOriginX,
                //        logicalTextBox.Y + canvasOriginY);
#endif
            }
            else
            {
                //-------------------------------------------
                //not support translucent text in this version,
                //so=> draw opaque (like above)
                //-------------------------------------------
                //1. find clip rect
                var clipRect = Rectangle.Intersect(logicalTextBox,
                                                   new Rectangle(currentClipRect.Left,
                                                                 currentClipRect.Top,
                                                                 currentClipRect.Width,
                                                                 currentClipRect.Height));
                //2. offset to canvas origin
                clipRect.Offset(canvasOriginX, canvasOriginY);
                //3. set rect rgn
                win32MemDc.SetClipRect(clipRect);

                unsafe
                {
                    fixed(char *startAddr = &str[0])
                    {
                        //4.
                        NativeTextWin32.TextOutUnsafe(originalHdc,
                                                      (int)logicalTextBox.X + canvasOriginX,
                                                      (int)logicalTextBox.Y + canvasOriginY,
                                                      (startAddr + startAt), len);
                    }
                }
                //5. clear rect rgn
                win32MemDc.ClearClipRect();
#if DEBUG
                //NativeTextWin32.dbugDrawTextOrigin(tempDc,
                //        logicalTextBox.X + canvasOriginX,
                //        logicalTextBox.Y + canvasOriginY);
#endif
            }
        }