
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#ifndef SkFontHost_DEFINED
#define SkFontHost_DEFINED

#include "SkTypeface.h"

class SkDescriptor;
class SkScalerContext;
struct SkScalerContextRec;
class SkStream;
class SkWStream;

/** \class SkFontHost

    This class is ported to each environment. It is responsible for bridging
    the gap between the (sort of) abstract class SkTypeface and the
    platform-specific implementation that provides access to font files.

    One basic task is for each create (subclass of) SkTypeface, the FontHost is
    responsible for assigning a uniqueID. The ID should be unique for the
    underlying font file/data, not unique per typeface instance. Thus it is
    possible/common to request a typeface for the same font more than once
    (e.g. asking for the same font by name several times). The FontHost may
    return seperate typeface instances in that case, or it may choose to use a
    cache and return the same instance (but calling typeface->ref(), since the
    caller is always responsible for calling unref() on each instance that is
    returned). Either way, the fontID for those instance(s) will be the same.
    In addition, the fontID should never be set to 0. That value is used as a
    sentinel to indicate no-font-id.

    The major aspects are:
    1) Given either a name/style, return a subclass of SkTypeface that
        references the closest matching font available on the host system.
    2) Given the data for a font (either in a stream or a file name), return
        a typeface that allows access to that data.
    3) Each typeface instance carries a 32bit ID for its corresponding font.
        SkFontHost turns that ID into a stream to access the font's data.
    4) Given a font ID, return a subclass of SkScalerContext, which connects a
        font scaler (e.g. freetype or other) to the font's data.
    5) Utilites to manage the font cache (budgeting) and gamma correction
*/
class SK_API SkFontHost {
public:
    /** Return a new, closest matching typeface given either an existing family
        (specified by a typeface in that family) or by a familyName and a
        requested style.
        1) If familyFace is null, use familyName.
        2) If familyName is null, use data (UTF-16 to cover).
        3) If all are null, return the default font that best matches style
     */
    static SkTypeface* CreateTypeface(const SkTypeface* familyFace,
                                      const char familyName[],
                                      SkTypeface::Style style);

    /** Return a new typeface given the data buffer. If the data does not
        represent a valid font, returns null.

        If a typeface instance is returned, the caller is responsible for
        calling unref() on the typeface when they are finished with it.

        The returned typeface may or may not have called ref() on the stream
        parameter. If the typeface has not called ref(), then it may have made
        a copy of the releveant data. In either case, the caller is still
        responsible for its refcnt ownership of the stream.
     */
    static SkTypeface* CreateTypefaceFromStream(SkStream*);

    /** Return a new typeface from the specified file path. If the file does not
        represent a valid font, this returns null. If a typeface is returned,
        the caller is responsible for calling unref() when it is no longer used.
     */
    static SkTypeface* CreateTypefaceFromFile(const char path[]);

    ///////////////////////////////////////////////////////////////////////////

    /** Return a new stream to read the font data, or null if the uniqueID does
        not match an existing typeface. .The caller must call stream->unref()
        when it is finished reading the data.
    */
    static SkStream* OpenStream(SkFontID uniqueID);

    /** Some fonts are stored in files. If that is true for the fontID, then
        this returns the byte length of the full file path. If path is not null,
        then the full path is copied into path (allocated by the caller), up to
        length bytes. If index is not null, then it is set to the truetype
        collection index for this font, or 0 if the font is not in a collection.

        Note: GetFileName does not assume that path is a null-terminated string,
        so when it succeeds, it only copies the bytes of the file name and
        nothing else (i.e. it copies exactly the number of bytes returned by the
        function. If the caller wants to treat path[] as a C string, it must be
        sure that it is allocated at least 1 byte larger than the returned size,
        and it must copy in the terminating 0.

        If the fontID does not correspond to a file, then the function returns
        0, and the path and index parameters are ignored.

        @param fontID   The font whose file name is being queried
        @param path     Either NULL, or storage for receiving up to length bytes
                        of the font's file name. Allocated by the caller.
        @param length   The maximum space allocated in path (by the caller).
                        Ignored if path is NULL.
        @param index    Either NULL, or receives the TTC index for this font.
                        If the font is not a TTC, then will be set to 0.
        @return The byte length of th font's file name, or 0 if the font is not
                baked by a file.
     */
    static size_t GetFileName(SkFontID fontID, char path[], size_t length,
                              int32_t* index);

    ///////////////////////////////////////////////////////////////////////////

    /** Write a unique identifier to the stream, so that the same typeface can
        be retrieved with Deserialize(). The standard format is to serialize
        a SkFontDescriptor followed by a uint32_t length value. If the length
        is non-zero then the following bytes (of that length) represent a
        serialized copy of the font which can be recreated from a stream.
    */
    static void Serialize(const SkTypeface*, SkWStream*);

    /** Given a stream created by Serialize(), return a new typeface (like
        CreateTypeface) which is either an exact match to the one serialized
        or the best available typeface based on the data in the deserialized
        SkFontDescriptor.
     */
    static SkTypeface* Deserialize(SkStream*);

    ///////////////////////////////////////////////////////////////////////////

    /** Return a subclass of SkScalarContext
    */
    static SkScalerContext* CreateScalerContext(const SkDescriptor* desc);

    /**
     *  Given a "current" fontID, return the next logical fontID to use
     *  when searching fonts for a given unicode value. Typically the caller
     *  will query a given font, and if a unicode value is not supported, they
     *  will call this, and if 0 is not returned, will search that font, and so
     *  on. This process must be finite, and when the fonthost sees a
     *  font with no logical successor, it must return 0.
     *
     *  The original fontID is also provided. This is the initial font that was
     *  stored in the typeface of the caller. It is provided as an aid to choose
     *  the best next logical font. e.g. If the original font was bold or serif,
     *  but the 2nd in the logical chain was plain, then a subsequent call to
     *  get the 3rd can still inspect the original, and try to match its
     *  stylistic attributes.
     */
    static SkFontID NextLogicalFont(SkFontID currFontID, SkFontID origFontID);

#ifdef SK_BUILD_FOR_ANDROID
    /*
     * This Android-only version of NextLogicalFont allows us to pass in an
     * entire Rec structure so that a caller can change fallback behavior
     */
    static SkFontID NextLogicalFont(const SkScalerContextRec& rec);
#endif


    ///////////////////////////////////////////////////////////////////////////

    /** Given a filled-out rec, the fonthost may decide to modify it to reflect
        what the host is actually capable of fulfilling. For example, if the
        rec is requesting a level of hinting that, for this host, maps some
        other level (e.g. kFull -> kNormal), it should update the rec to reflect
        what will actually be done. This is an optimization so that the font
        cache does not contain different recs (i.e. keys) that in reality map to
        the same output.

        A lazy (but valid) fonthost can do nothing in its FilterRec routine.

        The provided typeface corresponds to the fFontID field.
     */
    static void FilterRec(SkScalerContextRec* rec, SkTypeface* typeface);

    ///////////////////////////////////////////////////////////////////////////

    /** Retrieve detailed typeface metrics.  Used by the PDF backend.
        @param perGlyphInfo Indicate what glyph specific information (advances,
                            names, etc.) should be populated.
        @return The returned object has already been referenced.  NULL is
                returned if the font is not found.
        @param glyphIDs  For per-glyph info, specify subset of the font by
                         giving glyph ids.  Each integer represents a glyph
                         id.  Passing NULL means all glyphs in the font.
        @param glyphIDsCount Number of elements in subsetGlyphIds. Ignored if
                             glyphIDs is NULL.
     */
    static SkAdvancedTypefaceMetrics* GetAdvancedTypefaceMetrics(
            SkFontID fontID,
            SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
            const uint32_t* glyphIDs,
            uint32_t glyphIDsCount);

    /** Return the number of tables in the font
     */
    static int CountTables(SkFontID);

    /** Copy into tags[] (allocated by the caller) the list of table tags in
        the font, and return the number. This will be the same as CountTables()
        or 0 if an error occured.
     */
    static int GetTableTags(SkFontID, SkFontTableTag[]);

    /** Given a table tag, return the size of its contents, or 0 if not present
     */
    static size_t GetTableSize(SkFontID, SkFontTableTag);

    /** Copy the contents of a table into data (allocated by the caller). Note
        that the contents of the table will be in their native endian order
        (which for most truetype tables is big endian). If the table tag is
        not found, or there is an error copying the data, then 0 is returned.
        If this happens, it is possible that some or all of the memory pointed
        to by data may have been written to, even though an error has occured.

        @param fontID the font to copy the table from
        @param tag  The table tag whose contents are to be copied
        @param offset The offset in bytes into the table's contents where the
                copy should start from.
        @param length The number of bytes, starting at offset, of table data
                to copy.
        @param data storage address where the table contents are copied to
        @return the number of bytes actually copied into data. If offset+length
                exceeds the table's size, then only the bytes up to the table's
                size are actually copied, and this is the value returned. If
                offset > the table's size, or tag is not a valid table,
                then 0 is returned.
     */
    static size_t GetTableData(SkFontID fontID, SkFontTableTag tag,
                               size_t offset, size_t length, void* data);

    ///////////////////////////////////////////////////////////////////////////

    /** LCDs either have their color elements arranged horizontally or
        vertically. When rendering subpixel glyphs we need to know which way
        round they are.

        Note, if you change this after startup, you'll need to flush the glyph
        cache because it'll have the wrong type of masks cached.

        @deprecated use SkPixelGeometry instead.
    */
    enum LCDOrientation {
        kHorizontal_LCDOrientation = 0,    //!< this is the default
        kVertical_LCDOrientation   = 1
    };

    /** @deprecated set on Device creation. */
    static void SetSubpixelOrientation(LCDOrientation orientation);
    /** @deprecated get from Device. */
    static LCDOrientation GetSubpixelOrientation();

    /** LCD color elements can vary in order. For subpixel text we need to know
        the order which the LCDs uses so that the color fringes are in the
        correct place.

        Note, if you change this after startup, you'll need to flush the glyph
        cache because it'll have the wrong type of masks cached.

        kNONE_LCDOrder means that the subpixel elements are not spatially
        separated in any usable fashion.

        @deprecated use SkPixelGeometry instead.
     */
    enum LCDOrder {
        kRGB_LCDOrder = 0,    //!< this is the default
        kBGR_LCDOrder = 1,
        kNONE_LCDOrder = 2
    };

    /** @deprecated set on Device creation. */
    static void SetSubpixelOrder(LCDOrder order);
    /** @deprecated get from Device. */
    static LCDOrder GetSubpixelOrder();

#ifdef SK_BUILD_FOR_ANDROID
    ///////////////////////////////////////////////////////////////////////////

    /**
     * Return the number of font units per em.
     *
     * @param fontID the font to query.
     * @return the number of font units per em or 0 on error.
     */
    static uint32_t GetUnitsPerEm(SkFontID fontID);
#endif

    /** If Skia is running in a constrained environment and the typeface
        implementation is handle based, the typeface data may become
        unavailable asynchronously. If a font host or scaler context method is
        unable to access font data, it may call this function as a request to
        make the handle contained in the typeface useable.
    */
    static void EnsureTypefaceAccessible(const SkTypeface& typeface);
};

#endif
