mirror of
https://pdfium.googlesource.com/pdfium
synced 2026-08-01 10:55:12 +08:00
Decouple render device instantiation from fxcodec by moving the EncoderIface definition and registration into CFX_GEModule. Centralizing encoder registration in CFX_GEModule during library startup decouples render devices from fxcodec implementation details and eliminates layering violations. The benefits of this become clear in follow-up CLs. Register encoders once during library initialization via fxcodec::RegisterEncoders(). Render devices retrieve the encoder interface directly from CFX_GEModule when needed. TAG=agy CONV=95a2f3dd-7384-4cff-9247-9f9d201c4a25 Change-Id: Ia22f60c6a83d1c283696e6db18053fd2db3809fa Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/150990 Reviewed-by: Lei Zhang <thestig@chromium.org> Commit-Queue: Tom Sepez <tsepez@chromium.org>
217 lines
5.9 KiB
C++
217 lines
5.9 KiB
C++
// Copyright 2021 The PDFium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "core/fxge/win32/cfx_psrenderer.h"
|
|
|
|
#include <optional>
|
|
#include <utility>
|
|
|
|
#include "core/fxcrt/bytestring.h"
|
|
#include "core/fxcrt/data_vector.h"
|
|
#include "core/fxcrt/fx_coordinates.h"
|
|
#include "core/fxcrt/fx_stream.h"
|
|
#include "core/fxcrt/retain_ptr.h"
|
|
#include "core/fxcrt/span.h"
|
|
#include "core/fxge/cfx_gemodule.h"
|
|
#include "core/fxge/dib/cfx_dibitmap.h"
|
|
#include "core/fxge/dib/fx_dib.h"
|
|
#include "core/fxge/win32/cfx_psfonttracker.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace {
|
|
|
|
DataVector<uint8_t> FakeA85Encode(pdfium::span<const uint8_t> src_span) {
|
|
return DataVector<uint8_t>({'d', 'u', 'm', 'm', 'y', 'a', '8', '5'});
|
|
}
|
|
|
|
class TestWriteStream final : public IFX_RetainableWriteStream {
|
|
public:
|
|
CONSTRUCT_VIA_MAKE_RETAIN;
|
|
|
|
// IFX_RetainableWriteStream:
|
|
bool WriteBlock(pdfium::span<const uint8_t> buffer) override {
|
|
data_.insert(data_.end(), buffer.begin(), buffer.end());
|
|
return true;
|
|
}
|
|
|
|
pdfium::span<const uint8_t> GetSpan() const { return data_; }
|
|
|
|
private:
|
|
DataVector<uint8_t> data_;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
TEST(PSRendererTest, GenerateType42SfntData) {
|
|
std::optional<ByteString> result;
|
|
|
|
result = CFX_PSRenderer::GenerateType42SfntDataForTesting("empty", {});
|
|
EXPECT_FALSE(result.has_value());
|
|
|
|
static constexpr uint8_t kOddByteCountTestData[] = {0, 32, 55};
|
|
static constexpr char kExpectedOddByteCountResult[] = R"(/odd_sfnts [
|
|
<
|
|
002037
|
|
>
|
|
] def
|
|
)";
|
|
result = CFX_PSRenderer::GenerateType42SfntDataForTesting(
|
|
"odd", kOddByteCountTestData);
|
|
ASSERT_TRUE(result.has_value());
|
|
EXPECT_EQ(kExpectedOddByteCountResult, result.value());
|
|
|
|
// Requires padding.
|
|
static constexpr uint8_t kEvenByteCountTestData[] = {0, 32, 66, 77};
|
|
static constexpr char kExpectedEvenByteCountResult[] = R"(/even_sfnts [
|
|
<
|
|
0020424D00
|
|
>
|
|
] def
|
|
)";
|
|
result = CFX_PSRenderer::GenerateType42SfntDataForTesting(
|
|
"even", kEvenByteCountTestData);
|
|
ASSERT_TRUE(result.has_value());
|
|
EXPECT_EQ(kExpectedEvenByteCountResult, result.value());
|
|
}
|
|
|
|
TEST(PSRendererTest, GenerateType42FontDictionary) {
|
|
ByteString result;
|
|
|
|
static constexpr char kExpected1DescendantFontResult[] = R"(8 dict begin
|
|
/FontType 42 def
|
|
/FontMatrix [1 0 0 1 0 0] def
|
|
/FontName /1descendant_0 def
|
|
/Encoding 3 array
|
|
dup 0 /c00 put
|
|
dup 1 /c01 put
|
|
dup 2 /c02 put
|
|
readonly def
|
|
/FontBBox [1 2 3 4] def
|
|
/PaintType 0 def
|
|
/CharStrings 4 dict dup begin
|
|
/.notdef 0 def
|
|
/c00 0 def
|
|
/c01 1 def
|
|
/c02 2 def
|
|
end readonly def
|
|
/sfnts 1descendant_sfnts def
|
|
FontName currentdict end definefont pop
|
|
6 dict begin
|
|
/FontName /1descendant def
|
|
/FontType 0 def
|
|
/FontMatrix [1 0 0 1 0 0] def
|
|
/FMapType 2 def
|
|
/Encoding [
|
|
0
|
|
] def
|
|
/FDepVector [
|
|
/1descendant_0 findfont
|
|
] def
|
|
FontName currentdict end definefont pop
|
|
%%EndResource
|
|
)";
|
|
result = CFX_PSRenderer::GenerateType42FontDictionaryForTesting(
|
|
"1descendant", FX_RECT(1, 2, 3, 4), /*num_glyphs=*/3,
|
|
/*glyphs_per_descendant_font=*/3);
|
|
EXPECT_EQ(kExpected1DescendantFontResult, result);
|
|
|
|
static constexpr char kExpected2DescendantFontResult[] = R"(8 dict begin
|
|
/FontType 42 def
|
|
/FontMatrix [1 0 0 1 0 0] def
|
|
/FontName /2descendant_0 def
|
|
/Encoding 3 array
|
|
dup 0 /c00 put
|
|
dup 1 /c01 put
|
|
dup 2 /c02 put
|
|
readonly def
|
|
/FontBBox [12 -5 34 199] def
|
|
/PaintType 0 def
|
|
/CharStrings 4 dict dup begin
|
|
/.notdef 0 def
|
|
/c00 0 def
|
|
/c01 1 def
|
|
/c02 2 def
|
|
end readonly def
|
|
/sfnts 2descendant_sfnts def
|
|
FontName currentdict end definefont pop
|
|
8 dict begin
|
|
/FontType 42 def
|
|
/FontMatrix [1 0 0 1 0 0] def
|
|
/FontName /2descendant_1 def
|
|
/Encoding 3 array
|
|
dup 0 /c00 put
|
|
dup 1 /c01 put
|
|
readonly def
|
|
/FontBBox [12 -5 34 199] def
|
|
/PaintType 0 def
|
|
/CharStrings 4 dict dup begin
|
|
/.notdef 0 def
|
|
/c00 3 def
|
|
/c01 4 def
|
|
end readonly def
|
|
/sfnts 2descendant_sfnts def
|
|
FontName currentdict end definefont pop
|
|
6 dict begin
|
|
/FontName /2descendant def
|
|
/FontType 0 def
|
|
/FontMatrix [1 0 0 1 0 0] def
|
|
/FMapType 2 def
|
|
/Encoding [
|
|
0
|
|
1
|
|
] def
|
|
/FDepVector [
|
|
/2descendant_0 findfont
|
|
/2descendant_1 findfont
|
|
] def
|
|
FontName currentdict end definefont pop
|
|
%%EndResource
|
|
)";
|
|
result = CFX_PSRenderer::GenerateType42FontDictionaryForTesting(
|
|
"2descendant", FX_RECT(12, -5, 34, 199), /*num_glyphs=*/5,
|
|
/*glyphs_per_descendant_font=*/3);
|
|
EXPECT_EQ(kExpected2DescendantFontResult, result);
|
|
}
|
|
|
|
TEST(PSRendererTest, DrawDIBits) {
|
|
static constexpr char kExpectedOutput[] = R"(
|
|
save
|
|
/im/initmatrix load def
|
|
/n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load def/h/closepath load def
|
|
/f/fill load def/F/eofill load def/s/stroke load def/W/clip load def/W*/eoclip load def
|
|
/rg/setrgbcolor load def/k/setcmykcolor load def
|
|
/J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load def/M/setmiterlimit load def/d/setdash load def
|
|
/q/gsave load def/Q/grestore load def/iM/imagemask load def
|
|
/Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont load def
|
|
/cm/concat load def/Cm/currentmatrix load def/mx/matrix load def/sm/setmatrix load def
|
|
q
|
|
[1 0 0 1 0 0]cm 10 2 1[10 0 0 -2 0 2]currentfile/ASCII85Decode filter false 1 colorimage
|
|
dummya85
|
|
Q
|
|
|
|
restore
|
|
)";
|
|
auto output_stream = pdfium::MakeRetain<TestWriteStream>();
|
|
|
|
{
|
|
static constexpr int kWidth = 10;
|
|
static constexpr int kHeight = 2;
|
|
CFX_PSFontTracker font_tracker;
|
|
const EncoderIface encoder_interface{&FakeA85Encode, nullptr, nullptr,
|
|
nullptr, nullptr};
|
|
CFX_PSRenderer renderer(&font_tracker, &encoder_interface);
|
|
renderer.Init(output_stream, CFX_PSRenderer::RenderingLevel::kLevel2,
|
|
kWidth, kHeight);
|
|
|
|
auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
|
|
bool result = bitmap->Create(kWidth, kHeight, FXDIB_Format::k1bppRgb);
|
|
ASSERT_TRUE(result);
|
|
ASSERT_TRUE(renderer.DrawDIBits(std::move(bitmap), /*color=*/0,
|
|
CFX_Matrix(), FXDIB_ResampleOptions()));
|
|
}
|
|
|
|
auto output = ByteString(ByteStringView(output_stream->GetSpan()));
|
|
EXPECT_EQ(output, kExpectedOutput);
|
|
}
|