DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (a3f183201f7f)

VCS Links

FontCallbackData

Glyf

gfxHarfBuzzShaper

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef GFX_HARFBUZZSHAPER_H
#define GFX_HARFBUZZSHAPER_H

#include "gfxFont.h"

#include "harfbuzz/hb.h"
#include "nsUnicodeProperties.h"
#include "mozilla/gfx/2D.h"

class gfxHarfBuzzShaper : public gfxFontShaper {
public:
    explicit gfxHarfBuzzShaper(gfxFont *aFont);
    virtual ~gfxHarfBuzzShaper();

    /*
     * For HarfBuzz font callback functions, font_data is a ptr to a
     * FontCallbackData struct
     */
    struct FontCallbackData {
        gfxHarfBuzzShaper* mShaper;
        // initialized to a DrawTarget owned by our caller on every call to
        // ShapeText
        mozilla::gfx::DrawTarget* MOZ_NON_OWNING_REF mDrawTarget;
    };

    bool Initialize();

    bool ShapeText(DrawTarget      *aDrawTarget,
                   const char16_t *aText,
                   uint32_t         aOffset,
                   uint32_t         aLength,
                   Script           aScript,
                   bool             aVertical,
                   RoundingFlags    aRounding,
                   gfxShapedText   *aShapedText) override;

    // get a given font table in harfbuzz blob form
    hb_blob_t * GetFontTable(hb_tag_t aTag) const;

    // map unicode character to glyph ID
    hb_codepoint_t GetNominalGlyph(hb_codepoint_t unicode) const;
    hb_codepoint_t GetVariationGlyph(hb_codepoint_t unicode,
                                     hb_codepoint_t variation_selector) const;

    // get harfbuzz glyph advance, in font design units
    hb_position_t GetGlyphHAdvance(hb_codepoint_t glyph) const;

    hb_position_t GetGlyphVAdvance(hb_codepoint_t glyph) const;

    void GetGlyphVOrigin(hb_codepoint_t aGlyph,
                         hb_position_t *aX, hb_position_t *aY) const;

    // get harfbuzz horizontal advance in 16.16 fixed point format.
    static hb_position_t
    HBGetGlyphHAdvance(hb_font_t *font, void *font_data,
                       hb_codepoint_t glyph, void *user_data);

    // get harfbuzz vertical advance in 16.16 fixed point format.
    static hb_position_t
    HBGetGlyphVAdvance(hb_font_t *font, void *font_data,
                       hb_codepoint_t glyph, void *user_data);

    static hb_bool_t
    HBGetGlyphVOrigin(hb_font_t *font, void *font_data,
                      hb_codepoint_t glyph,
                      hb_position_t *x, hb_position_t *y,
                      void *user_data);

    hb_position_t GetHKerning(uint16_t aFirstGlyph,
                              uint16_t aSecondGlyph) const;

    hb_bool_t GetGlyphExtents(hb_codepoint_t aGlyph,
                              hb_glyph_extents_t *aExtents) const;

    bool UseVerticalPresentationForms() const
    {
        return mUseVerticalPresentationForms;
    }

    static hb_script_t
    GetHBScriptUsedForShaping(Script aScript) {
        // Decide what harfbuzz script code will be used for shaping
        hb_script_t hbScript;
        if (aScript <= Script::INHERITED) {
            // For unresolved "common" or "inherited" runs,
            // default to Latin for now.
            hbScript = HB_SCRIPT_LATIN;
        } else {
            hbScript =
                hb_script_t(mozilla::unicode::GetScriptTagForCode(aScript));
        }
        return hbScript;
    }

protected:
    nsresult SetGlyphsFromRun(gfxShapedText  *aShapedText,
                              uint32_t        aOffset,
                              uint32_t        aLength,
                              const char16_t *aText,
                              bool            aVertical,
                              RoundingFlags   aRounding);

    // retrieve glyph positions, applying advance adjustments and attachments
    // returns results in appUnits
    nscoord GetGlyphPositions(gfxContext *aContext,
                              nsTArray<nsPoint>& aPositions,
                              uint32_t aAppUnitsPerDevUnit);

    bool InitializeVertical();
    bool LoadHmtxTable();

    struct Glyf { // we only need the bounding-box at the beginning
                  // of the glyph record, not the actual outline data
        mozilla::AutoSwap_PRInt16 numberOfContours;
        mozilla::AutoSwap_PRInt16 xMin;
        mozilla::AutoSwap_PRInt16 yMin;
        mozilla::AutoSwap_PRInt16 xMax;
        mozilla::AutoSwap_PRInt16 yMax;
    };

    const Glyf *FindGlyf(hb_codepoint_t aGlyph, bool *aEmptyGlyf) const;

    // harfbuzz face object: we acquire a reference from the font entry
    // on shaper creation, and release it in our destructor
    hb_face_t         *mHBFace;

    // size-specific font object, owned by the gfxHarfBuzzShaper
    hb_font_t         *mHBFont;

    // harfbuzz buffer for the shaping process
    hb_buffer_t       *mBuffer;

    FontCallbackData   mCallbackData;

    // Following table references etc are declared "mutable" because the
    // harfbuzz callback functions take a const ptr to the shaper, but
    // wish to cache tables here to avoid repeatedly looking them up
    // in the font.

    // Old-style TrueType kern table, if we're not doing GPOS kerning
    mutable hb_blob_t *mKernTable;

    // Cached copy of the hmtx table.
    mutable hb_blob_t *mHmtxTable;

    // For vertical fonts, cached vmtx and VORG table, if present.
    mutable hb_blob_t *mVmtxTable;
    mutable hb_blob_t *mVORGTable;
    // And for vertical TrueType (not CFF) fonts that have vmtx,
    // we also use loca and glyf to get glyph bounding boxes.
    mutable hb_blob_t *mLocaTable;
    mutable hb_blob_t *mGlyfTable;

    // Cached pointer to cmap subtable to be used for char-to-glyph mapping.
    // This comes from GetFontTablePtr; if it is non-null, our destructor
    // must call ReleaseFontTablePtr to avoid permanently caching the table.
    mutable hb_blob_t *mCmapTable;
    mutable int32_t    mCmapFormat;
    mutable uint32_t   mSubtableOffset;
    mutable uint32_t   mUVSTableOffset;

    // Cached copy of numLongMetrics field from the hhea table,
    // for use when looking up glyph metrics; initialized to 0 by the
    // constructor so we can tell it hasn't been set yet.
    // This is a signed value so that we can use -1 to indicate
    // an error (if the hhea table was not available).
    mutable int32_t    mNumLongHMetrics;
    // Similarly for vhea if it's a vertical font.
    mutable int32_t    mNumLongVMetrics;

    // Whether the font implements GetGlyph, or we should read tables
    // directly
    bool mUseFontGetGlyph;
    // Whether the font implements GetGlyphWidth, or we should read tables
    // directly to get ideal widths
    bool mUseFontGlyphWidths;

    bool mInitialized;
    bool mVerticalInitialized;

    // Whether to use vertical presentation forms for CJK characters
    // when available (only set if the 'vert' feature is not available).
    bool mUseVerticalPresentationForms;

    // these are set from the FindGlyf callback on first use of the glyf data
    mutable bool mLoadedLocaGlyf;
    mutable bool mLocaLongOffsets;
};

#endif /* GFX_HARFBUZZSHAPER_H */