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)); //} }
//====================================== 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); //} }
/// <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); //} }
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(); }
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; } } }
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); }
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); }
//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(); }
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)); }
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); }
//============================================== 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(); }
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 } }
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 } }