Example #1
0
        private void ParseGlyphRunProperties() 
        {
            LayoutDependentGlyphRunProperties glyphRunProperties = null; 
            Uri uri = FontUri;

            if (uri != null)
            { 
                // Indices and UnicodeString cannot both be empty.
                if (String.IsNullOrEmpty(UnicodeString) && String.IsNullOrEmpty(Indices)) 
                    throw new ArgumentException(SR.Get(SRID.GlyphsUnicodeStringAndIndicesCannotBothBeEmpty)); 

                glyphRunProperties = new LayoutDependentGlyphRunProperties(); 

                if (!uri.IsAbsoluteUri)
                {
                    uri = BindUriHelper.GetResolvedUri(BaseUriHelper.GetBaseUri(this), uri); 
                }
 
                glyphRunProperties.glyphTypeface = new GlyphTypeface(uri, StyleSimulations); 

                glyphRunProperties.unicodeString = UnicodeString; 
                glyphRunProperties.sideways = IsSideways;
                glyphRunProperties.deviceFontName = DeviceFontName;

                // parse the Indices property 
                List<ParsedGlyphData> parsedGlyphs;
                int glyphCount = ParseGlyphsProperty( 
                    glyphRunProperties.glyphTypeface, 
                    glyphRunProperties.unicodeString,
                    glyphRunProperties.sideways, 
                    out parsedGlyphs,
                    out glyphRunProperties.clusterMap);

                Debug.Assert(parsedGlyphs.Count == glyphCount); 

                glyphRunProperties.glyphIndices = new ushort[glyphCount]; 
                glyphRunProperties.advanceWidths = new double[glyphCount]; 

                ParseCaretStops(glyphRunProperties); 

                // Delay creating glyphOffsets array because in many common cases it will contain only zeroed entries.
                glyphRunProperties.glyphOffsets = null;
 
                int i = 0;
 
                glyphRunProperties.fontRenderingSize = FontRenderingEmSize; 
                glyphRunProperties.bidiLevel = BidiLevel;
 
                double fromEmToMil = glyphRunProperties.fontRenderingSize / EmMultiplier;

                foreach (ParsedGlyphData parsedGlyphData in parsedGlyphs)
                { 
                    glyphRunProperties.glyphIndices[i] = parsedGlyphData.glyphIndex;
 
                    // convert advances and offsets from integers in em space to doubles coordinates in MIL space 
                    glyphRunProperties.advanceWidths[i] = parsedGlyphData.advanceWidth * fromEmToMil;
 
                    if (parsedGlyphData.offsetX != 0 || parsedGlyphData.offsetY != 0)
                    {
                        // Lazily create glyph offset array. Previous entries will be correctly set to zero
                        // by the default Point ctor. 
                        if (glyphRunProperties.glyphOffsets == null)
                            glyphRunProperties.glyphOffsets = new Point[glyphCount]; 
 
                        glyphRunProperties.glyphOffsets[i].X = parsedGlyphData.offsetX * fromEmToMil;
                        glyphRunProperties.glyphOffsets[i].Y = parsedGlyphData.offsetY * fromEmToMil; 
                    }

                    ++i;
                } 
            }
            _glyphRunProperties = glyphRunProperties; 
        } 
Example #2
0
        private void ParseGlyphRunProperties()
        {
            LayoutDependentGlyphRunProperties glyphRunProperties = null;
            Uri uri = FontUri;

            if (uri != null)
            {
                // Indices and UnicodeString cannot both be empty.
                if (String.IsNullOrEmpty(UnicodeString) && String.IsNullOrEmpty(Indices))
                {
                    throw new ArgumentException(SR.Get(SRID.GlyphsUnicodeStringAndIndicesCannotBothBeEmpty));
                }

                glyphRunProperties = new LayoutDependentGlyphRunProperties(GetDpi().PixelsPerDip);

                if (!uri.IsAbsoluteUri)
                {
                    uri = BindUriHelper.GetResolvedUri(BaseUriHelper.GetBaseUri(this), uri);
                }

                glyphRunProperties.glyphTypeface = new GlyphTypeface(uri, StyleSimulations);

                glyphRunProperties.unicodeString  = UnicodeString;
                glyphRunProperties.sideways       = IsSideways;
                glyphRunProperties.deviceFontName = DeviceFontName;

                // parse the Indices property
                List <ParsedGlyphData> parsedGlyphs;
                int glyphCount = ParseGlyphsProperty(
                    glyphRunProperties.glyphTypeface,
                    glyphRunProperties.unicodeString,
                    glyphRunProperties.sideways,
                    out parsedGlyphs,
                    out glyphRunProperties.clusterMap);

                Debug.Assert(parsedGlyphs.Count == glyphCount);

                glyphRunProperties.glyphIndices  = new ushort[glyphCount];
                glyphRunProperties.advanceWidths = new double[glyphCount];

                ParseCaretStops(glyphRunProperties);

                // Delay creating glyphOffsets array because in many common cases it will contain only zeroed entries.
                glyphRunProperties.glyphOffsets = null;

                int i = 0;

                glyphRunProperties.fontRenderingSize = FontRenderingEmSize;
                glyphRunProperties.bidiLevel         = BidiLevel;

                double fromEmToMil = glyphRunProperties.fontRenderingSize / EmMultiplier;

                foreach (ParsedGlyphData parsedGlyphData in parsedGlyphs)
                {
                    glyphRunProperties.glyphIndices[i] = parsedGlyphData.glyphIndex;

                    // convert advances and offsets from integers in em space to doubles coordinates in MIL space
                    glyphRunProperties.advanceWidths[i] = parsedGlyphData.advanceWidth * fromEmToMil;

                    if (parsedGlyphData.offsetX != 0 || parsedGlyphData.offsetY != 0)
                    {
                        // Lazily create glyph offset array. Previous entries will be correctly set to zero
                        // by the default Point ctor.
                        if (glyphRunProperties.glyphOffsets == null)
                        {
                            glyphRunProperties.glyphOffsets = new Point[glyphCount];
                        }

                        glyphRunProperties.glyphOffsets[i].X = parsedGlyphData.offsetX * fromEmToMil;
                        glyphRunProperties.glyphOffsets[i].Y = parsedGlyphData.offsetY * fromEmToMil;
                    }

                    ++i;
                }
            }
            _glyphRunProperties = glyphRunProperties;
        }
Example #3
0
        private void ParseCaretStops(LayoutDependentGlyphRunProperties glyphRunProperties)
        { 
            string caretStopsString = CaretStops; 
            if (String.IsNullOrEmpty(caretStopsString))
            { 
                glyphRunProperties.caretStops = null;
                return;
            }
 
            // Caret stop count should be equal to the number of UTF16 code points in the glyph run plus one.
            // Logic below is similar to GlyphRun.CodepointCount property. 
 
            int caretStopCount;
 
            if (!String.IsNullOrEmpty(glyphRunProperties.unicodeString))
                caretStopCount = glyphRunProperties.unicodeString.Length + 1;
            else
            { 
                if (glyphRunProperties.clusterMap != null && glyphRunProperties.clusterMap.Length != 0)
                    caretStopCount = glyphRunProperties.clusterMap.Length + 1; 
                else 
                {
                    Debug.Assert(glyphRunProperties.glyphIndices != null); 
                    caretStopCount = glyphRunProperties.glyphIndices.Length + 1;
                }
            }
 
            bool[] caretStops = new bool[caretStopCount];
 
            int i = 0; 
            foreach (char c in caretStopsString)
            { 
                if (Char.IsWhiteSpace(c))
                    continue;

                int nibble; 

                if ('0' <= c && c <= '9') 
                    nibble = c - '0'; 
                else if ('a' <= c && c <= 'f')
                    nibble = c - 'a' + 10; 
                else if ('A' <= c && c <= 'F')
                    nibble = c - 'A' + 10;
                else
                    throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsContainsHexDigits), "CaretStops"); 

                Debug.Assert(0 <= nibble && nibble <= 15); 
 
                if ((nibble & 8) != 0)
                { 
                    if (i >= caretStops.Length)
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops");
                    caretStops[i] = true;
                } 
                ++i;
                if ((nibble & 4) != 0) 
                { 
                    if (i >= caretStops.Length)
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops"); 
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 2) != 0) 
                {
                    if (i >= caretStops.Length) 
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops"); 
                    caretStops[i] = true;
                } 
                ++i;
                if ((nibble & 1) != 0)
                {
                    if (i >= caretStops.Length) 
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops");
                    caretStops[i] = true; 
                } 
                ++i;
            } 

            // If the number of entries in the caret stop specification string is less than the number of code points,
            // set the remaining caret stop values to true.
            while (i < caretStops.Length) 
            {
                caretStops[i++] = true; 
            } 
            glyphRunProperties.caretStops = caretStops;
        } 
Example #4
0
        private void ParseCaretStops(LayoutDependentGlyphRunProperties glyphRunProperties)
        {
            string caretStopsString = CaretStops;

            if (String.IsNullOrEmpty(caretStopsString))
            {
                glyphRunProperties.caretStops = null;
                return;
            }

            // Caret stop count should be equal to the number of UTF16 code points in the glyph run plus one.
            // Logic below is similar to GlyphRun.CodepointCount property.

            int caretStopCount;

            if (!String.IsNullOrEmpty(glyphRunProperties.unicodeString))
            {
                caretStopCount = glyphRunProperties.unicodeString.Length + 1;
            }
            else
            {
                if (glyphRunProperties.clusterMap != null && glyphRunProperties.clusterMap.Length != 0)
                {
                    caretStopCount = glyphRunProperties.clusterMap.Length + 1;
                }
                else
                {
                    Debug.Assert(glyphRunProperties.glyphIndices != null);
                    caretStopCount = glyphRunProperties.glyphIndices.Length + 1;
                }
            }

            bool[] caretStops = new bool[caretStopCount];

            int i = 0;

            foreach (char c in caretStopsString)
            {
                if (Char.IsWhiteSpace(c))
                {
                    continue;
                }

                int nibble;

                if ('0' <= c && c <= '9')
                {
                    nibble = c - '0';
                }
                else if ('a' <= c && c <= 'f')
                {
                    nibble = c - 'a' + 10;
                }
                else if ('A' <= c && c <= 'F')
                {
                    nibble = c - 'A' + 10;
                }
                else
                {
                    throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsContainsHexDigits), "CaretStops");
                }

                Debug.Assert(0 <= nibble && nibble <= 15);

                if ((nibble & 8) != 0)
                {
                    if (i >= caretStops.Length)
                    {
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops");
                    }
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 4) != 0)
                {
                    if (i >= caretStops.Length)
                    {
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops");
                    }
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 2) != 0)
                {
                    if (i >= caretStops.Length)
                    {
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops");
                    }
                    caretStops[i] = true;
                }
                ++i;
                if ((nibble & 1) != 0)
                {
                    if (i >= caretStops.Length)
                    {
                        throw new ArgumentException(SR.Get(SRID.GlyphsCaretStopsLengthCorrespondsToUnicodeString), "CaretStops");
                    }
                    caretStops[i] = true;
                }
                ++i;
            }

            // If the number of entries in the caret stop specification string is less than the number of code points,
            // set the remaining caret stop values to true.
            while (i < caretStops.Length)
            {
                caretStops[i++] = true;
            }
            glyphRunProperties.caretStops = caretStops;
        }