Ejemplo n.º 1
0
        public void GetAndAdd()
        {
            char from = 'é';
            char to   = 'a';

            char result = Diacritics.Add(to, Diacritics.Get(from));

            Assert.AreEqual('á', result);
        }
Ejemplo n.º 2
0
 public void DiacriticsCharTests()
 {
     Assert.IsFalse(Diacritics.Contains('A'));
     Assert.AreEqual('e', Diacritics.Remove('é'));
 }
Ejemplo n.º 3
0
        public void ShowText(IInputBytes bytes)
        {
            var currentState = GetCurrentState();

            var font = currentState.FontState.FromExtendedGraphicsState ? activeExtendedGraphicsStateFont : resourceStore.GetFont(currentState.FontState.FontName);

            if (font == null)
            {
                throw new InvalidOperationException($"Could not find the font with name {currentState.FontState.FontName} in the resource store. It has not been loaded yet.");
            }

            var fontSize          = currentState.FontState.FontSize;
            var horizontalScaling = currentState.FontState.HorizontalScaling / 100.0;
            var characterSpacing  = currentState.FontState.CharacterSpacing;
            var rise = currentState.FontState.Rise;

            var transformationMatrix = currentState.CurrentTransformationMatrix;

            var renderingMatrix =
                TransformationMatrix.FromValues(fontSize * horizontalScaling, 0, 0, fontSize, 0, rise);

            var pointSize = Math.Round(transformationMatrix.Multiply(TextMatrices.TextMatrix).Transform(new PdfRectangle(0, 0, 1, fontSize)).Height, 2);

            while (bytes.MoveNext())
            {
                var code = font.ReadCharacterCode(bytes, out int codeLength);

                var foundUnicode = font.TryGetUnicode(code, out var unicode);

                if (!foundUnicode || unicode == null)
                {
                    log.Warn($"We could not find the corresponding character with code {code} in font {font.Name}.");
                    // Try casting directly to string as in PDFBox 1.8.
                    unicode = new string((char)code, 1);
                }

                var wordSpacing = 0.0;
                if (code == ' ' && codeLength == 1)
                {
                    wordSpacing += GetCurrentState().FontState.WordSpacing;
                }

                var textMatrix = TextMatrices.TextMatrix;

                if (font.IsVertical)
                {
                    if (!(font is IVerticalWritingSupported verticalFont))
                    {
                        throw new InvalidOperationException($"Font {font.Name} was in vertical writing mode but did not implement {nameof(IVerticalWritingSupported)}.");
                    }

                    var positionVector = verticalFont.GetPositionVector(code);

                    textMatrix = textMatrix.Translate(positionVector.X, positionVector.Y);
                }

                var boundingBox = font.GetBoundingBox(code);

                var transformedGlyphBounds = PerformantRectangleTransformer
                                             .Transform(renderingMatrix, textMatrix, transformationMatrix, boundingBox.GlyphBounds);

                var transformedPdfBounds = PerformantRectangleTransformer
                                           .Transform(renderingMatrix, textMatrix, transformationMatrix, new PdfRectangle(0, 0, boundingBox.Width, 0));

                // If the text rendering mode calls for filling, the current nonstroking color in the graphics state is used;
                // if it calls for stroking, the current stroking color is used.
                // In modes that perform both filling and stroking, the effect is as if each glyph outline were filled and then stroked in separate operations.
                // TODO: expose color as something more advanced
                var color = currentState.FontState.TextRenderingMode != TextRenderingMode.Stroke
                    ? currentState.CurrentNonStrokingColor
                    : currentState.CurrentStrokingColor;

                Letter letter = null;
                if (Diacritics.IsInCombiningDiacriticRange(unicode) && bytes.CurrentOffset > 0 && letters.Count > 0)
                {
                    var attachTo = letters[letters.Count - 1];

                    if (attachTo.TextSequence == textSequence &&
                        Diacritics.TryCombineDiacriticWithPreviousLetter(unicode, attachTo.Value, out var newLetter))
                    {
                        // TODO: union of bounding boxes.
                        letters.Remove(attachTo);

                        letter = new Letter(
                            newLetter,
                            attachTo.GlyphRectangle,
                            attachTo.StartBaseLine,
                            attachTo.EndBaseLine,
                            attachTo.Width,
                            attachTo.FontSize,
                            attachTo.Font,
                            attachTo.Color,
                            attachTo.PointSize,
                            attachTo.TextSequence);
                    }
                    else
                    {
                        letter = new Letter(
                            unicode,
                            transformedGlyphBounds,
                            transformedPdfBounds.BottomLeft,
                            transformedPdfBounds.BottomRight,
                            transformedPdfBounds.Width,
                            fontSize,
                            font.Details,
                            color,
                            pointSize,
                            textSequence);
                    }
                }
                else
                {
                    letter = new Letter(
                        unicode,
                        transformedGlyphBounds,
                        transformedPdfBounds.BottomLeft,
                        transformedPdfBounds.BottomRight,
                        transformedPdfBounds.Width,
                        fontSize,
                        font.Details,
                        color,
                        pointSize,
                        textSequence);
                }

                letters.Add(letter);

                markedContentStack.AddLetter(letter);

                double tx, ty;
                if (font.IsVertical)
                {
                    var verticalFont = (IVerticalWritingSupported)font;
                    var displacement = verticalFont.GetDisplacementVector(code);
                    tx = 0;
                    ty = (displacement.Y * fontSize) + characterSpacing + wordSpacing;
                }
                else
                {
                    tx = (boundingBox.Width * fontSize + characterSpacing + wordSpacing) * horizontalScaling;
                    ty = 0;
                }

                TextMatrices.TextMatrix = TextMatrices.TextMatrix.Translate(tx, ty);
            }
        }