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