// 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/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());

  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.
  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>();

  {
    constexpr int kWidth = 10;
    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()));
  }

  ByteString output(output_stream->GetSpan());
  EXPECT_EQ(output, kExpectedOutput);
}
