From 06253966e4726beff15c969075a20894648a8610 Mon Sep 17 00:00:00 2001 From: mvantzet Date: Fri, 13 Jan 2023 12:35:25 +0100 Subject: [PATCH] Added Letter properties RenderingMode, StrokeColor, FillColor and added those as mandatory constructor arguments. Kept property Color, which contains either StrokeColor (if rendering mode is Stroke) or FillColor (for all other rendering modes). In PdfPageBuilder opted for default text rendering mode "Fill" which seems like a sensible default. --- .../DuplicateOverlappingTextProcessor.cs | 4 +- .../ContentOrderTextExtractor.cs | 4 +- src/UglyToad.PdfPig/Content/Letter.cs | 39 +++++++++++++++++-- .../Graphics/ContentStreamProcessor.cs | 35 +++++------------ src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs | 11 +++++- 5 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs index b3e3e2b1..e6900dfe 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/DuplicateOverlappingTextProcessor.cs @@ -77,7 +77,9 @@ letter.Width, letter.FontSize, fontDetails, - letter.Color, + letter.RenderingMode, + letter.StrokeColor, + letter.FillColor, letter.PointSize, letter.TextSequence); diff --git a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs index 8766a694..80f5f58a 100644 --- a/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs +++ b/src/UglyToad.PdfPig.DocumentLayoutAnalysis/TextExtractor/ContentOrderTextExtractor.cs @@ -65,7 +65,9 @@ letter.Width, letter.FontSize, letter.Font, - letter.Color, + letter.RenderingMode, + letter.StrokeColor, + letter.FillColor, letter.PointSize, letter.TextSequence); } diff --git a/src/UglyToad.PdfPig/Content/Letter.cs b/src/UglyToad.PdfPig/Content/Letter.cs index b15ea4f3..08abfcd3 100644 --- a/src/UglyToad.PdfPig/Content/Letter.cs +++ b/src/UglyToad.PdfPig/Content/Letter.cs @@ -61,12 +61,33 @@ /// Details about the font for this letter. /// public FontDetails Font { get; } + + /// + /// Text rendering mode that indicates whether we should draw this letter's strokes, + /// fill, both, neither (in case of hidden text), etc. + /// If it calls for stroking the is used. + /// If it calls for filling, the 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. + /// + public TextRenderingMode RenderingMode { get; } /// - /// The color of the letter. + /// The primary color of the letter, which is either the in case + /// is , or otherwise + /// it is the . /// public IColor Color { get; } + /// + /// Stroking color + /// + public IColor StrokeColor { get; } + + /// + /// Non-stroking (fill) color + /// + public IColor FillColor { get; } + /// /// The size of the font in points. /// @@ -86,7 +107,9 @@ double width, double fontSize, FontDetails font, - IColor color, + TextRenderingMode renderingMode, + IColor strokeColor, + IColor fillColor, double pointSize, int textSequence) { @@ -97,7 +120,17 @@ Width = width; FontSize = fontSize; Font = font; - Color = color ?? GrayColor.Black; + RenderingMode = renderingMode; + if (renderingMode == TextRenderingMode.Stroke) + { + Color = StrokeColor = strokeColor ?? GrayColor.Black; + FillColor = fillColor; + } + else + { + Color = FillColor = fillColor ?? GrayColor.Black; + StrokeColor = strokeColor; + } PointSize = pointSize; TextSequence = textSequence; TextOrientation = GetTextOrientation(); diff --git a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs index 1e5efffd..7759c9cc 100644 --- a/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs +++ b/src/UglyToad.PdfPig/Graphics/ContentStreamProcessor.cs @@ -292,14 +292,7 @@ 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) { @@ -319,26 +312,16 @@ attachTo.Width, attachTo.FontSize, attachTo.Font, - attachTo.Color, + attachTo.RenderingMode, + attachTo.StrokeColor, + attachTo.FillColor, attachTo.PointSize, attachTo.TextSequence); } - else - { - letter = new Letter( - unicode, - transformedGlyphBounds, - transformedPdfBounds.BottomLeft, - transformedPdfBounds.BottomRight, - transformedPdfBounds.Width, - fontSize, - font.Details, - color, - pointSize, - textSequence); - } } - else + + // If we did not create a letter for a combined diacritic, create one here. + if (letter == null) { letter = new Letter( unicode, @@ -348,7 +331,9 @@ transformedPdfBounds.Width, fontSize, font.Details, - color, + currentState.FontState.TextRenderingMode, + currentState.CurrentStrokingColor, + currentState.CurrentNonStrokingColor, pointSize, textSequence); } diff --git a/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs b/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs index c814f75b..7552a9ac 100644 --- a/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs +++ b/src/UglyToad.PdfPig/Writer/PdfPageBuilder.cs @@ -895,7 +895,16 @@ var documentSpace = textMatrix.Transform(renderingMatrix.Transform(fontMatrix.Transform(rect))); - var letter = new Letter(c.ToString(), documentSpace, advanceRect.BottomLeft, advanceRect.BottomRight, width, (double)fontSize, FontDetails.GetDefault(name), + var letter = new Letter( + c.ToString(), + documentSpace, + advanceRect.BottomLeft, + advanceRect.BottomRight, + width, + (double)fontSize, + FontDetails.GetDefault(name), + TextRenderingMode.Fill, + GrayColor.Black, GrayColor.Black, (double)fontSize, textSequence);