/// <summary> /// Get font data for embedding /// </summary> /// <param name="pIncFont"></param> /// <returns></returns> public static byte[] GetFontData(Font pIncFont) { using (MyDeviceContext dc = new MyDeviceContext()) { Font newFont = new Font(pIncFont.FontFamily, pIncFont.FontFamily.GetEmHeight(pIncFont.Style), pIncFont.Style, GraphicsUnit.Pixel); dc.SelectedFont = newFont; uint cbSize = GetFontData(dc.GetHdc(), 0, 0, IntPtr.Zero, 0); if (cbSize == 0) { throw new Win32Exception(); } IntPtr buffer = Marshal.AllocHGlobal((int)cbSize); cbSize = GetFontData(dc.GetHdc(), 0, 0, buffer, cbSize); byte[] resultingBuffer = new byte[cbSize]; Marshal.Copy(buffer, resultingBuffer, 0, (int)cbSize); return(resultingBuffer); } }
// Parse a glyph outline in native format public int GetGlyphWidth(Font pIncFont, int charIndex) { GLYPHMETRICS metrics = new GLYPHMETRICS(); MAT2 matrix = new MAT2(); matrix.eM11.value = 1; matrix.eM12.value = 0; matrix.eM21.value = 0; matrix.eM22.value = 1; using (MyDeviceContext dc = new MyDeviceContext()) { Font newFont = new Font(pIncFont.FontFamily, pIncFont.FontFamily.GetEmHeight(pIncFont.Style), pIncFont.Style, GraphicsUnit.Pixel); dc.SelectedFont = newFont; if (GetGlyphOutline(dc.GetHdc(), (uint)charIndex, (uint)GGO_GLYPH_METRICS, out metrics, 0, IntPtr.Zero, ref matrix) != GDI_ERROR) { return((int)((float)metrics.gmCellIncX * 1000.0f / (float)pIncFont.FontFamily.GetEmHeight(pIncFont.Style))); //return metrics.gmBlackBoxX; } } return(0); }
/// <summary> /// Get Font Metrics /// </summary> /// <param name="pIncFont"></param> public FontMetrics(Font pIncFont) { using (MyDeviceContext dc = new MyDeviceContext()) { Font newFont = new Font(pIncFont.FontFamily, pIncFont.FontFamily.GetEmHeight(pIncFont.Style), pIncFont.Style, GraphicsUnit.Pixel); dc.SelectedFont = newFont; uint cbSize = GetOutlineTextMetrics(dc.GetHdc(), 0, IntPtr.Zero); if (cbSize == 0) { throw new Win32Exception(); } IntPtr buffer = Marshal.AllocHGlobal((int)cbSize); try { if (GetOutlineTextMetrics(dc.GetHdc(), cbSize, buffer) != 0) { OUTLINETEXTMETRIC otm; otm = (OUTLINETEXTMETRIC)Marshal.PtrToStructure(buffer, typeof(OUTLINETEXTMETRIC)); this.italicAngle = otm.otmItalicAngle; IntPtr newPtr; try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpFullName); fullName = Marshal.PtrToStringAuto(newPtr); } catch { } try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpFaceName); faceName = Marshal.PtrToStringAuto(newPtr); } catch { } try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpFamilyName); familyName = Marshal.PtrToStringAuto(newPtr); } catch { } try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpStyleName); styleName = Marshal.PtrToStringAuto(newPtr); } catch { } this.capHeight = (int)otm.otmsCapEmHeight; this.fontBBox = otm.otmrcFontBox; this.stemV = otm.otmTextMetrics.tmMaxCharWidth; this.firstChar = otm.otmTextMetrics.tmFirstChar; this.lastChar = otm.otmTextMetrics.tmLastChar; if (this.LastChar == 0) { this.LastChar = 255; } /// load embedding license /// If bit 1 of otmfsType is set, embedding is not permitted for the font. /// If bit 1 is clear, the font can be embedded. /// If bit 2 is set, the embedding is read-only. if ((otm.otmfsType & 0x01) == 0x01) { embeddingLicense = EmbeddingLicense.NotAllowed; } else { embeddingLicense = EmbeddingLicense.Allowed; } if ((otm.otmfsType & 0x02) == 0x02) { embeddingLicense = EmbeddingLicense.AllowedReadOnly; } // make flag // taken from http://msdn.microsoft.com/en-us/library/dd162774(VS.85).aspx if (otm.otmPanoseNumber.bProportion == 0x04) { flags |= 1; } if (otm.otmPanoseNumber.bFamilyType == 0x03) { flags |= 8; } if (otm.otmPanoseNumber.bFamilyType == 0x02) { flags |= 32; // nonsymbolic font } else { flags |= 4; // symbolic font } if (!(otm.otmPanoseNumber.bSerifStyle == 0x0b || otm.otmPanoseNumber.bSerifStyle == 0x0c || otm.otmPanoseNumber.bSerifStyle == 0x0d)) { flags |= 2; } } } finally { Marshal.FreeHGlobal(buffer); } } }
/// <summary> /// Get Font Metrics /// </summary> /// <param name="pIncFont"></param> public FontMetrics(Font pIncFont) { using (MyDeviceContext dc = new MyDeviceContext()) { Font newFont = new Font(pIncFont.FontFamily, pIncFont.FontFamily.GetEmHeight(pIncFont.Style), pIncFont.Style, GraphicsUnit.Pixel); dc.SelectedFont = newFont; uint cbSize = GetOutlineTextMetrics(dc.GetHdc(), 0, IntPtr.Zero); if (cbSize == 0) throw new Win32Exception(); IntPtr buffer = Marshal.AllocHGlobal((int)cbSize); try { if (GetOutlineTextMetrics(dc.GetHdc(), cbSize, buffer) != 0) { OUTLINETEXTMETRIC otm; otm = (OUTLINETEXTMETRIC)Marshal.PtrToStructure(buffer, typeof(OUTLINETEXTMETRIC)); this.italicAngle = otm.otmItalicAngle; IntPtr newPtr; try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpFullName); fullName = Marshal.PtrToStringAuto(newPtr); } catch { } try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpFaceName); faceName = Marshal.PtrToStringAuto(newPtr); } catch { } try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpFamilyName); familyName = Marshal.PtrToStringAuto(newPtr); } catch { } try { newPtr = new IntPtr(buffer.ToInt32() + otm.otmpStyleName); styleName = Marshal.PtrToStringAuto(newPtr); } catch { } this.capHeight = (int)otm.otmsCapEmHeight; this.fontBBox = otm.otmrcFontBox; this.stemV = otm.otmTextMetrics.tmMaxCharWidth; this.firstChar = otm.otmTextMetrics.tmFirstChar; this.lastChar = otm.otmTextMetrics.tmLastChar; if (this.LastChar == 0) { this.LastChar = 255; } /// load embedding license /// If bit 1 of otmfsType is set, embedding is not permitted for the font. /// If bit 1 is clear, the font can be embedded. /// If bit 2 is set, the embedding is read-only. if ((otm.otmfsType & 0x01) == 0x01) { embeddingLicense = EmbeddingLicense.NotAllowed; } else { embeddingLicense = EmbeddingLicense.Allowed; } if ((otm.otmfsType & 0x02) == 0x02) { embeddingLicense = EmbeddingLicense.AllowedReadOnly; } // make flag // taken from http://msdn.microsoft.com/en-us/library/dd162774(VS.85).aspx if (otm.otmPanoseNumber.bProportion == 0x04) { flags |= 1; } if (otm.otmPanoseNumber.bFamilyType == 0x03) { flags |= 8; } if (otm.otmPanoseNumber.bFamilyType == 0x02) { flags |= 32; // nonsymbolic font } else { flags |= 4; // symbolic font } if (!(otm.otmPanoseNumber.bSerifStyle == 0x0b || otm.otmPanoseNumber.bSerifStyle == 0x0c || otm.otmPanoseNumber.bSerifStyle == 0x0d)) { flags |= 2; } } } finally { Marshal.FreeHGlobal(buffer); } } }
// Parse a glyph outline in native format public int GetGlyphWidth(Font pIncFont, int charIndex) { GLYPHMETRICS metrics = new GLYPHMETRICS(); MAT2 matrix = new MAT2(); matrix.eM11.value = 1; matrix.eM12.value = 0; matrix.eM21.value = 0; matrix.eM22.value = 1; using (MyDeviceContext dc = new MyDeviceContext()) { Font newFont = new Font(pIncFont.FontFamily, pIncFont.FontFamily.GetEmHeight(pIncFont.Style), pIncFont.Style, GraphicsUnit.Pixel); dc.SelectedFont = newFont; if (GetGlyphOutline(dc.GetHdc(), (uint)charIndex, (uint)GGO_GLYPH_METRICS, out metrics, 0, IntPtr.Zero, ref matrix) != GDI_ERROR) { return (int)((float)metrics.gmCellIncX * 1000.0f / (float)pIncFont.FontFamily.GetEmHeight(pIncFont.Style)); //return metrics.gmBlackBoxX; } } return 0; }
/// <summary> /// Get font data for embedding /// </summary> /// <param name="pIncFont"></param> /// <returns></returns> public static byte[] GetFontData(Font pIncFont) { using (MyDeviceContext dc = new MyDeviceContext()) { Font newFont = new Font(pIncFont.FontFamily, pIncFont.FontFamily.GetEmHeight(pIncFont.Style), pIncFont.Style, GraphicsUnit.Pixel); dc.SelectedFont = newFont; uint cbSize = GetFontData(dc.GetHdc(), 0, 0, IntPtr.Zero, 0); if (cbSize == 0) throw new Win32Exception(); IntPtr buffer = Marshal.AllocHGlobal((int)cbSize); cbSize = GetFontData(dc.GetHdc(), 0, 0, buffer, cbSize); byte[] resultingBuffer = new byte[cbSize]; Marshal.Copy(buffer, resultingBuffer, 0, (int)cbSize); return resultingBuffer; } }