diff --git a/pdf/draw_absolute_test.go b/pdf/draw_absolute_test.go index 15cf720..4735111 100644 --- a/pdf/draw_absolute_test.go +++ b/pdf/draw_absolute_test.go @@ -816,6 +816,6 @@ func TestAbsoluteImageBackground(t *testing.T) { left: 1px; } - + `) } diff --git a/pdf/draw_background_test.go b/pdf/draw_background_test.go index 1c22991..694a06b 100644 --- a/pdf/draw_background_test.go +++ b/pdf/draw_background_test.go @@ -11,8 +11,7 @@ import ( // Test how backgrounds are drawn. func TestCanvasBackground(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) for _, data := range [][3]string{ {"all_blue", strings.Repeat(strings.Repeat("B", 10)+"\n", 10), ` `) } func TestPageBackgroundFixed(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) // Regression test for https://github.com/Kozea/WeasyPrint/issues/1993 assertPixelsEqual(t, ` RBBB @@ -1072,15 +1055,14 @@ func TestPageBackgroundFixed(t *testing.T) { `, ` `) } func TestPageBackgroundFixedBleed(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) // Regression test for https://github.com/Kozea/WeasyPrint/issues/1993 assertPixelsEqual(t, ` RRRRRR @@ -1092,15 +1074,14 @@ func TestPageBackgroundFixedBleed(t *testing.T) { `, ` `) } func TestBleedBackgroundSizeClip(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) // Regression test for https://github.com/Kozea/WeasyPrint/issues/1943 assertPixelsEqual(t, ` BBBBBB @@ -1112,15 +1093,14 @@ func TestBleedBackgroundSizeClip(t *testing.T) { `, ` `) } func TestMarksCrop(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` KK__KK K____K @@ -1136,8 +1116,7 @@ func TestMarksCrop(t *testing.T) { } func TestMarksCross(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __KK__ ______ @@ -1153,8 +1132,7 @@ func TestMarksCross(t *testing.T) { } func TestMarksCropCross(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` KKKKKK K____K diff --git a/pdf/draw_box_test.go b/pdf/draw_box_test.go index 2a3b805..5847135 100644 --- a/pdf/draw_box_test.go +++ b/pdf/draw_box_test.go @@ -106,12 +106,11 @@ func TestBorders(t *testing.T) { // Test the rendering of collapsing borders. func TestBordersTableCollapse(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) source := ` ` @@ -119,13 +118,17 @@ func TestBordersTableCollapse(t *testing.T) { // Do not test the exact rendering of earch border style but at least // check that they do not do the same. var documents []string - for _, borderStyle := range []string{ + for _, borderStyle := range [...]string{ "none", "solid", "dashed", "dotted", "double", - "inset", "outset", "groove", "ridge", + "outset", /* "groove", */ + "inset", /* "ridge", */ } { documents = append(documents, fmt.Sprintf(source, borderStyle)) } assertDifferentRenderings(t, documents) + + assertSameRendering(t, fmt.Sprintf(source, "outset"), fmt.Sprintf(source, "groove"), 0) + assertSameRendering(t, fmt.Sprintf(source, "inset"), fmt.Sprintf(source, "ridge"), 0) } func TestOutlines(t *testing.T) { @@ -183,8 +186,7 @@ func TestEmBorders(t *testing.T) { } func TestBordersBoxSizing(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ________ _RRRRRR_ @@ -329,8 +331,7 @@ func TestRoundedRect(t *testing.T) { } func TestDrawBorderRadius(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___zzzzz __zzzzzz @@ -357,8 +358,7 @@ func TestDrawBorderRadius(t *testing.T) { } func TestDrawSplitBorderRadius(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___zzzzz __zzzzzz @@ -404,8 +404,7 @@ func TestDrawSplitBorderRadius(t *testing.T) { } func TestBorderImageStretch(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ _RYYYMMMG_ @@ -422,7 +421,7 @@ func TestBorderImageStretch(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 25%; height: 4px; margin: 1px; @@ -434,8 +433,7 @@ func TestBorderImageStretch(t *testing.T) { } func TestBorderImageFill(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ _RYYYMMMG_ @@ -452,7 +450,7 @@ func TestBorderImageFill(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 25% fill; height: 4px; margin: 1px; @@ -464,8 +462,7 @@ func TestBorderImageFill(t *testing.T) { } func TestBorderImageDefaultSlice(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _____________ _RYMG___RYMG_ @@ -486,7 +483,7 @@ func TestBorderImageDefaultSlice(t *testing.T) { } div { border: 4px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); height: 2px; margin: 1px; width: 3px; @@ -497,8 +494,7 @@ func TestBorderImageDefaultSlice(t *testing.T) { } func TestBorderImageUnevenWidth(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ____________ _RRRYYYMMMG_ @@ -516,7 +512,7 @@ func TestBorderImageUnevenWidth(t *testing.T) { div { border: 1px solid black; border-left-width: 3px; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 25%; height: 4px; margin: 1px; @@ -528,8 +524,7 @@ func TestBorderImageUnevenWidth(t *testing.T) { } func TestBorderImageNotPercent(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ _RYYYMMMG_ @@ -546,7 +541,7 @@ func TestBorderImageNotPercent(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 1; height: 4px; margin: 1px; @@ -558,8 +553,7 @@ func TestBorderImageNotPercent(t *testing.T) { } func TestBorderImageRepeat(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ _RYMYMYMYG_ @@ -576,7 +570,7 @@ func TestBorderImageRepeat(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 25%; border-image-repeat: repeat; height: 4px; @@ -589,8 +583,7 @@ func TestBorderImageRepeat(t *testing.T) { } func TestBorderImageSpace(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ _R_YMC_G_ @@ -608,7 +601,7 @@ func TestBorderImageSpace(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border2.svg); + border-image-source: url(../resources_test/border2.svg); border-image-slice: 20%; border-image-repeat: space; height: 5px; @@ -621,8 +614,7 @@ func TestBorderImageSpace(t *testing.T) { } func TestBorderImageOutset(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ____________ _RYYYYMMMMG_ @@ -641,7 +633,7 @@ func TestBorderImageOutset(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 25%; border-image-outset: 2px; height: 2px; @@ -655,8 +647,7 @@ func TestBorderImageOutset(t *testing.T) { } func TestBorderImageWidth(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ _RRYYMMGG_ @@ -673,7 +664,7 @@ func TestBorderImageWidth(t *testing.T) { } div { border: 1px solid black; - border-image-source: url(border.svg); + border-image-source: url(../resources_test/border.svg); border-image-slice: 25%; border-image-width: 2; height: 4px; @@ -686,8 +677,7 @@ func TestBorderImageWidth(t *testing.T) { } func TestBorderImageGradient(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ _RRRRRRRR_ diff --git a/pdf/draw_image_test.go b/pdf/draw_image_test.go index 728fccd..4727e14 100644 --- a/pdf/draw_image_test.go +++ b/pdf/draw_image_test.go @@ -637,7 +637,7 @@ func TestImagesBorder(t *testing.T) { body { margin: 0; font-size: 0 } img { margin: 1px; border: 1px solid lime } -
`) +
`) } func TestImagesBorderAbsolute(t *testing.T) { @@ -649,7 +649,7 @@ func TestImagesBorderAbsolute(t *testing.T) { body { margin: 0; font-size: 0 } img { margin: 1px; border: 1px solid lime; position: absolute } -
`) +
`) } func TestImageExif(t *testing.T) { diff --git a/pdf/draw_svg_markers_test.go b/pdf/draw_svg_markers_test.go index 162d707..73065d3 100644 --- a/pdf/draw_svg_markers_test.go +++ b/pdf/draw_svg_markers_test.go @@ -7,8 +7,7 @@ import ( ) func TestMarkers(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ___________ @@ -44,8 +43,7 @@ func TestMarkers(t *testing.T) { } func TestMarkersViewbox(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ____RRR____ @@ -81,8 +79,7 @@ func TestMarkersViewbox(t *testing.T) { } func TestMarkersSize(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ____BBR____ @@ -120,8 +117,7 @@ func TestMarkersSize(t *testing.T) { } func TestMarkersViewboxSize(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ____RRR____ @@ -195,8 +191,7 @@ func TestMarkersOverflow(t *testing.T) { } func TestMarkersUserspace(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ___________ @@ -233,8 +228,7 @@ func TestMarkersUserspace(t *testing.T) { } func TestMarkersStrokeWidth(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ___________ @@ -271,8 +265,7 @@ func TestMarkersStrokeWidth(t *testing.T) { } func TestMarkersViewboxStrokeWidth(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` ___________ ____BRR____ diff --git a/pdf/draw_svg_test.go b/pdf/draw_svg_test.go index 0b50b92..847bcd9 100644 --- a/pdf/draw_svg_test.go +++ b/pdf/draw_svg_test.go @@ -4,13 +4,11 @@ import ( "fmt" "testing" - "github.com/benoitkugler/webrender/utils/testutils" tu "github.com/benoitkugler/webrender/utils/testutils" ) func TestUse(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` RRRRR_____ @@ -43,8 +41,7 @@ func TestUse(t *testing.T) { // Test how SVG simple patterns are drawn. func TestPattern(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` BBrrBBrr @@ -77,8 +74,7 @@ func TestPattern(t *testing.T) { } func TestPattern_2(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` BBrrBBrr @@ -111,8 +107,7 @@ func TestPattern_2(t *testing.T) { } func TestPattern_3(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` BBrrBBrr @@ -145,8 +140,7 @@ func TestPattern_3(t *testing.T) { } func TestPattern_4(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` BBrrBBrr @@ -188,8 +182,7 @@ const svgOpacitySource = ` %s` func TestOpacity(t *testing.T) { - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertSameRendering(t, fmt.Sprintf(svgOpacitySource, ` `), fmt.Sprintf(svgOpacitySource, ` + stroke="lime" fill="blue" fill-opacity="0.5" /> `), 0) } @@ -221,7 +213,7 @@ func TestFillOpacity(t *testing.T) { // @pytest.mark.xfail // func TestStrokeOpacity(t *testing.T) { -// capt := testutils.CaptureLogs() +// capt := tu.CaptureLogs() // defer capt.AssertNoLogs(t) // assertSameRendering(t, / ("stroke_opacity_reference", svgOpacitySource % ` @@ -239,7 +231,7 @@ func TestFillOpacity(t *testing.T) { // @pytest.mark.xfail // func TestStrokeFillOpacity(t *testing.T) { -// capt := testutils.CaptureLogs() +// capt := tu.CaptureLogs() // defer capt.AssertNoLogs(t) // assertSameRendering(t, / ("stroke_fill_opacity_reference", svgOpacitySource % ` @@ -258,7 +250,7 @@ func TestFillOpacity(t *testing.T) { // @pytest.mark.xfail // func TestPatternGradientStrokeFillOpacity(t *testing.T) { -// capt := testutils.CaptureLogs() +// capt := tu.CaptureLogs() // defer capt.AssertNoLogs(t) // assertSameRendering(t, / ("pattern_gradient_stroke_fill_opacity_reference", svgOpacitySource % ` @@ -306,8 +298,7 @@ func TestFillOpacity(t *testing.T) { func TestTranslateOpacity(t *testing.T) { // Regression test for https://github.com/Kozea/WeasyPrint/issues/1976 - capt := tu.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertSameRendering(t, fmt.Sprintf(svgOpacitySource, ` @@ -324,8 +315,7 @@ func TestTranslateOpacity(t *testing.T) { // Test how SVG simple shapes are drawn. func TestRectStroke(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -350,8 +340,7 @@ func TestRectStroke(t *testing.T) { } func TestRectFill(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -375,8 +364,7 @@ func TestRectFill(t *testing.T) { } func TestRectStrokeFill(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -401,8 +389,7 @@ func TestRectStrokeFill(t *testing.T) { } func TestRectRound(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _zzzzzzz_ @@ -426,8 +413,7 @@ func TestRectRound(t *testing.T) { } func TestRectRoundZero(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` RRRRRRRRR @@ -451,8 +437,7 @@ func TestRectRoundZero(t *testing.T) { } func TestLine(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -477,8 +462,7 @@ func TestLine(t *testing.T) { } func TestPolyline(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -503,8 +487,7 @@ func TestPolyline(t *testing.T) { } func TestPolylineFill(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -529,8 +512,7 @@ func TestPolylineFill(t *testing.T) { } func TestPolygon(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -555,8 +537,7 @@ func TestPolygon(t *testing.T) { } func TestPolygonFill(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -581,8 +562,7 @@ func TestPolygonFill(t *testing.T) { } func TestCircleStroke(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ @@ -608,8 +588,7 @@ func TestCircleStroke(t *testing.T) { } func TestCircleFill(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ @@ -635,8 +614,7 @@ func TestCircleFill(t *testing.T) { } func TestEllipseStroke(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ @@ -662,8 +640,7 @@ func TestEllipseStroke(t *testing.T) { } func TestEllipseFill(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` __________ @@ -689,8 +666,7 @@ func TestEllipseFill(t *testing.T) { } func TestRectInG(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` RRRRR____ @@ -716,8 +692,7 @@ func TestRectInG(t *testing.T) { } func TestRectXYInG(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -743,8 +718,7 @@ func TestRectXYInG(t *testing.T) { } func TestRectStrokeZero(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -769,8 +743,7 @@ func TestRectStrokeZero(t *testing.T) { } func TestRectWidthHeightZero(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -797,8 +770,7 @@ func TestRectWidthHeightZero(t *testing.T) { // attributes. func TestVisibilityVisible(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -823,8 +795,7 @@ func TestVisibilityVisible(t *testing.T) { } func TestVisibilityHidden(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -849,8 +820,7 @@ func TestVisibilityHidden(t *testing.T) { } func TestVisibilityInheritHidden(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -876,8 +846,7 @@ func TestVisibilityInheritHidden(t *testing.T) { } func TestVisibilityInheritVisible(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -904,8 +873,7 @@ func TestVisibilityInheritVisible(t *testing.T) { } func TestDisplayInline(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -930,8 +898,7 @@ func TestDisplayInline(t *testing.T) { } func TestDisplayNone(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -956,8 +923,7 @@ func TestDisplayNone(t *testing.T) { } func TestDisplayInheritNone(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ @@ -983,8 +949,7 @@ func TestDisplayInheritNone(t *testing.T) { } func TestDisplayInheritInline(t *testing.T) { - capt := testutils.CaptureLogs() - defer capt.AssertNoLogs(t) + defer tu.CaptureLogs().AssertNoLogs(t) assertPixelsEqual(t, ` _________ diff --git a/pdf/draw_test.go b/pdf/draw_test.go index db90829..c46629a 100644 --- a/pdf/draw_test.go +++ b/pdf/draw_test.go @@ -34,9 +34,9 @@ var colorByName = map[byte]color.RGBA{ 'G': {R: 0, G: 255, B: 0, A: 255}, // lime green 'V': {R: 191, G: 0, B: 64, A: 255}, // average of 1*B and 3*R. 'S': {R: 255, G: 63, B: 63, A: 255}, // R above R above #fff - 'C': {R: 0, G: 255, B: 255}, // cyan - 'M': {R: 255, G: 0, B: 255}, // magenta - 'Y': {R: 255, G: 255, B: 0}, // yellow + 'C': {R: 0, G: 255, B: 255, A: 255}, // cyan + 'M': {R: 255, G: 0, B: 255, A: 255}, // magenta + 'Y': {R: 255, G: 255, B: 0, A: 255}, // yellow 'r': {R: 255, G: 0, B: 0, A: 255}, // red 'g': {R: 0, G: 128, B: 0, A: 255}, // half green 'b': {R: 0, G: 0, B: 128, A: 255}, // half blue @@ -317,7 +317,7 @@ func assertPixelsEqualFromPixels(t *testing.T, expectedPixels [][]color.RGBA, in for j, v := range exp { g := gotPixels[i][j] if v != g { - t.Fatalf("(file://%s): pixel at (%d, %d): expected %v, got %v", got.Name(), i, j, + t.Fatalf("(file://%s): pixel at (row: %d, col: %d): expected %v, got %v", got.Name(), i+1, j+1, formatColor(v), formatColor(g)) } } diff --git a/pdf/draw_text_test.go b/pdf/draw_text_test.go index 2ad9c37..6c068e5 100644 --- a/pdf/draw_text_test.go +++ b/pdf/draw_text_test.go @@ -670,18 +670,18 @@ func TestTextSubsetComposite(t *testing.T) { // check that subsetting does not remove // composite glyphs deps assertPixelsEqual(t, ` - _______ - ____R__ - ____R__ - ___R___ - _______ - _RRRRR_ - _R___R_ - _RRRRR_ - _R_____ - _R___R_ - __RRRR_ - _______ + _______ + _______ + _______ + ___RR__ + __RR___ + _______ + __RRR__ + _R___R_ + _R___R_ + _RRRRR_ + _R_____ + _R_____ `, `
é
`) } @@ -797,6 +798,7 @@ func TestTabulationCharacter(t *testing.T) { } func TestOtbFont(t *testing.T) { + t.Skip() // TODO: https://github.com/benoitkugler/webrender/issues/3 assertPixelsEqual(t, ` ____________________ __RR______RR________ diff --git a/pdf/page.go b/pdf/page.go index 7fdb605..6ad26b8 100644 --- a/pdf/page.go +++ b/pdf/page.go @@ -21,13 +21,13 @@ var ( ) func (g *group) SetAlphaMask(mask backend.Canvas) { - alphaStream := mask.(*group).app + alphaStream := mask.(*group).stream g.drawMask(&alphaStream) } func (g *group) SetColorPattern(p backend.Canvas, contentWidth, contentHeight fl, mt matrix.Transform, stroke bool) { mat := model.Matrix{mt.A, mt.B, mt.C, mt.D, mt.E, mt.F} - mat = mat.Multiply(g.app.State.Matrix) + mat = mat.Multiply(g.stream.State.Matrix) // initiate the pattern ... _, _, gridWidth, gridHeight := p.GetBoundingBox() @@ -38,20 +38,20 @@ func (g *group) SetColorPattern(p backend.Canvas, contentWidth, contentHeight fl TilingType: 1, } - contentXObject := p.(*group).app.ToXFormObject(compressStreams) + contentXObject := p.(*group).stream.ToXFormObject(compressStreams) // wrap the content into a Do command patternApp := cs.NewGraphicStream(model.Rectangle{Llx: 0, Lly: 0, Urx: contentWidth, Ury: contentHeight}) patternApp.AddXObject(contentXObject) patternApp.ApplyToTilling(pattern) // select the color space - patternName := g.app.AddPattern(pattern) + patternName := g.stream.AddPattern(pattern) if stroke { - g.app.Ops(cs.OpSetStrokeColorSpace{ColorSpace: model.ColorSpacePattern}) - g.app.Ops(cs.OpSetStrokeColorN{Pattern: patternName}) + g.stream.Ops(cs.OpSetStrokeColorSpace{ColorSpace: model.ColorSpacePattern}) + g.stream.Ops(cs.OpSetStrokeColorN{Pattern: patternName}) } else { - g.app.Ops(cs.OpSetFillColorSpace{ColorSpace: model.ColorSpacePattern}) - g.app.Ops(cs.OpSetFillColorN{Pattern: patternName}) + g.stream.Ops(cs.OpSetFillColorSpace{ColorSpace: model.ColorSpacePattern}) + g.stream.Ops(cs.OpSetFillColorN{Pattern: patternName}) } } @@ -62,14 +62,22 @@ func (g *group) SetBlendingMode(mode string) { chunks[i] = strings.Title(s) } bm := strings.Join(chunks, "") - g.app.SetGraphicState(&model.GraphicState{BM: []model.Name{model.ObjName(bm)}}) + g.stream.SetGraphicState(&model.GraphicState{BM: []model.Name{model.ObjName(bm)}}) } func (g *group) Clip(evenOdd bool) { if evenOdd { - g.app.Ops(cs.OpEOClip{}, cs.OpEndPath{}) + g.stream.Ops(cs.OpEOClip{}, cs.OpEndPath{}) } else { - g.app.Ops(cs.OpClip{}, cs.OpEndPath{}) + g.stream.Ops(cs.OpClip{}, cs.OpEndPath{}) + } +} + +func (g *group) SetAlpha(alpha fl, stroke bool) { + if stroke { + g.stream.SetStrokeAlpha(alpha) + } else { + g.stream.SetFillAlpha(alpha) } } @@ -77,24 +85,24 @@ func (g *group) SetColorRgba(color parser.RGBA, stroke bool) { alpha := color.A color.A = 1 // do not take into account the opacity, it is handled by `setXXXAlpha` if stroke { - g.app.SetColorStroke(color) - g.app.SetStrokeAlpha(alpha) + g.stream.SetColorStroke(color) + g.stream.SetStrokeAlpha(alpha) } else { - g.app.SetColorFill(color) - g.app.SetFillAlpha(alpha) + g.stream.SetColorFill(color) + g.stream.SetFillAlpha(alpha) } } func (g *group) SetLineWidth(width fl) { - g.app.Ops(cs.OpSetLineWidth{W: width}) + g.stream.Ops(cs.OpSetLineWidth{W: width}) } func (g *group) SetDash(dashes []fl, offset fl) { - g.app.Ops(cs.OpSetDash{Dash: model.DashPattern{Array: dashes, Phase: offset}}) + g.stream.Ops(cs.OpSetDash{Dash: model.DashPattern{Array: dashes, Phase: offset}}) } func (g *group) SetStrokeOptions(opts backend.StrokeOptions) { - g.app.Ops( + g.stream.Ops( cs.OpSetLineCap{Style: uint8(opts.LineCap)}, cs.OpSetLineJoin{Style: uint8(opts.LineJoin)}, cs.OpSetMiterLimit{Limit: opts.MiterLimit}, @@ -102,7 +110,7 @@ func (g *group) SetStrokeOptions(opts backend.StrokeOptions) { } func (g *group) GetTransform() matrix.Transform { - m := g.app.State.Matrix + m := g.stream.State.Matrix return matrix.New(m[0], m[1], m[2], m[3], m[4], m[5]) } @@ -111,7 +119,7 @@ func (g *group) GetTransform() matrix.Transform { // The new transformation of user space takes place // after any existing transformation. func (g *group) Transform(mt matrix.Transform) { - g.app.Transform(model.Matrix{mt.A, mt.B, mt.C, mt.D, mt.E, mt.F}) + g.stream.Transform(model.Matrix{mt.A, mt.B, mt.C, mt.D, mt.E, mt.F}) } // group implements backend.Canvas and @@ -119,15 +127,15 @@ func (g *group) Transform(mt matrix.Transform) { type group struct { cache - app cs.GraphicStream + stream cs.GraphicStream } func newGroup(cache cache, left, top, right, bottom fl, ) group { return group{ - cache: cache, - app: cs.NewGraphicStream(model.Rectangle{Llx: left, Lly: top, Urx: right, Ury: bottom}), // y grows downward + cache: cache, + stream: cs.NewGraphicStream(model.Rectangle{Llx: left, Lly: top, Urx: right, Ury: bottom}), // y grows downward } } @@ -157,7 +165,7 @@ func newContextPage(left, top, right, bottom fl, // update the underlying PageObject with the content stream func (cp *outputPage) finalize() { // the MediaBox is the unsclaled BBox. TODO: why ? - cp.app.ApplyToPageObject(&cp.page, compressStreams) + cp.stream.ApplyToPageObject(&cp.page, compressStreams) if cp.customMediaBox != nil { cp.page.MediaBox = cp.customMediaBox } @@ -225,13 +233,13 @@ func (cp *outputPage) SetBleedBox(left fl, top fl, right fl, bottom fl) { // Returns the current page rectangle func (g *group) GetBoundingBox() (left, top, right, bottom fl) { - bbox := g.app.BoundingBox + bbox := g.stream.BoundingBox return bbox.Llx, bbox.Lly, bbox.Urx, bbox.Ury } // Updates the current page rectangle func (g *group) SetBoundingBox(left, top, right, bottom fl) { - bbox := &g.app.BoundingBox + bbox := &g.stream.BoundingBox bbox.Llx = left bbox.Lly = top bbox.Urx = right @@ -243,9 +251,9 @@ func (g *group) SetBoundingBox(left, top, right, bottom fl) { // If an error is encoutered, the stack is still restored // and the error is returned func (g *group) OnNewStack(task func()) { - g.app.SaveState() + g.stream.SaveState() task() - _ = g.app.RestoreState() // the calls are balanced + _ = g.stream.RestoreState() // the calls are balanced } // NewGroup creates a new drawing target with the given @@ -258,27 +266,27 @@ func (g *group) NewGroup(x fl, y fl, width fl, height fl) backend.Canvas { // DrawGroup add the `gr` content to the current target. It will panic // if `gr` was not created with `AddGroup` func (g *group) DrawWithOpacity(opacity fl, gr backend.Canvas) { - content := gr.(*group).app.ToXFormObject(compressStreams) + content := gr.(*group).stream.ToXFormObject(compressStreams) form := &model.XObjectTransparencyGroup{ XObjectForm: *content, CS: model.ColorSpaceRGB, I: true, } - g.app.SetFillAlpha(opacity) - g.app.SetStrokeAlpha(opacity) - g.app.AddXObject(form) + g.stream.SetFillAlpha(opacity) + g.stream.SetStrokeAlpha(opacity) + g.stream.AddXObject(form) } func (g *group) drawMask(app *cs.GraphicStream) { transparency := app.ToXFormObject(compressStreams) - g.app.SetAlphaMask(transparency) + g.stream.SetAlphaMask(transparency) } // Adds a rectangle of the given size to the current path, // at position “(x, y)“ in user-space coordinates. // (X,Y) coordinates are the top left corner of the rectangle. func (g *group) Rectangle(x fl, y fl, width fl, height fl) { - g.app.Ops(cs.OpRectangle{X: x, Y: y, W: width, H: height}) + g.stream.Ops(cs.OpRectangle{X: x, Y: y, W: width, H: height}) } // A drawing operator that fills the current path @@ -291,27 +299,27 @@ func (g *group) Paint(op backend.PaintOp) { evenOdd := op&backend.FillEvenOdd != 0 if fill && stroke { if evenOdd { - g.app.Ops(cs.OpEOFillStroke{}) + g.stream.Ops(cs.OpEOFillStroke{}) } else { - g.app.Ops(cs.OpFillStroke{}) + g.stream.Ops(cs.OpFillStroke{}) } } else if fill { if evenOdd { - g.app.Ops(cs.OpEOFill{}) + g.stream.Ops(cs.OpEOFill{}) } else { - g.app.Ops(cs.OpFill{}) + g.stream.Ops(cs.OpFill{}) } } else if stroke { - g.app.Ops(cs.OpStroke{}) + g.stream.Ops(cs.OpStroke{}) } else { - g.app.Ops(cs.OpEndPath{}) + g.stream.Ops(cs.OpEndPath{}) } } // Begin a new sub-path. // After this call the current point will be “(x, y)“. func (g *group) MoveTo(x fl, y fl) { - g.app.Ops(cs.OpMoveTo{X: x, Y: y}) + g.stream.Ops(cs.OpMoveTo{X: x, Y: y}) } // Adds a line to the path from the current point @@ -319,18 +327,18 @@ func (g *group) MoveTo(x fl, y fl) { // After this call the current point will be “(x, y)“. // A current point must be defined before using this method. func (g *group) LineTo(x fl, y fl) { - g.app.Ops(cs.OpLineTo{X: x, Y: y}) + g.stream.Ops(cs.OpLineTo{X: x, Y: y}) } // Add cubic Bézier curve to current path. // The curve shall extend to “(x3, y3)“ using “(x1, y1)“ and “(x2, // y2)“ as the Bézier control points. func (g *group) CubicTo(x1, y1, x2, y2, x3, y3 fl) { - g.app.Ops(cs.OpCubicTo{X1: x1, Y1: y1, X2: x2, Y2: y2, X3: x3, Y3: y3}) + g.stream.Ops(cs.OpCubicTo{X1: x1, Y1: y1, X2: x2, Y2: y2, X3: x3, Y3: y3}) } // ClosePath close the current path, which will apply line join style. -func (g *group) ClosePath() { g.app.Ops(cs.OpClosePath{}) } +func (g *group) ClosePath() { g.stream.Ops(cs.OpClosePath{}) } // DrawRasterImage draws the given image at the current point func (g *group) DrawRasterImage(img backend.RasterImage, width fl, height fl) { @@ -347,7 +355,7 @@ func (g *group) DrawRasterImage(img backend.RasterImage, width fl, height fl) { g.images[img.ID] = obj } - g.app.AddXObjectDims(obj, 0, height, width, -height) + g.stream.AddXObjectDims(obj, 0, height, width, -height) } // DrawGradient draws the given gradient at the current point. @@ -383,5 +391,5 @@ func (g *group) DrawGradient(layout backend.GradientLayout, width fl, height fl) g.drawMask(&alphaStream) } - g.app.Shading(sh) + g.stream.Shading(sh) } diff --git a/pdf/pdf.go b/pdf/pdf.go index d111241..d44a374 100644 --- a/pdf/pdf.go +++ b/pdf/pdf.go @@ -18,7 +18,7 @@ var ( ) // may be set to false when debugging -const compressStreams = true +const compressStreams = false type fontContent struct { content []byte diff --git a/pdf/pdf_svg_test.go b/pdf/pdf_svg_test.go index 843c518..5bb7afe 100644 --- a/pdf/pdf_svg_test.go +++ b/pdf/pdf_svg_test.go @@ -21,7 +21,7 @@ func drawStandaloneSVG(t *testing.T, input string, outFile string) { var out model.Document var page model.PageObject - dst.app.ApplyToPageObject(&page, false) + dst.stream.ApplyToPageObject(&page, false) out.Catalog.Pages.Kids = append(out.Catalog.Pages.Kids, &page) if err := out.WriteFile(outFile, nil); err != nil { diff --git a/pdf/pdf_test.go b/pdf/pdf_test.go index bd1f75e..c182a06 100644 --- a/pdf/pdf_test.go +++ b/pdf/pdf_test.go @@ -200,7 +200,7 @@ func TestBookmarks4(t *testing.T) { pdf := htmlToBytes(t, `

1

2

diff --git a/pdf/text.go b/pdf/text.go index a5b9d59..52731fc 100644 --- a/pdf/text.go +++ b/pdf/text.go @@ -14,7 +14,6 @@ import ( "github.com/benoitkugler/pdf/fonts/cmaps" "github.com/benoitkugler/pdf/model" "github.com/benoitkugler/webrender/backend" - "github.com/benoitkugler/webrender/matrix" "github.com/benoitkugler/webrender/text" drawText "github.com/benoitkugler/webrender/text/draw" "github.com/go-text/typesetting/opentype/api" @@ -42,20 +41,17 @@ func (g *group) SetTextPaint(op backend.PaintOp) { } else { tr = 3 } - g.app.Ops(contentstream.OpSetTextRender{Render: tr}) + g.stream.Ops(contentstream.OpSetTextRender{Render: tr}) } // DrawText draws the given text using the current fill color. func (g *group) DrawText(texts []backend.TextDrawing) { - g.app.BeginText() - defer g.app.EndText() + g.stream.BeginText() + defer g.stream.EndText() for _, text := range texts { - mat := matrix.New(text.FontSize, 0, 0, -text.FontSize, text.X, text.Y) - if text.Angle != 0 { // avoid useless multiplication if angle == 0 - mat.RightMultBy(matrix.Rotation(text.Angle)) - } - g.app.SetTextMatrix(mat.A, mat.B, mat.C, mat.D, mat.E, mat.F) + mat := text.Matrix() + g.stream.SetTextMatrix(mat.A, mat.B, mat.C, mat.D, mat.E, mat.F) for _, run := range text.Runs { pf := g.fonts[run.Font] @@ -64,7 +60,7 @@ func (g *group) DrawText(texts []backend.TextDrawing) { useFont := g.cache.fontFiles[run.Font.Origin()].isSupported if useFont { - g.app.SetFontAndSize(pdfFonts.BuiltFont{Meta: pf.FontDict}, 1) + g.stream.SetFontAndSize(pdfFonts.BuiltFont{Meta: pf.FontDict}, text.FontSize) } var out []contentstream.SpacedGlyph @@ -82,7 +78,7 @@ func (g *group) DrawText(texts []backend.TextDrawing) { } if useFont { - g.app.Ops(contentstream.OpShowSpaceGlyph{Glyphs: out}) + g.stream.Ops(contentstream.OpShowSpaceGlyph{Glyphs: out}) } } } @@ -184,7 +180,7 @@ func cidWidths(dict map[backend.GID]backend.GlyphExtents) []model.CIDWidth { return widths } -// returns true if a valid 'glyf' or 'cff ' tables is present +// returns true if a valid 'glyf' , 'cff ' 'or' tables is present func isSupportedFont(content []byte) bool { ld, err := loader.NewLoader(bytes.NewReader(content)) if err != nil { @@ -216,7 +212,10 @@ func isSupportedFont(content []byte) bool { hasValidGlyf = len(glyf) > 0 } hasCff := ld.HasTable(loader.MustNewTag("CFF ")) - return hasValidGlyf || hasCff + + hasBitmap := ld.HasTable(loader.MustNewTag("EBDT")) && ld.HasTable(loader.MustNewTag("EBLC")) + + return hasValidGlyf || hasCff || hasBitmap } func newFontFile(fontDesc backend.FontDescription, font pdfFont, content []byte) *model.FontFile { @@ -244,6 +243,167 @@ func newFontFile(fontDesc backend.FontDescription, font pdfFont, content []byte) return fs } +// TODO: see https://github.com/benoitkugler/webrender/issues/3 +// // https://docs.microsoft.com/typography/opentype/spec/ebdt +// func buildBitmapFontDictionary( pdf, font, widths, +// compress_pdf, subset) (font_dictionary model.FontType3) { +// font_dictionary.FontBBox = model.Rectangle{0, 0, 1, 1} +// font_dictionary.FontMatrix = model.Matrix{1, 0, 0, 1, 0, 0} +// if subset{ +// chars = tuple(sorted(font.cmap)) +// } else{ +// chars = tuple([]int{256})} +// first, last = chars[0], chars[-1] +// font_dictionary.FirstChar = first +// // font_dictionary.LastChar = last +// var differences []int +// // for index, index_widths in zip(widths[::2], widths[1::2]): +// // differences.append(index) +// // for i in range(len(index_widths)): +// // if i + index in chars: +// // differences.append(f'/{i + index}') +// // font_dictionary.Encoding = pydyf.Dictionary({ 'Type': '/Encoding', 'Differences': pydyf.Array(differences), }) +// // char_procs = pydyf.Dictionary({}) +// font_glyphs = font.ttfont["EBDT"].strikeData[0] +// widths := make([]int, (last - first + 1)) +// glyphs_info = map[int]int{} +// for key, glyph := range font_glyphs { +// glyph_format = glyph.getFormat() +// glyph_id = font.ttfont.getGlyphID(key) + +// // Get and store glyph metrics +// if glyph_format == 5{ +// data = glyph.data +// subtables = font.ttfont["EBLC"].strikes[0].indexSubTables +// for subtable in subtables: +// first_index = subtable.firstGlyphIndex +// last_index = subtable.lastGlyphIndex +// if first_index <= glyph_id <= last_index: +// height = subtable.metrics.height +// advance = width = subtable.metrics.width +// bearing_x = subtable.metrics.horiBearingX +// bearing_y = subtable.metrics.horiBearingY +// break +// else: +// LOGGER.warning(f"Unknown bitmap metrics for glyph: {glyph_id}") +// continue +// }else{ +// data_start = 5 if glyph_format in (1, 2, 8) else 8 +// data = glyph.data[data_start:] +// height, width = glyph.data[0:2] +// bearing_x = int.from_bytes(glyph.data[2:3], "big", signed=True) +// bearing_y = int.from_bytes(glyph.data[3:4], "big", signed=True) +// advance = glyph.data[4]} +// position_y = bearing_y - height +// if glyph_id in chars{ +// widths[glyph_id - first] = advance} +// stride = ceil(width / 8) +// glyph_info = glyphs_info[glyph_id] = { +// "width": width, +// "height": height, +// "x": bearing_x, +// "y": position_y, +// "stride": stride, +// "bitmap": None, +// "subglyphs": None, +// } + +// // Decode bitmaps +// if 0 in (width, height) or not data{ +// glyph_info["bitmap"] = b""} +// elif glyph_format in (1, 6): +// glyph_info["bitmap"] = data +// elif glyph_format in (2, 5, 7): +// padding = (8 - (width % 8)) % 8 +// bits = bin(int(data.hex(), 16))[2:] +// bits = bits.zfill(8 * len(data)) +// bitmap_bits = ''.join( +// bits[i * width:(i + 1) * width] + padding * '0' +// for i in range(height)) +// glyph_info['bitmap'] = int(bitmap_bits, 2).to_bytes( +// height * stride, 'big') +// elif glyph_format in (8, 9): +// subglyphs = glyph_info['subglyphs'] = [] +// i = 0 if glyph_format == 9 else 1 +// number_of_components = int.from_bytes(data[i:i+2], 'big') +// for j in range(number_of_components): +// index = (i + 2) + (j * 4) +// subglyph_id = int.from_bytes(data[index:index+2], 'big') +// x = int.from_bytes(data[index+2:index+3], 'big', signed=True) +// y = int.from_bytes(data[index+3:index+4], 'big', signed=True) +// subglyphs.append({'id': subglyph_id, 'x': x, 'y': y}) +// else: // pragma: no cover +// LOGGER.warning(f'Unsupported bitmap glyph format: {glyph_format}') +// glyph_info['bitmap'] = bytes(height * stride) +// } +// for glyph_id, glyph_info in glyphs_info.items(): +// // Don’t store glyph not in cmap +// if glyph_id not in chars: +// continue + +// // Draw glyph +// stride = glyph_info['stride'] +// width = glyph_info['width'] +// height = glyph_info['height'] +// x = glyph_info['x'] +// y = glyph_info['y'] +// if glyph_info['bitmap'] is None: +// length = height * stride +// bitmap_int = int.from_bytes(bytes(length), 'big') +// for subglyph in glyph_info['subglyphs']: +// sub_x = subglyph['x'] +// sub_y = subglyph['y'] +// sub_id = subglyph['id'] +// if sub_id not in glyphs_info: +// LOGGER.warning(f'Unknown subglyph: {sub_id}') +// continue +// subglyph = glyphs_info[sub_id] +// if subglyph['bitmap'] is None: +// // TODO: support subglyph in subglyph +// LOGGER.warning( +// f'Unsupported subglyph in subglyph: {sub_id}') +// continue +// for row_y in range(subglyph['height']): +// row_slice = slice( +// row_y * subglyph['stride'], +// (row_y + 1) * subglyph['stride']) +// row = subglyph['bitmap'][row_slice] +// row_int = int.from_bytes(row, 'big') +// shift = stride * 8 * (height - sub_y - row_y - 1) +// stride_difference = stride - subglyph['stride'] +// if stride_difference > 0: +// row_int <<= stride_difference * 8 +// elif stride_difference < 0: +// row_int >>= -stride_difference * 8 +// if sub_x > 0: +// row_int >>= sub_x +// elif sub_x < 0: +// row_int <<= -sub_x +// row_int %= 1 << stride * 8 +// row_int <<= shift +// bitmap_int |= row_int +// bitmap = bitmap_int.to_bytes(length, 'big') +// else: +// bitmap = glyph_info['bitmap'] +// bitmap_stream = pydyf.Stream([ +// b'0 0 d0', +// f'{width} 0 0 {height} {x} {y} cm'.encode(), +// b'BI', +// b'/IM true', +// b'/W', width, +// b'/H', height, +// b'/BPC 1', +// b'/D [1 0]', +// b'ID', bitmap, b'EI' +// ], compress=compress_pdf) +// pdf.add_object(bitmap_stream) +// char_procs[glyph_id] = bitmap_stream.reference + +// pdf.add_object(char_procs) +// font_dictionary['Widths'] = pydyf.Array(widths) +// font_dictionary['CharProcs'] = char_procs.reference +// } + // post-process the font used func (c *Output) writeFonts() { for bFont, font := range c.cache.fonts { diff --git a/resources_test/border.svg b/resources_test/border.svg new file mode 100644 index 0000000..3da4da4 --- /dev/null +++ b/resources_test/border.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/resources_test/border2.svg b/resources_test/border2.svg new file mode 100644 index 0000000..1a6458c --- /dev/null +++ b/resources_test/border2.svg @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources_test/pattern-transparent.svg b/resources_test/pattern-transparent.svg new file mode 100644 index 0000000..905bb52 --- /dev/null +++ b/resources_test/pattern-transparent.svg @@ -0,0 +1,3 @@ + + +
abc