Aegisub/src/font_file_lister.h

115 lines
3.9 KiB
C++

// Copyright (c) 2012, Thomas Goyne <plorkyeran@aegisub.org>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
// Aegisub Project http://www.aegisub.org/
/// @file font_file_lister.h
/// @see font_file_lister.cpp
/// @ingroup font_collector
///
#pragma once
#include <libaegisub/fs_fwd.h>
#include <boost/filesystem/path.hpp>
#include <functional>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <wx/string.h>
class AssDialogue;
class AssFile;
typedef std::function<void (wxString, int)> FontCollectorStatusCallback;
/// @class FontFileLister
/// @brief Font lister interface
class FontFileLister {
public:
struct CollectionResult {
/// Characters which could not be found in any font files
wxString missing;
/// Paths to the file(s) containing the requested font
std::vector<agi::fs::path> paths;
};
/// @brief Get the path to the font with the given styles
/// @param facename Name of font face
/// @param bold ASS font weight
/// @param italic Italic?
/// @param characters Characters in this style
/// @return Path to the matching font file(s), or empty if not found
virtual CollectionResult GetFontPaths(std::string const& facename, int bold, bool italic, std::set<wxUniChar> const& characters) = 0;
};
/// @class FontCollector
/// @brief Class which collects the paths to all fonts used in a script
class FontCollector {
/// All data needed to find the font file used to render text
struct StyleInfo {
std::string facename;
int bold;
bool italic;
bool operator<(StyleInfo const& rgt) const;
};
/// Data about where each style is used
struct UsageData {
std::set<wxUniChar> chars; ///< Characters used in this style which glyphs will be needed for
std::set<int> lines; ///< Lines on which this style is used via overrides
std::set<std::string> styles; ///< ASS styles which use this style
};
/// Message callback provider by caller
FontCollectorStatusCallback status_callback;
/// The actual lister to use to get font paths
FontFileLister &lister;
/// The set of all glyphs used in the file
std::map<StyleInfo, UsageData> used_styles;
/// Style name -> ASS style definition
std::map<std::string, StyleInfo> styles;
/// Paths to found required font files
std::set<agi::fs::path> results;
/// Number of fonts which could not be found
int missing = 0;
/// Number of fonts which were found, but did not contain all used glyphs
int missing_glyphs = 0;
/// Gather all of the unique styles with text on a line
void ProcessDialogueLine(const AssDialogue *line, int index);
/// Get the font for a single style
void ProcessChunk(std::pair<StyleInfo, UsageData> const& style);
/// Print the lines and styles on which a missing font is used
void PrintUsage(UsageData const& data);
public:
/// Constructor
/// @param status_callback Function to pass status updates to
/// @param lister The actual font file lister
FontCollector(FontCollectorStatusCallback status_callback, FontFileLister &lister);
/// @brief Get a list of the locations of all font files used in the file
/// @param file Lines in the subtitle file to check
/// @param status Callback function for messages
/// @return List of paths to fonts
std::vector<agi::fs::path> GetFontPaths(const AssFile *file);
};