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));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
 public FontFileEnumerator(IEnumerable <IFontSource> fontSourceCollection,
                           IntPtr fontFileLoader,
                           IDWriteFactory factory)
 {
     _fontSourceCollectionEnumerator = fontSourceCollection.GetEnumerator();
     _fontFileLoader = fontFileLoader;
     _factory        = factory;
 }
Esempio n. 4
0
 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));
        }
Esempio n. 6
0
        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));
        }
Esempio n. 8
0
        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);
        }
Esempio n. 10
0
        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;
        }
Esempio n. 11
0
        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);
            }

        }
Esempio n. 12
0
        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));
        }
Esempio n. 13
0
        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);
        }
Esempio n. 14
0
 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;
 }
Esempio n. 16
0
 private void Release()
 {
     if (this.comObject != null)
     {
         Marshal.ReleaseComObject(this.comObject);
         this.comObject = null;
         this.createTextFormat = null;
         this.createTextLayout = null;
     }
 }
Esempio n. 17
0
 internal DWriteFactory(IDWriteFactory handle)
 {
     this.handle = handle;
 }
Esempio n. 18
0
        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);
            }
        }
Esempio n. 19
0
        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);
        }
Esempio n. 20
0
 public FontFileEnumerator(IDWriteFactory factory, FontFileLoader loader, IEnumerator <DWriteFontFile> enumerator)
 {
     _factory    = factory;
     _loader     = loader;
     _enumerator = enumerator;
 }
Esempio n. 21
0
 private static extern IntPtr RegisterLoaders(
     [MarshalAs(UnmanagedType.Interface)] IDWriteFactory dwritefactory,
     CreateEnumeratorFromKeyFn enum_fn,
     CreateStreamFromKeyFn stream_fn,
     IntPtr managedFactoryHandle);
Esempio n. 22
0
 public static extern void DWriteCreateFactory(
     [In] DWriteFactoryType factoryType,
     [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid,
     [Out] out IDWriteFactory factory);