public static IComObject <T> CreateTextLayout <T>(this IDWriteFactory factory, IDWriteTextFormat format, string text, int textLength = 0, float maxWidth = float.MaxValue, float maxHeight = float.MaxValue ) where T : IDWriteTextLayout { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } if (format == null) { throw new ArgumentNullException(nameof(format)); } if (text == null) { throw new ArgumentNullException(nameof(text)); } textLength = textLength <= 0 ? text.Length : textLength; factory.CreateTextLayout(text, (uint)textLength, format, maxWidth, maxHeight, out var layout).ThrowOnError(); return(new ComObject <T>((T)layout)); }
public LineBreakpoints AnalyzeLineBreakpoints(IntPtr[] text_ptrs, uint[] lengths, CultureInfo culture, Factory factory, uint range_start, uint range_length, bool isRightToLeft, CultureInfo numberCulture, bool ignoreUserOverride, uint numberSubstitutionMethod) { IDWriteTextAnalyzer pTextAnalyzer = null; TextAnalyzerSink textAnalyzerSink = null; TextAnalyzerSource textAnalyzerSource = null; IDWriteFactory pDWriteFactory = factory.DWriteFactory; pTextAnalyzer = pDWriteFactory.CreateTextAnalyzer(); string numberSubstitutionLocaleName = numberCulture != null ? numberCulture.IetfLanguageTag : null; textAnalyzerSource = new TextAnalyzerSource( text_ptrs, lengths, culture.IetfLanguageTag, pDWriteFactory, isRightToLeft, numberSubstitutionLocaleName, ignoreUserOverride, numberSubstitutionMethod); textAnalyzerSink = new TextAnalyzerSink(); textAnalyzerSink.InitializeLineBreakpoints((int)range_start, (int)(range_start + range_length)); pTextAnalyzer.AnalyzeLineBreakpoints(textAnalyzerSource, range_start, range_length, textAnalyzerSink); return(textAnalyzerSink.LineBreakpoints); }
public FontFileEnumerator(IEnumerable <IFontSource> fontSourceCollection, IntPtr fontFileLoader, IDWriteFactory factory) { _fontSourceCollectionEnumerator = fontSourceCollection.GetEnumerator(); _fontFileLoader = fontFileLoader; _factory = factory; }
internal TextAnalyzerSource(char *text, uint length, string culture, IDWriteFactory factory, bool isRightToLeft, string numberCulture, bool ignoreUserOverride, uint numberSubstitutionMethod) { pText = text; TextLength = length; NumberSubstitution = factory.CreateNumberSubstitution(numberSubstitutionMethod, numberCulture, ignoreUserOverride); PinnedLocaleName = GCHandle.Alloc(culture, GCHandleType.Pinned); ReadingDirection = isRightToLeft ? DWriteReadingDirection.RightToLeft : DWriteReadingDirection.LeftToRight; }
public static IComObject <IDWriteTypography> CreateTypography(this IDWriteFactory factory) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } factory.CreateTypography(out var typography).ThrowOnError(); return(new ComObject <IDWriteTypography>(typography)); }
void Initialize(FactoryType factoryType) { Guid IID_IDWriteFactory = typeof(IDWriteFactory).GUID; IDWriteFactory factoryTemp; int hr = DWriteCreateFactory( factoryType, IID_IDWriteFactory, out factoryTemp); Marshal.ThrowExceptionForHR(hr); _pFactory = factoryTemp; }
public static IComObject <IDWriteInlineObject> CreateEllipsisTrimmingSign(this IDWriteFactory factory, IDWriteTextFormat format) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } if (format == null) { throw new ArgumentNullException(nameof(format)); } factory.CreateEllipsisTrimmingSign(format, out var sign).ThrowOnError(); return(new ComObject <IDWriteInlineObject>(sign)); }
internal TextAnalyzerSource(char *text, uint length, string culture, IDWriteFactory factory, bool isRightToLeft, string numberCulture, bool ignoreUserOverride, uint numberSubstitutionMethod) { var segment = new TextSegment(); segment.ptr = new IntPtr(text); segment.start = 0; segment.end = length; TextSegments = new TextSegment[] { segment }; TextLength = length; NumberSubstitution = factory.CreateNumberSubstitution(numberSubstitutionMethod, numberCulture, ignoreUserOverride); PinnedLocaleName = GCHandle.Alloc(culture, GCHandleType.Pinned); ReadingDirection = isRightToLeft ? DWriteReadingDirection.RightToLeft : DWriteReadingDirection.LeftToRight; }
HRESULT IDWriteFontCollectionLoader.CreateEnumeratorFromKey(IDWriteFactory factory, IntPtr collectionKey, uint collectionKeySize, out IDWriteFontFileEnumerator fontFileEnumerator) { var func = EnumerableFunc; if (func == null) { fontFileEnumerator = null; ComError.SetError(nameof(EnumerableFunc) + " was not set."); return(HRESULTS.DISP_E_EXCEPTION); } byte[] key; if (collectionKey == IntPtr.Zero || collectionKeySize == 0) { key = null; } else { key = new byte[collectionKeySize]; Marshal.Copy(collectionKey, key, 0, (int)collectionKeySize); } var enumerable = func(factory, key); if (enumerable == null) { fontFileEnumerator = null; ComError.SetError(nameof(EnumerableFunc) + " returned nothing."); return(HRESULTS.DISP_E_EXCEPTION); } var enumerator = enumerable.GetEnumerator(); if (enumerator == null) { fontFileEnumerator = null; ComError.SetError(nameof(EnumerableFunc) + " returned a null enumerator."); return(HRESULTS.DISP_E_EXCEPTION); } fontFileEnumerator = new FontFileEnumerator(factory, _loader, enumerator); return(HRESULTS.S_OK); }
internal TextAnalyzerSource(IntPtr[] text_ptrs, uint[] lengths, string culture, IDWriteFactory factory, bool isRightToLeft, string numberCulture, bool ignoreUserOverride, uint numberSubstitutionMethod) { TextSegments = new TextSegment[text_ptrs.Length]; uint pos = 0; for (int i = 0; i < text_ptrs.Length; i++) { var segment = new TextSegment(); segment.ptr = text_ptrs[i]; segment.start = pos; pos += lengths[i]; segment.end = pos; TextSegments[i] = segment; } TextLength = pos; NumberSubstitution = factory.CreateNumberSubstitution(numberSubstitutionMethod, numberCulture, ignoreUserOverride); PinnedLocaleName = GCHandle.Alloc(culture, GCHandleType.Pinned); ReadingDirection = isRightToLeft ? DWriteReadingDirection.RightToLeft : DWriteReadingDirection.LeftToRight; }
private DWriteFactory(IDWriteFactory obj) { this.comObject = obj; bool result; result = ComHelper.GetMethod(this.comObject, 15, out this.createTextFormat); if(!result) { Debug.WriteLine("Fail to get COM method at index {0}", 15); } result = ComHelper.GetMethod(this.comObject, 18, out this.createTextLayout); if (!result) { Debug.WriteLine("Fail to get COM method at index {0}", 18); } }
public static IComObject <T> CreateTextFormat <T>(this IDWriteFactory factory, string familyName, float size, IDWriteFontCollection fonts = null, DWRITE_FONT_WEIGHT weight = DWRITE_FONT_WEIGHT.DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE style = DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH.DWRITE_FONT_STRETCH_NORMAL, string localeName = null) where T : IDWriteTextFormat { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } if (familyName == null) { throw new ArgumentNullException(nameof(familyName)); } localeName = localeName ?? string.Empty; factory.CreateTextFormat(familyName, fonts, weight, style, stretch, size, localeName, out var format).ThrowOnError(); return(new ComObject <T>((T)format)); }
public int CreateEnumeratorFromKey(IDWriteFactory factory, IntPtr collectionKey, uint collectionKeySize, out IDWriteFontFileEnumeratorMirror fontFileEnumerator) { uint numberOfCharacters = collectionKeySize / 2; fontFileEnumerator = null; if ((collectionKeySize % 2 != 0) || // The collectionKeySize must be divisible by sizeof(WCHAR) (numberOfCharacters <= 1) || // The collectionKey cannot be less than or equal 1 character as it has to contain the NULL character. (Marshal.ReadInt16(collectionKey, ((int)numberOfCharacters - 1) * 2) != '\0')) // The collectionKey must end with the NULL character { return(unchecked ((int)0x80070057)); // E_INVALIDARG } fontFileEnumerator = null; string uriString = Marshal.PtrToStringUni(collectionKey); int hr = 0; try { IFontSourceCollection fontSourceCollection = _fontSourceCollectionFactory.Create(uriString); FontFileEnumerator fontFileEnum = new FontFileEnumerator( fontSourceCollection, _fontFileLoader, factory ); fontFileEnumerator = (IDWriteFontFileEnumeratorMirror)fontFileEnum; } catch (Exception exception) { hr = Marshal.GetHRForException(exception); } return(hr); }
extern static int DWriteCreateFactory( FactoryType factoryType, [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid, [Out, MarshalAs(UnmanagedType.Interface)] out IDWriteFactory factory);
internal DWriteFactory(IDWriteFactory handle) { this.handle = handle; }
private void Release() { if (this.comObject != null) { Marshal.ReleaseComObject(this.comObject); this.comObject = null; this.createTextFormat = null; this.createTextLayout = null; } }
unsafe static public IList <Span> Itemize( char *text, uint length, CultureInfo culture, Factory factory, bool isRightToLeftParagraph, CultureInfo numberCulture, bool ignoreUserOverride, uint numberSubstitutionMethod, IClassification classificationUtility ) { // If a text has zero length then we do not need to itemize. if (length > 0) { IDWriteTextAnalyzer pTextAnalyzer = null; TextAnalyzerSink textAnalyzerSink = null; TextAnalyzerSource textAnalyzerSource = null; IDWriteFactory pDWriteFactory = factory.DWriteFactory; pTextAnalyzer = pDWriteFactory.CreateTextAnalyzer(); string numberSubstitutionLocaleName = numberCulture != null ? numberCulture.IetfLanguageTag : null; // NOTE: the text parameter is NOT copied inside TextAnalysisSource to improve perf. // This is ok as long as we use the TextAnalysisSource in the same scope as we hold ref to text. // If we are ever to change this pattern then this should be revisited in TextAnalysisSource in // PresentationNative. textAnalyzerSource = new TextAnalyzerSource( text, length, culture.IetfLanguageTag, pDWriteFactory, isRightToLeftParagraph, numberSubstitutionLocaleName, ignoreUserOverride, numberSubstitutionMethod); textAnalyzerSink = new TextAnalyzerSink(); // Analyze the script ranges. pTextAnalyzer.AnalyzeScript(textAnalyzerSource, 0, length, textAnalyzerSink); // Analyze the number substitution ranges. pTextAnalyzer.AnalyzeNumberSubstitution(textAnalyzerSource, 0, length, textAnalyzerSink); var dwriteScriptAnalysisList = textAnalyzerSink.ScriptAnalysis; var dwriteNumberSubstitutionList = textAnalyzerSink.NumberSubstitution; TextItemizer textItemizer = new TextItemizer(dwriteScriptAnalysisList, dwriteNumberSubstitutionList); return(AnalyzeExtendedAndItemize(textItemizer, new IntPtr(text), length, numberCulture, classificationUtility)); } else { return(null); } }
unsafe internal static IDWriteFontFile CreateFontFile( IDWriteFactory factory, IntPtr fontFileLoader, // IDWriteFontFileLoader* Uri filePathUri ) { IDWriteFontFile dwriteFontFile; bool isLocal = Factory.IsLocalUri(filePathUri); if (isLocal) { // DWrite currently has a slow lookup for the last write time, which // introduced a noticable perf regression when we switched over. // To mitigate this scenario, we will fetch the timestamp ourselves // and cache it for future calls. // // Note: we only do this if a Dispatcher exists for the current // thread. There is a seperate cache for each thread. FILETIME cachedTimeStamp; IntPtr pTimeStamp = IntPtr.Zero; // If something fails, do nothing and let DWrite sort it out. Dispatcher currentDispatcher = Dispatcher.FromThread(Thread.CurrentThread); if (currentDispatcher != null) { try { // One-time initialization per thread. if (_timeStampCache == null) { _timeStampCache = new Dictionary <Uri, FILETIME>(); } if (!_timeStampCache.TryGetValue(filePathUri, out cachedTimeStamp)) { long longFileTime = File.GetLastWriteTime(filePathUri.LocalPath).ToFileTime(); cachedTimeStamp.dwLowDateTime = (int)(longFileTime); cachedTimeStamp.dwHighDateTime = (int)(longFileTime >> 32); _timeStampCache.Add(filePathUri, cachedTimeStamp); // We don't want to hold this cached value for a long time since // all font references will be tied to this timestamp, and any font // update during the lifetime of the application will cause is to // encounter errors. So we use a dispatcher operation to clear // the cache as soon as we get back to pumping messages. if (_timeStampCacheCleanupOp == null) { _timeStampCacheCleanupOp = currentDispatcher.BeginInvoke(new Action(CleanupTimeStampCache)); } } pTimeStamp = Marshal.AllocCoTaskMem(Marshal.SizeOf <FILETIME>()); Marshal.StructureToPtr <FILETIME>(cachedTimeStamp, pTimeStamp, false); } catch { } } try { dwriteFontFile = factory.CreateFontFileReference( filePathUri.LocalPath, pTimeStamp ); } finally { Marshal.FreeCoTaskMem(pTimeStamp); } } else { string filePath = filePathUri.AbsoluteUri; fixed(char *pFilePath = filePath) { dwriteFontFile = factory.CreateCustomFontFileReference( new IntPtr(pFilePath), (uint)(filePath.Length + 1) * 2, fontFileLoader ); } } return(dwriteFontFile); }
public FontFileEnumerator(IDWriteFactory factory, FontFileLoader loader, IEnumerator <DWriteFontFile> enumerator) { _factory = factory; _loader = loader; _enumerator = enumerator; }
private static extern IntPtr RegisterLoaders( [MarshalAs(UnmanagedType.Interface)] IDWriteFactory dwritefactory, CreateEnumeratorFromKeyFn enum_fn, CreateStreamFromKeyFn stream_fn, IntPtr managedFactoryHandle);
public static extern void DWriteCreateFactory( [In] DWriteFactoryType factoryType, [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid, [Out] out IDWriteFactory factory);