Exemplo n.º 1
0
        /**
         * <summary>Executes scanning on this operation.</summary>
         * <param name="state">Graphics state context.</param>
         * <param name="textScanner">Scanner to be notified about text contents.
         * In case it's null, the operation is applied to the graphics state context.</param>
         */
        public void Scan(
            ContentScanner.GraphicsState state,
            IScanner textScanner
            )
        {
            /*
             * TODO: I really dislike this solution -- it's a temporary hack until the event-driven
             * parsing mechanism is implemented...
             */
            /*
             * TODO: support to vertical writing mode.
             */

            double contextHeight = state.Scanner.ContextSize.Height;
            // PK - 2017-09-15 - state.Font can be null, which throws an exception below, so fall back on standard Courier
            Font   font               = state.Font ?? new StandardType1Font(((Page)state.Scanner.RootLevel.ContentContext).Document, StandardType1Font.FamilyEnum.Courier, false, false);
            double fontSize           = state.FontSize;
            double scaledFactor       = Font.GetScalingFactor(fontSize) * state.Scale;
            bool   wordSpaceSupported = !(font is CompositeFont);
            double wordSpace          = wordSpaceSupported ? state.WordSpace * state.Scale : 0;
            double charSpace          = state.CharSpace * state.Scale;
            Matrix ctm = state.Ctm.Clone();
            Matrix tm  = state.Tm;

            if (this is ShowTextToNextLine)
            {
                ShowTextToNextLine showTextToNextLine = (ShowTextToNextLine)this;
                double?            newWordSpace       = showTextToNextLine.WordSpace;
                if (newWordSpace != null)
                {
                    if (textScanner == null)
                    {
                        state.WordSpace = newWordSpace.Value;
                    }
                    if (wordSpaceSupported)
                    {
                        wordSpace = newWordSpace.Value * state.Scale;
                    }
                }
                double?newCharSpace = showTextToNextLine.CharSpace;
                if (newCharSpace != null)
                {
                    if (textScanner == null)
                    {
                        state.CharSpace = newCharSpace.Value;
                    }
                    charSpace = newCharSpace.Value * state.Scale;
                }
                tm = state.Tlm.Clone();
                tm.Multiply(new Matrix(1, 0, 0, 1, 0, (float)-state.Lead));
            }
            else
            {
                tm = state.Tm.Clone();
            }

            foreach (object textElement in Value)
            {
                if (textElement is byte[]) // Text string.
                {
                    string textString = font.Decode((byte[])textElement);
                    foreach (char textChar in textString)
                    {
                        double charWidth = font.GetWidth(textChar) * scaledFactor;

                        if (textScanner != null)
                        {
                            /*
                             * NOTE: The text rendering matrix is recomputed before each glyph is painted
                             * during a text-showing operation.
                             */
                            Matrix trm                  = ctm.Clone(); trm.Multiply(tm);
                            double charHeight           = font.GetHeight(textChar, fontSize);
                            drawing::RectangleF charBox = new drawing::RectangleF(
                                trm.Elements[4],
                                (float)(contextHeight - trm.Elements[5] - font.GetAscent(fontSize) * trm.Elements[3]),
                                (float)charWidth * trm.Elements[0],
                                (float)charHeight * trm.Elements[3]
                                );
                            textScanner.ScanChar(textChar, charBox);
                        }

                        /*
                         * NOTE: After the glyph is painted, the text matrix is updated
                         * according to the glyph displacement and any applicable spacing parameter.
                         */
                        tm.Translate((float)(charWidth + charSpace + (textChar == ' ' ? wordSpace : 0)), 0);
                    }
                }
                else // Text position adjustment.
                {
                    tm.Translate((float)(-Convert.ToSingle(textElement) * scaledFactor), 0);
                }
            }

            if (textScanner == null)
            {
                state.Tm = tm;

                if (this is ShowTextToNextLine)
                {
                    state.Tlm = tm.Clone();
                }
            }
        }
Exemplo n.º 2
0
        /**
         * <summary>Executes scanning on this operation.</summary>
         * <param name="state">Graphics state context.</param>
         * <param name="textScanner">Scanner to be notified about text contents.
         * In case it's null, the operation is applied to the graphics state context.</param>
         */
        public void Scan(
            ContentScanner.GraphicsState state,
            IScanner textScanner
            )
        {
            /*
             * TODO: I really dislike this solution -- it's a temporary hack until the event-driven
             * parsing mechanism is implemented...
             */
            /*
             * TODO: support to vertical writing mode.
             */

            IContentContext context       = state.Scanner.ContentContext;
            float           contextHeight = context.Box.Height;
            Font            font          = state.Font;
            float           fontSize      = state.FontSize;
            float           scale         = state.Scale / 100;
            float           scaledFactor  = Font.GetScalingFactor(fontSize) * scale;
            float           wordSpace     = state.WordSpace * scale;
            float           charSpace     = state.CharSpace * scale;
            Matrix          ctm           = state.Ctm.Clone();
            Matrix          tm            = state.Tm;

            if (this is ShowTextToNextLine)
            {
                ShowTextToNextLine showTextToNextLine = (ShowTextToNextLine)this;
                float?newWordSpace = showTextToNextLine.WordSpace;
                if (newWordSpace != null)
                {
                    if (textScanner == null)
                    {
                        state.WordSpace = newWordSpace.Value;
                    }
                    wordSpace = newWordSpace.Value * scale;
                }
                float?newCharSpace = showTextToNextLine.CharSpace;
                if (newCharSpace != null)
                {
                    if (textScanner == null)
                    {
                        state.CharSpace = newCharSpace.Value;
                    }
                    charSpace = newCharSpace.Value * scale;
                }
                tm = state.Tlm.Clone();
                tm.Translate(0, state.Lead);
            }
            else
            {
                tm = state.Tm.Clone();
            }

            foreach (object textElement in Value)
            {
                if (textElement is byte[]) // Text string.
                {
                    string textString = font.Decode((byte[])textElement);
                    foreach (char textChar in textString)
                    {
                        float charWidth = font.GetWidth(textChar) * scaledFactor;

                        if (textScanner != null)
                        {
                            /*
                             * NOTE: The text rendering matrix is recomputed before each glyph is painted
                             * during a text-showing operation.
                             */
                            Matrix trm                  = ctm.Clone(); trm.Multiply(tm);
                            float  charHeight           = font.GetHeight(textChar, fontSize);
                            drawing::RectangleF charBox = new drawing::RectangleF(
                                trm.Elements[4],
                                contextHeight - trm.Elements[5] - font.GetAscent(fontSize) * tm.Elements[3],
                                charWidth * tm.Elements[0],
                                charHeight * tm.Elements[3]
                                );
                            textScanner.ScanChar(textChar, charBox);
                        }

                        /*
                         * NOTE: After the glyph is painted, the text matrix is updated
                         * according to the glyph displacement and any applicable spacing parameter.
                         */
                        tm.Translate(charWidth + charSpace + (textChar == ' ' ? wordSpace : 0), 0);
                    }
                }
                else // Text position adjustment.
                {
                    tm.Translate(-Convert.ToSingle(textElement) * scaledFactor, 0);
                }
            }

            if (textScanner == null)
            {
                state.Tm = tm;

                if (this is ShowTextToNextLine)
                {
                    state.Tlm = tm.Clone();
                }
            }
        }