// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/entity/contents/text_contents.h"

#include <cstring>
#include <optional>
#include <utility>

#include "impeller/core/buffer_view.h"
#include "impeller/core/formats.h"
#include "impeller/core/sampler_descriptor.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/entity.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/point.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/typographer/glyph_atlas.h"
#include "impeller/typographer/lazy_glyph_atlas.h"

namespace impeller {

TextContents::TextContents() = default;

TextContents::~TextContents() = default;

void TextContents::SetTextFrame(const std::shared_ptr<TextFrame>& frame) {
  frame_ = frame;
}

void TextContents::SetColor(Color color) {
  color_ = color;
}

Color TextContents::GetColor() const {
  return color_.WithAlpha(color_.alpha * inherited_opacity_);
}

bool TextContents::CanInheritOpacity(const Entity& entity) const {
  // Computing whether or not opacity can be inherited requires determining if
  // any glyphs can overlap exactly. While this was previously implemented
  // via TextFrame::MaybeHasOverlapping, this code relied on scaling up text
  // bounds for a size specified at 1.0 DPR, which was not accurate at
  // higher or lower DPRs. Rather than re-implement the checks to compute exact
  // glyph bounds, for now this optimization has been disabled for Text.
  return false;
}

void TextContents::SetInheritedOpacity(Scalar opacity) {
  inherited_opacity_ = opacity;
}

void TextContents::SetOffset(Vector2 offset) {
  offset_ = offset;
}

void TextContents::SetForceTextColor(bool value) {
  force_text_color_ = value;
}

std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
  return frame_->GetBounds().TransformBounds(entity.GetTransform());
}

void TextContents::PopulateGlyphAtlas(
    const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
    Scalar scale) {
  lazy_glyph_atlas->AddTextFrame(*frame_, scale, offset_, properties_);
  scale_ = scale;
}

void TextContents::SetTextProperties(Color color,
                                     bool stroke,
                                     Scalar stroke_width,
                                     Cap stroke_cap,
                                     Join stroke_join,
                                     Scalar stroke_miter) {
  if (frame_->HasColor()) {
    // Alpha is always applied when rendering, remove it here so
    // we do not double-apply the alpha.
    properties_.color = color.WithAlpha(1.0);
  }
  if (stroke) {
    properties_.stroke = true;
    properties_.stroke_width = stroke_width;
    properties_.stroke_cap = stroke_cap;
    properties_.stroke_join = stroke_join;
    properties_.stroke_miter = stroke_miter;
  }
}

bool TextContents::Render(const ContentContext& renderer,
                          const Entity& entity,
                          RenderPass& pass) const {
  auto color = GetColor();
  if (color.IsTransparent()) {
    return true;
  }

  auto type = frame_->GetAtlasType();
  const std::shared_ptr<GlyphAtlas>& atlas =
      renderer.GetLazyGlyphAtlas()->CreateOrGetGlyphAtlas(
          *renderer.GetContext(), renderer.GetTransientsBuffer(), type);

  if (!atlas || !atlas->IsValid()) {
    VALIDATION_LOG << "Cannot render glyphs without prepared atlas.";
    return false;
  }

  // Information shared by all glyph draw calls.
  pass.SetCommandLabel("TextFrame");
  auto opts = OptionsFromPassAndEntity(pass, entity);
  opts.primitive_type = PrimitiveType::kTriangle;
  pass.SetPipeline(renderer.GetGlyphAtlasPipeline(opts));

  using VS = GlyphAtlasPipeline::VertexShader;
  using FS = GlyphAtlasPipeline::FragmentShader;

  // Common vertex uniforms for all glyphs.
  VS::FrameInfo frame_info;
  frame_info.mvp =
      Entity::GetShaderTransform(entity.GetShaderClipDepth(), pass, Matrix());
  ISize atlas_size = atlas->GetTexture()->GetSize();
  bool is_translation_scale = entity.GetTransform().IsTranslationScaleOnly();
  Matrix entity_transform = entity.GetTransform();
  Matrix basis_transform = entity_transform.Basis();

  VS::BindFrameInfo(pass,
                    renderer.GetTransientsBuffer().EmplaceUniform(frame_info));

  FS::FragInfo frag_info;
  frag_info.use_text_color = force_text_color_ ? 1.0 : 0.0;
  frag_info.text_color = ToVector(color.Premultiply());
  frag_info.is_color_glyph = type == GlyphAtlas::Type::kColorBitmap;

  FS::BindFragInfo(pass,
                   renderer.GetTransientsBuffer().EmplaceUniform(frag_info));

  SamplerDescriptor sampler_desc;
  if (is_translation_scale) {
    sampler_desc.min_filter = MinMagFilter::kNearest;
    sampler_desc.mag_filter = MinMagFilter::kNearest;
  } else {
    // Currently, we only propagate the scale of the transform to the atlas
    // renderer, so if the transform has more than just a translation, we turn
    // on linear sampling to prevent crunchiness caused by the pixel grid not
    // being perfectly aligned.
    // The downside is that this slightly over-blurs rotated/skewed text.
    sampler_desc.min_filter = MinMagFilter::kLinear;
    sampler_desc.mag_filter = MinMagFilter::kLinear;
  }

  // No mipmaps for glyph atlas (glyphs are generated at exact scales).
  sampler_desc.mip_filter = MipFilter::kBase;

  FS::BindGlyphAtlasSampler(
      pass,                 // command
      atlas->GetTexture(),  // texture
      renderer.GetContext()->GetSamplerLibrary()->GetSampler(
          sampler_desc)  // sampler
  );

  // Common vertex information for all glyphs.
  // All glyphs are given the same vertex information in the form of a
  // unit-sized quad. The size of the glyph is specified in per instance data
  // and the vertex shader uses this to size the glyph correctly. The
  // interpolated vertex information is also used in the fragment shader to
  // sample from the glyph atlas.

  constexpr std::array<Point, 6> unit_points = {Point{0, 0}, Point{1, 0},
                                                Point{0, 1}, Point{1, 0},
                                                Point{0, 1}, Point{1, 1}};

  auto& host_buffer = renderer.GetTransientsBuffer();
  size_t vertex_count = 0;
  for (const auto& run : frame_->GetRuns()) {
    vertex_count += run.GetGlyphPositions().size();
  }
  vertex_count *= 6;

  BufferView buffer_view = host_buffer.Emplace(
      vertex_count * sizeof(VS::PerVertexData), alignof(VS::PerVertexData),
      [&](uint8_t* contents) {
        VS::PerVertexData vtx;
        VS::PerVertexData* vtx_contents =
            reinterpret_cast<VS::PerVertexData*>(contents);
        size_t i = 0u;
        for (const TextRun& run : frame_->GetRuns()) {
          const Font& font = run.GetFont();
          Scalar rounded_scale = TextFrame::RoundScaledFontSize(
              scale_, font.GetMetrics().point_size);
          const FontGlyphAtlas* font_atlas =
              atlas->GetFontGlyphAtlas(font, rounded_scale);
          if (!font_atlas) {
            VALIDATION_LOG << "Could not find font in the atlas.";
            continue;
          }

          // Adjust glyph position based on the subpixel rounding
          // used by the font.
          Point subpixel_adjustment(0.5, 0.5);
          switch (font.GetAxisAlignment()) {
            case AxisAlignment::kNone:
              break;
            case AxisAlignment::kX:
              subpixel_adjustment.x = 0.125;
              break;
            case AxisAlignment::kY:
              subpixel_adjustment.y = 0.125;
              break;
            case AxisAlignment::kAll:
              subpixel_adjustment.x = 0.125;
              subpixel_adjustment.y = 0.125;
              break;
          }

          Point screen_offset = (entity_transform * Point(0, 0));
          for (const TextRun::GlyphPosition& glyph_position :
               run.GetGlyphPositions()) {
            // Note: uses unrounded scale for more accurate subpixel position.
            Point subpixel = TextFrame::ComputeSubpixelPosition(
                glyph_position, font.GetAxisAlignment(), offset_, scale_);
            std::optional<std::pair<Rect, Rect>> maybe_atlas_glyph_bounds =
                font_atlas->FindGlyphBounds(
                    SubpixelGlyph{glyph_position.glyph, subpixel, properties_});
            if (!maybe_atlas_glyph_bounds.has_value()) {
              VALIDATION_LOG << "Could not find glyph position in the atlas.";
              continue;
            }
            const Rect& atlas_glyph_bounds =
                maybe_atlas_glyph_bounds.value().first;
            Rect glyph_bounds = maybe_atlas_glyph_bounds.value().second;
            // For each glyph, we compute two rectangles. One for the vertex
            // positions and one for the texture coordinates (UVs). The atlas
            // glyph bounds are used to compute UVs in cases where the
            // destination and source sizes may differ due to clamping the sizes
            // of large glyphs.
            Point uv_origin =
                (atlas_glyph_bounds.GetLeftTop() - Point(0.5, 0.5)) /
                atlas_size;
            Point uv_size =
                (atlas_glyph_bounds.GetSize() + Point(1, 1)) / atlas_size;

            Point unrounded_glyph_position =
                (basis_transform * glyph_position.position) +
                glyph_bounds.GetLeftTop();
            Point screen_glyph_position =
                (screen_offset + unrounded_glyph_position + subpixel_adjustment)
                    .Floor();

            Size scaled_size = glyph_bounds.GetSize();
            for (const Point& point : unit_points) {
              Point position;
              if (is_translation_scale) {
                position = screen_glyph_position + (point * scaled_size);
              } else {
                Rect scaled_bounds = glyph_bounds.Scale(1.0 / rounded_scale);
                position = entity_transform * (glyph_position.position +
                                               scaled_bounds.GetLeftTop() +
                                               point * scaled_bounds.GetSize());
              }
              vtx.uv = uv_origin + (uv_size * point);
              vtx.position = position;
              vtx_contents[i++] = vtx;
            }
          }
        }
      });

  pass.SetVertexBuffer({
      .vertex_buffer = std::move(buffer_view),
      .index_buffer = {},
      .vertex_count = vertex_count,
      .index_type = IndexType::kNone,
  });

  return pass.Draw().ok();
}

}  // namespace impeller
