/// <summary> /// Convert source objects into a source string /// </summary> /// <param name="fontSource"></param> /// <param name="commonSettings"></param> /// <returns></returns> public static string ConvertToSourceString(IFontSource fontSource, IEPubCommonSettings commonSettings) { var builder = new StringBuilder(); switch (fontSource.Type) { case SourceTypes.External: builder.AppendFormat(@" url({0}) ", fontSource.Location); break; case SourceTypes.Local: builder.AppendFormat(" local(\"{0}\") ", fontSource.Location); break; case SourceTypes.Embedded: if (!commonSettings.EmbedStyles) { builder.AppendFormat(commonSettings.FlatStructure? @" url({0}) " : @" url(../fonts/{0}) ", Path.GetFileName(fontSource.Location.ToLower())); } else { builder.AppendFormat(commonSettings.FlatStructure ? @" url(../{0}) " : @" url(fonts/{0}) ", Path.GetFileName(fontSource.Location.ToLower())); } break; default: Logger.Log.ErrorFormat("Unknown font source type : {0}", fontSource.Type); break; } return(builder.ToString()); }
/// <summary> /// Convert source objects into a source string /// </summary> /// <param name="fontSource"></param> /// <param name="commonSettings"></param> /// <returns></returns> public static string ConvertToSourceString(IFontSource fontSource, IEPubCommonSettings commonSettings) { var builder = new StringBuilder(); switch (fontSource.Type) { case SourceTypes.External: builder.AppendFormat(@" url({0}) ", fontSource.Location); break; case SourceTypes.Local: builder.AppendFormat(" local(\"{0}\") ", fontSource.Location); break; case SourceTypes.Embedded: if (!commonSettings.EmbedStyles) { builder.AppendFormat(commonSettings.FlatStructure? @" url({0}) " : @" url(../fonts/{0}) ", Path.GetFileName(fontSource.Location.ToLower())); } else { builder.AppendFormat(commonSettings.FlatStructure ? @" url(../{0}) " : @" url(fonts/{0}) ", Path.GetFileName(fontSource.Location.ToLower())); } break; default: Logger.Log.ErrorFormat("Unknown font source type : {0}", fontSource.Type); break; } return builder.ToString(); }
public int CreateStreamFromKey(IntPtr fontFileReferenceKey, uint fontFileReferenceKeySize, out IDWriteFontFileStreamMirror fontFileStream) { uint numberOfCharacters = fontFileReferenceKeySize / 2; fontFileStream = null; if ((fontFileReferenceKeySize % 2 != 0) || // The fontFileReferenceKeySize must be divisible by sizeof(WCHAR) (numberOfCharacters <= 1) || // The fontFileReferenceKey cannot be less than or equal 1 character as it has to contain the NULL character. (Marshal.ReadInt16(fontFileReferenceKey, ((int)numberOfCharacters - 1) * 2) != '\0')) // The fontFileReferenceKey must end with the NULL character { return(unchecked ((int)0x80070057)); // E_INVALIDARG } string uriString = Marshal.PtrToStringUni(fontFileReferenceKey); int hr = 0; try { IFontSource fontSource = _fontSourceFactory.Create(uriString); FontFileStream customFontFileStream = new FontFileStream(fontSource); fontFileStream = (IDWriteFontFileStreamMirror)customFontFileStream; } catch (System.Exception exception) { hr = Marshal.GetHRForException(exception); } return(hr); }
public void CopyFrom(IFontSource fontSource) { if (fontSource == null) { throw new ArgumentNullException("fontSource"); } if (fontSource == this) { return; } Type = fontSource.Type; Location = fontSource.Location; Format = fontSource.Format; }
internal int?GetCodepointIndex(int codepoint, out IFontSource font) { font = null; var g = default(int?); foreach (var f in _fontSources) { g = f.GetGlyphId(codepoint); if (g != null) { font = f; break; } } return(g); }
private static string GetFontName(IFontSource fontSource) { switch (fontSource.Type) { case SourceTypes.Local: return(fontSource.Location); case SourceTypes.External: case SourceTypes.Embedded: string shortName = Path.GetFileNameWithoutExtension(fontSource.Location); if (!string.IsNullOrEmpty(shortName)) { return(shortName); } return(fontSource.Location); } return(string.Empty); }
public FontFile CreateFontFile(Uri filePathUri) { IDWriteFontFile dwriteFontFile = null; try { dwriteFontFile = CreateFontFile(_pFactory, WpfFontFileLoader, filePathUri); } catch { // If DWrite's CreateFontFileReference fails then try opening the file using WPF's logic. // The failures that WPF returns are more granular than the HRESULTs that DWrite returns // thus we use WPF's logic to open the file to throw the same exceptions that // WPF would have thrown before. IFontSource fontSource = _fontSourceFactory.Create(filePathUri.AbsoluteUri); fontSource.TestFileOpenable(); throw; } return(new FontFile(dwriteFontFile)); }
public FontFileStream(IFontSource fontSource) { // Previously we were using fontSource->GetStream() which caused crashes in the XPS scenarios // as the stream was getting closed by some other object. In XPS scenarios GetStream() would return // MS::Internal::IO:Packaging::SynchronizingStream which is owned by the XPS docs and // is known to have issues regarding the lifetime management where by if the current XPS page is // flipped then the stream will get disposed. Thus, we cannot rely on the stream directly and hence we now use // fontSource->GetUnmanagedStream() which returns a copy of the content of the stream. Special casing XPS will not // guarantee that this problem will be fixed so we will use the GetUnmanagedStream(). Note: This path will only // be taken for embedded fonts among which XPS is a main scenario. For local fonts we use DWrite's APIs. _fontSourceStream = fontSource.GetUnmanagedStream(); try { _lastWriteTime = fontSource.GetLastWriteTimeUtc().ToFileTimeUtc(); } catch (ArgumentOutOfRangeException) //The resulting file time would represent a date and time before 12:00 midnight January 1, 1601 C.E. UTC. { _lastWriteTime = -1; } // Create lock to control access to font source stream. _fontSourceStreamLock = new Object(); }
unsafe public FontFace CreateFontFace(Uri filePathUri, uint faceIndex, FontSimulations fontSimulationFlags) { FontFile fontFile = CreateFontFile(filePathUri); FontFileType dwriteFontFileType; FontFaceType dwriteFontFaceType; uint numberOfFaces = 0; int hr; if (fontFile.Analyze( out dwriteFontFileType, out dwriteFontFaceType, out numberOfFaces, out hr )) { if (faceIndex >= numberOfFaces) { throw new ArgumentOutOfRangeException("faceIndex"); } IntPtr dwriteFontFace = IntPtr.Zero; // IDWriteFontFace IntPtr dwriteFontFile = fontFile.DWriteFontFileIface; try { dwriteFontFace = _pFactory.CreateFontFace( dwriteFontFaceType, 1, &dwriteFontFile, faceIndex, fontSimulationFlags ); } finally { Marshal.Release(dwriteFontFile); } return(new FontFace(dwriteFontFace)); } // This path is here because there is a behavior mismatch between DWrite and WPF. // If a directory was given instead of a font uri WPF previously throws // System.UnauthorizedAccessException. We handle most of the exception behavior mismatch // in FontFile^ Factory::CreateFontFile by opening the file using WPF's previous (prior to DWrite integration) logic if // CreateFontFileReference fails (please see comments in FontFile^ Factory::CreateFontFile). // However in this special case DWrite's CreateFontFileReference will succeed if given // a directory instead of a font file and it is the Analyze() call will fail returning DWRITE_E_FILEFORMAT. // Thus, incase the hr returned from Analyze() was DWRITE_E_FILEFORMAT we do as we did in FontFile^ Factory::CreateFontFile // to try and open the file using WPF old logic and throw System.UnauthorizedAccessException as WPF used to do. // If a file format exception is expected then opening the file should succeed and ConvertHresultToException() // Should throw the correct exception. // A final note would be that this overhead is only incurred in error conditions and so the normal execution path should // not be affected. else { if (hr == unchecked ((int)0x88985000)) // DWRITE_E_FILEFORMAT { IFontSource fontSource = _fontSourceFactory.Create(filePathUri.AbsoluteUri); fontSource.TestFileOpenable(); } Marshal.ThrowExceptionForHR(hr); } return(null); }
private static string GetFontName(IFontSource fontSource) { switch (fontSource.Type) { case SourceTypes.Local: return fontSource.Location; case SourceTypes.External: case SourceTypes.Embedded: string shortName = Path.GetFileNameWithoutExtension(fontSource.Location); if (!string.IsNullOrEmpty(shortName)) { return shortName; } return fontSource.Location; } return string.Empty; }
public void RenderGlyph(ITexture2DManager textureManager, DynamicFontGlyph glyph, IFontSource fontSource, int blurAmount, int strokeAmount, bool premultiplyAlpha, int kernelWidth, int kernelHeight) #endif { var pad = Math.Max(DynamicFontGlyph.PadFromBlur(blurAmount), DynamicFontGlyph.PadFromBlur(strokeAmount)); // Render glyph to byte buffer var bufferSize = glyph.Bounds.Width * glyph.Bounds.Height; var buffer = _byteBuffer; if ((buffer == null) || (buffer.Length < bufferSize)) { buffer = new byte[bufferSize]; _byteBuffer = buffer; } Array.Clear(buffer, 0, bufferSize); var colorBuffer = _colorBuffer; if ((colorBuffer == null) || (colorBuffer.Length < bufferSize * 4)) { colorBuffer = new byte[bufferSize * 4]; _colorBuffer = colorBuffer; } fontSource.RasterizeGlyphBitmap(glyph.Id, glyph.Size, buffer, pad + pad * glyph.Bounds.Width, glyph.Bounds.Width - pad * 2, glyph.Bounds.Height - pad * 2, glyph.Bounds.Width); if (strokeAmount > 0) { var width = glyph.Bounds.Width; var top = width * strokeAmount; var bottom = (glyph.Bounds.Height - strokeAmount) * glyph.Bounds.Width; var right = glyph.Bounds.Width - strokeAmount; var left = strokeAmount; byte d; for (var i = 0; i < bufferSize; ++i) { var ci = i * 4; var col = buffer[i]; var black = 0; if (col == 255) { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = 255; continue; } if (i >= top) { black = buffer[i - top]; } if (i < bottom) { d = buffer[i + top]; black = ((255 - d) * black + 255 * d) / 255; } if (i % width >= left) { d = buffer[i - strokeAmount]; black = ((255 - d) * black + 255 * d) / 255; } if (i % width < right) { d = buffer[i + strokeAmount]; black = ((255 - d) * black + 255 * d) / 255; } if (black == 0) { if (col == 0) { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = 0; //black transparency to suit stroke continue; } if (premultiplyAlpha) { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = col; } else { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = 255; colorBuffer[ci + 3] = col; } } else { if (col == 0) { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = 0; colorBuffer[ci + 3] = (byte)black; continue; } if (premultiplyAlpha) { var alpha = ((255 - col) * black + 255 * col) / 255; colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = (byte)((alpha * col) / 255); colorBuffer[ci + 3] = (byte)alpha; } else { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = col; colorBuffer[ci + 3] = (byte)(((255 - col) * black + 255 * col) / 255); } } } } else { if (blurAmount > 0) { fixed(byte *bdst = &buffer[0]) { Blur(bdst, glyph.Bounds.Width, glyph.Bounds.Height, glyph.Bounds.Width, blurAmount); } } for (var i = 0; i < bufferSize; ++i) { var ci = i * 4; var c = buffer[i]; if (premultiplyAlpha) { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = colorBuffer[ci + 3] = c; } else { colorBuffer[ci] = colorBuffer[ci + 1] = colorBuffer[ci + 2] = 255; colorBuffer[ci + 3] = c; } } } #if MONOGAME || FNA || STRIDE // Write to texture if (Texture == null) { Texture = Texture2DManager.CreateTexture(graphicsDevice, Width, Height); } Texture2DManager.SetTextureData(Texture, glyph.Bounds, colorBuffer); #else // Write to texture if (Texture == null) { Texture = textureManager.CreateTexture(Width, Height); } textureManager.SetTextureData(Texture, glyph.Bounds, colorBuffer); #endif }
public void RenderGlyph(GraphicsDevice graphicsDevice, DynamicFontGlyph glyph, IFontSource fontSource, int blurAmount, int strokeAmount, bool premultiplyAlpha, int kernelWidth, int kernelHeight)
public FontFileStream(IFontSource fontSource) { }