chromium/ui/base/resource/resource_bundle.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "ui/base/resource/resource_bundle.h"

#include <stdint.h>

#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/debug/alias.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted_memory.h"
#include "base/notreached.h"
#include "base/numerics/byte_conversions.h"
#include "base/numerics/safe_conversions.h"
#include "base/path_service.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/base_tracing.h"
#include "build/build_config.h"
#include "net/filter/gzip_header.h"
#include "skia/ext/image_operations.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "third_party/brotli/include/brotli/decode.h"
#include "third_party/skia/include/codec/SkPngDecoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/zlib/google/compression_utils.h"
#include "ui/base/buildflags.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/data_pack.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/strings/grit/app_locale_settings.h"
#include "url/gurl.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "ui/base/resource/resource_bundle_android.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "ui/gfx/platform_font_skia.h"
#endif

#if BUILDFLAG(IS_WIN)
#include "ui/display/win/dpi.h"

// To avoid conflicts with the macro from the Windows SDK...
#undef LoadBitmap
#endif

namespace ui {

namespace {

// PNG-related constants.
const uint8_t kPngMagic[8] =;
const size_t kPngChunkMetadataSize =;  // length, type, crc32
const unsigned char kPngScaleChunkType[4] =;
const unsigned char kPngDataChunkType[4] =;

#if !BUILDFLAG(IS_APPLE)
const char kPakFileExtension[] =;
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
// Pointers to the functions |lottie::ParseLottieAsStillImage| and
// |lottie::ParseLottieAsThemedStillImage|, so that dependencies used by those
// functions do not need to be included directly in ui/base.
ResourceBundle::LottieImageParseFunction g_parse_lottie_as_still_image_ =
    nullptr;
ResourceBundle::LottieThemedImageParseFunction
    g_parse_lottie_as_themed_still_image_ = nullptr;
#endif

ResourceBundle* g_shared_instance_ =;

#if !BUILDFLAG(IS_CHROMEOS_LACROS)
base::FilePath GetResourcesPakFilePath(const std::string& pak_name) {}
#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)

SkBitmap CreateEmptyBitmap() {}

// Helper function for determining whether a resource is gzipped.
bool HasGzipHeader(std::string_view data) {}

// Helper function for determining whether a resource is brotli compressed.
bool HasBrotliHeader(std::string_view data) {}

// Returns the uncompressed size of Brotli compressed |input| from header.
size_t GetBrotliDecompressSize(std::string_view input) {}

OutputBufferType;

// Returns a span of the given length that writes into `out_buf`.
base::span<uint8_t> GetBufferForWriting(OutputBufferType out_buf, size_t len) {}

// Decompresses data in |input| using brotli, storing
// the result in |output|, which is resized as necessary. Returns true for
// success. To be used for grit compressed resources only.
bool BrotliDecompress(std::string_view input, OutputBufferType output) {}

// Helper function for decompressing resource.
void DecompressIfNeeded(std::string_view data, OutputBufferType output) {}

}  // namespace

// A descendant of |gfx::ImageSkiaSource| that loads a bitmap image for the
// requested scale factor from |ResourceBundle| on demand for a given
// |resource_id|. If the bitmap for the requested scale factor does not exist,
// it will return the 1x bitmap scaled by the scale factor. This may lead to
// broken UI if the correct size of the scaled image is not exactly
// |scale_factor| * the size of the 1x bitmap. When
// --highlight-missing-scaled-resources flag is specified, scaled 1x bitmaps are
// highlighted by blending them with red.
class ResourceBundle::BitmapImageSource : public gfx::ImageSkiaSource {};

ResourceBundle::FontDetails::FontDetails(std::string typeface,
                                         int size_delta,
                                         gfx::Font::Weight weight)
    :{}

bool ResourceBundle::FontDetails::operator==(const FontDetails& rhs) const {}

bool ResourceBundle::FontDetails::operator<(const FontDetails& rhs) const {}

// static
std::string ResourceBundle::InitSharedInstanceWithLocale(
    const std::string& pref_locale,
    Delegate* delegate,
    LoadResources load_resources) {}

// static
void ResourceBundle::InitSharedInstanceWithBuffer(
    base::span<const uint8_t> buffer,
    ResourceScaleFactor scale_factor) {}

// static
void ResourceBundle::InitSharedInstanceWithPakFileRegion(
    base::File pak_file,
    const base::MemoryMappedFile::Region& region) {}

// static
void ResourceBundle::InitSharedInstanceWithPakPath(const base::FilePath& path) {}

// static
void ResourceBundle::CleanupSharedInstance() {}

// static
ResourceBundle* ResourceBundle::SwapSharedInstanceForTesting(
    ResourceBundle* instance) {}

// static
bool ResourceBundle::HasSharedInstance() {}

// static
ResourceBundle& ResourceBundle::GetSharedInstance() {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
// static
void ResourceBundle::SetLottieParsingFunctions(
    LottieImageParseFunction parse_lottie_as_still_image,
    LottieThemedImageParseFunction parse_lottie_as_themed_still_image) {
  g_parse_lottie_as_still_image_ = parse_lottie_as_still_image;
  g_parse_lottie_as_themed_still_image_ = parse_lottie_as_themed_still_image;
}
#endif

void ResourceBundle::LoadSecondaryLocaleDataWithPakFileRegion(
    base::File pak_file,
    const base::MemoryMappedFile::Region& region) {}

#if !BUILDFLAG(IS_ANDROID)
// static
bool ResourceBundle::LocaleDataPakExists(const std::string& locale) {}
#endif  // !BUILDFLAG(IS_ANDROID)

void ResourceBundle::AddDataPackFromPath(const base::FilePath& path,
                                         ResourceScaleFactor scale_factor) {}

void ResourceBundle::AddOptionalDataPackFromPath(
    const base::FilePath& path,
    ResourceScaleFactor scale_factor) {}

void ResourceBundle::AddDataPackFromBuffer(base::span<const uint8_t> buffer,
                                           ResourceScaleFactor scale_factor) {}

void ResourceBundle::AddDataPackFromFileRegion(
    base::File file,
    const base::MemoryMappedFile::Region& region,
    ResourceScaleFactor scale_factor) {}

#if !BUILDFLAG(IS_APPLE)
// static
base::FilePath ResourceBundle::GetLocaleFilePath(
    const std::string& app_locale) {}
#endif

#if !BUILDFLAG(IS_ANDROID)
std::string ResourceBundle::LoadLocaleResources(const std::string& pref_locale,
                                                bool crash_on_failure) {}
#endif  // !BUILDFLAG(IS_ANDROID)

void ResourceBundle::LoadTestResources(const base::FilePath& path,
                                       const base::FilePath& locale_path) {}

void ResourceBundle::UnloadLocaleResources() {}

void ResourceBundle::OverrideLocalePakForTest(const base::FilePath& pak_path) {}

void ResourceBundle::OverrideLocaleStringResource(
    int resource_id,
    const std::u16string& string) {}

const base::FilePath& ResourceBundle::GetOverriddenPakPath() const {}

std::u16string ResourceBundle::MaybeMangleLocalizedString(
    const std::u16string& str) const {}

std::string ResourceBundle::ReloadLocaleResources(
    const std::string& pref_locale) {}

gfx::ImageSkia* ResourceBundle::GetImageSkiaNamed(int resource_id) {}

gfx::Image& ResourceBundle::GetImageNamed(int resource_id) {}

std::optional<ResourceBundle::LottieData> ResourceBundle::GetLottieData(
    int resource_id) const {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
const ui::ImageModel& ResourceBundle::GetThemedLottieImageNamed(
    int resource_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Check to see if the image is already in the cache.
  auto found = image_models_.find(resource_id);
  if (found != image_models_.end())
    return found->second;

  std::optional<LottieData> data = GetLottieData(resource_id);
  CHECK(data) << "Unable to load themed Lottie image with id " << resource_id;

  // The bytes string was successfully loaded, so parse it and cache the
  // resulting image.
  auto inserted = image_models_.emplace(
      resource_id, (*g_parse_lottie_as_themed_still_image_)(std::move(*data)));
  DCHECK(inserted.second);
  return inserted.first->second;
}
#endif

constexpr uint8_t ResourceBundle::kBrotliConst[];

base::RefCountedMemory* ResourceBundle::LoadDataResourceBytes(
    int resource_id) const {}

base::RefCountedMemory* ResourceBundle::LoadDataResourceBytesForScale(
    int resource_id,
    ResourceScaleFactor scale_factor) const {}

std::string_view ResourceBundle::GetRawDataResource(int resource_id) const {}

std::string_view ResourceBundle::GetRawDataResourceForScale(
    int resource_id,
    ResourceScaleFactor scale_factor,
    ResourceScaleFactor* loaded_scale_factor) const {}

std::string ResourceBundle::LoadDataResourceString(int resource_id) const {}

std::string ResourceBundle::LoadDataResourceStringForScale(
    int resource_id,
    ResourceScaleFactor scaling_factor) const {}

std::string ResourceBundle::LoadLocalizedResourceString(int resource_id) const {}

bool ResourceBundle::IsGzipped(int resource_id) const {}

bool ResourceBundle::IsBrotli(int resource_id) const {}

std::u16string ResourceBundle::GetLocalizedString(int resource_id) {}

base::RefCountedMemory* ResourceBundle::LoadLocalizedResourceBytes(
    int resource_id) const {}

const gfx::FontList& ResourceBundle::GetFontListWithDelta(int size_delta) {}

const gfx::FontList& ResourceBundle::GetFontListForDetails(
    const FontDetails& details) {}

const gfx::FontList& ResourceBundle::GetFontList(FontStyle legacy_style) {}

const gfx::Font& ResourceBundle::GetFont(FontStyle style) {}

void ResourceBundle::ReloadFonts() {}

ResourceScaleFactor ResourceBundle::GetMaxResourceScaleFactor() const {}

void ResourceBundle::CheckCanOverrideStringResources() {}

ResourceBundle::ResourceBundle(Delegate* delegate)
    :{}

ResourceBundle::~ResourceBundle() {}

// static
void ResourceBundle::InitSharedInstance(Delegate* delegate) {}

void ResourceBundle::FreeImages() {}

#if !BUILDFLAG(IS_CHROMEOS_LACROS)
void ResourceBundle::LoadChromeResources() {}
#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)

void ResourceBundle::AddDataPackFromPathInternal(
    const base::FilePath& path,
    ResourceScaleFactor scale_factor,
    bool optional) {}

void ResourceBundle::AddResourceHandle(
    std::unique_ptr<ResourceHandle> resource_handle) {}

void ResourceBundle::InitDefaultFontList() {}

gfx::ImageSkia ResourceBundle::CreateImageSkia(int resource_id) {}

bool ResourceBundle::LoadBitmap(const ResourceHandle& data_handle,
                                int resource_id,
                                SkBitmap* bitmap,
                                bool* fell_back_to_1x) const {}

bool ResourceBundle::LoadBitmap(int resource_id,
                                ResourceScaleFactor* scale_factor,
                                SkBitmap* bitmap,
                                bool* fell_back_to_1x) const {}

gfx::Image& ResourceBundle::GetEmptyImage() {}

#if BUILDFLAG(IS_CHROMEOS_ASH)
const ui::ImageModel& ResourceBundle::GetEmptyImageModel() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  if (empty_image_model_.IsEmpty())
    empty_image_model_ = ui::ImageModel::FromImage(GetEmptyImage());
  return empty_image_model_;
}
#endif

std::u16string ResourceBundle::GetLocalizedStringImpl(int resource_id) const {}

// static
bool ResourceBundle::PNGContainsFallbackMarker(base::span<const uint8_t> buf) {}

// static
bool ResourceBundle::DecodePNG(const unsigned char* buf,
                               size_t size,
                               SkBitmap* bitmap,
                               bool* fell_back_to_1x) {}

}  // namespace ui