Esempio n. 1
0
        // ...on the way to handle Indices...
        private void WriteGlyphsInternal(Glyphs glyphs, string text)
        {
            var complexity = GlyphIndicesComplexity.None;
            var indices    = new GlyphIndices(glyphs.Indices);

            if (glyphs.Indices != null)
            {
                complexity = indices.Complexity;
            }
            complexity = GlyphIndicesComplexity.ClusterMapping;
            switch (complexity)
            {
            case GlyphIndicesComplexity.None:
                break;

            case GlyphIndicesComplexity.DistanceOnly:
                WriteGlyphs_DistanceOnly(glyphs);
                break;

            case GlyphIndicesComplexity.GlyphIndicesAndDistanceOnly:
                break;

            case GlyphIndicesComplexity.ClusterMapping:
                WriteGlyphs_ClusterMapping(glyphs);
                break;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// This is just a draft to see what to do in detail.
        /// </summary>
        private void WriteGlyphs_ClusterMapping(Glyphs glyphs)
        {
            string unicodeString = glyphs.UnicodeString;

#if DEBUG_
            if (!String.IsNullOrEmpty(unicodeString))
            {
                if (unicodeString.StartsWith("abc"))
                {
                    GetType();
                }
            }
#endif

            bool   boldSimulation       = (glyphs.StyleSimulations & StyleSimulations.BoldSimulation) == StyleSimulations.BoldSimulation;
            double boldSimulationFactor = 1;
            if (boldSimulation)
            {
                boldSimulationFactor = 1;
            }

            bool RightToLeft = glyphs.BidiLevel % 2 == 1; // TODOWPF: why is this a level?? what means "bidirectional nesting"?

            GlyphIndices indices = glyphs.Indices;
            if (indices == null)
            {
                indices = new GlyphIndices();
            }
            int  codeIdx    = 0;
            int  codeCount  = String.IsNullOrEmpty(unicodeString) ? 0 : unicodeString.Length;
            int  glyphCount = indices.Count;
            int  glyphIdx   = 0;
            bool stop       = false;

            PdfFont            realizedFont = this.graphicsState.realizedFont;
            OpenTypeDescriptor descriptor   = realizedFont.FontDescriptor._descriptor;
            int glyphIndex;

            double x       = glyphs.OriginX;
            double y       = glyphs.OriginY;
            XPoint pos     = new XPoint(x, y); // accumulation may lead to rounding error -> check it!
            double uOffset = 0;
            double vOffset = 0;

            StringBuilder outputText       = new StringBuilder();
            double        accumulatedWidth = 0;
            int           outputGlyphCount = 0;
            bool          mustRender       = false;
            bool          hasOffset        = false;

            do
            {
                GlyphIndices.GlyphMapping clusterMapping = new GlyphIndices.GlyphMapping(42);
                if (glyphIdx < glyphCount)
                {
                    clusterMapping = indices[glyphIdx];
                }

                for (int clusterGlyphIdx = 0; clusterGlyphIdx < clusterMapping.ClusterGlyphCount; clusterGlyphIdx++)
                {
                    GlyphIndices.GlyphMapping mapping = new GlyphIndices.GlyphMapping(42);
                    if (glyphIdx + clusterGlyphIdx < glyphCount)
                    {
                        mapping = indices[glyphIdx + clusterGlyphIdx];
                    }

                    Debug.Assert(mustRender == false);

                    // Determine whether to render accumulated glyphs
                    if (outputGlyphCount > 0 && (hasOffset || mapping.HasAdvanceWidthOrOffset))
                    {
                        outputText.Append('>');

                        WriteLiteral("{0:0.####} {1:0.####} Td {2}Tj\n", pos.X, pos.Y, outputText.ToString());

                        //double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        //if (!PdfSharp.Internal.DoubleUtil.IsNaN(mapping.AdvanceWidth))
                        //  width = mapping.AdvanceWidth * 10;
                        //pos = new XPoint(accumulatedWidth + width / 1000 * glyphs.FontRenderingEmSize, 0);
                        pos = new XPoint(accumulatedWidth, 0);

                        // reset values
                        accumulatedWidth  = 0;
                        outputGlyphCount  = 0;
                        outputText.Length = 0;
                        mustRender        = false;
                    }

                    mustRender = mapping.HasAdvanceWidth;
                    //mustRender = true;

                    // Adjust former uOffset
                    if (uOffset != 0)
                    {
                        pos.X     -= uOffset;
                        uOffset    = 0;
                        mustRender = true;
                    }

                    // Adjust position by current former uOffset
                    if (mapping.HasUOffset)
                    {
                        uOffset    = mapping.UOffset * glyphs.FontRenderingEmSize / 100;
                        pos.X     += uOffset;
                        mustRender = true;
                        hasOffset  = true;
                    }

                    // Adjust former vOffset
                    if (vOffset != 0)
                    {
                        pos.Y     += vOffset;
                        vOffset    = 0;
                        mustRender = true;
                    }

                    // Adjust position by current former vOffset
                    if (mapping.HasVOffset)
                    {
                        vOffset    = mapping.VOffset * glyphs.FontRenderingEmSize / 100;
                        pos.Y     -= vOffset;
                        mustRender = true;
                        hasOffset  = true;
                    }


                    // get index of current glyph
                    if (mapping.HasGlyphIndex)
                    {
                        glyphIndex = mapping.GlyphIndex;
                    }
                    else
                    {
                        glyphIndex = descriptor.CharCodeToGlyphIndex(unicodeString[codeIdx]);
                    }

                    // add glyph index to the fonts 'used glyph table'
                    realizedFont.AddGlyphIndices(new string((char)glyphIndex, 1));

#if true
                    if (outputGlyphCount == 0)
                    {
                        outputText.Append('<');
                    }
                    outputText.AppendFormat("{0:X2}{1:X2}", (byte)(glyphIndex >> 8), (byte)glyphIndex);
#else
                    byte[] bytes = new byte[2] {
                        (byte)(glyphIndex >> 8), (byte)glyphIndex
                    };
                    bytes = PdfEncoders.FormatStringLiteral(bytes, true, false, true, null);
                    string output = PdfEncoders.RawEncoding.GetString(bytes);
#endif

                    // At the end of the glyph run we must always render
                    if (!mustRender)
                    {
                        mustRender = codeIdx + clusterMapping.ClusterCodeUnitCount >= codeCount && // is it the last code unit cluster
                                     glyphIdx + clusterGlyphIdx + 1 >= glyphCount; // is it the last glyph index
                    }
                    //mustRender = true;
                    if (mustRender)
                    {
                        outputText.Append('>');

                        WriteLiteral("{0:0.####} {1:0.####} Td {2}Tj\n", pos.X, pos.Y, outputText.ToString());

                        double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        if (!PdfSharp.Internal.DoubleUtil.IsNaN(mapping.AdvanceWidth))
                        {
                            width = mapping.AdvanceWidth * 10;
                        }
                        pos = new XPoint(accumulatedWidth + width * boldSimulationFactor / 1000 * glyphs.FontRenderingEmSize, 0);

                        // reset values
                        accumulatedWidth  = 0;
                        outputGlyphCount  = 0;
                        outputText.Length = 0;
                        mustRender        = false;
                    }
                    else // deferred rendering
                    {
                        // accumulate width
                        Debug.Assert(DoubleUtil.IsNaN(mapping.AdvanceWidth));
                        double width = descriptor.GlyphIndexToPdfWidth(glyphIndex);
                        width             = width * boldSimulationFactor / 1000 * glyphs.FontRenderingEmSize;
                        accumulatedWidth += width;

                        outputGlyphCount++;
                    }
                }
                codeIdx  += clusterMapping.ClusterCodeUnitCount;
                glyphIdx += clusterMapping.ClusterGlyphCount;

                if (codeIdx >= codeCount && glyphIdx >= glyphCount)
                {
                    stop = true;
                }
            }while (!stop);
        }