tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsTextFrameUtils.h (8342B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef NSTEXTFRAMEUTILS_H_
      8 #define NSTEXTFRAMEUTILS_H_
      9 
     10 #include "gfxSkipChars.h"
     11 #include "nsBidiUtils.h"
     12 
     13 class nsAtom;
     14 class nsIContent;
     15 struct nsStyleText;
     16 
     17 namespace mozilla {
     18 namespace dom {
     19 class Text;
     20 }
     21 }  // namespace mozilla
     22 
     23 #define BIG_TEXT_NODE_SIZE 4096
     24 
     25 #define CH_NBSP 160
     26 #define CH_SHY 173
     27 #define CH_CJKSP 12288  // U+3000 IDEOGRAPHIC SPACE (CJK Full-Width Space)
     28 
     29 class nsTextFrameUtils {
     30 public:
     31  // These constants are used as textrun flags for textframe textruns.
     32  //
     33  // If you add a flag, please add support for it in gfxTextRun::Dump.
     34  enum class Flags : uint16_t {
     35    // The following flags are set by TransformText
     36 
     37    // the text has at least one untransformed tab character
     38    HasTab = 0x01,
     39    // the original text has at least one soft hyphen character
     40    HasShy = 0x02,
     41    // the text has at least one untransformed newline character
     42    HasNewline = 0x04,
     43 
     44    // Flag used in textrun construction to *prevent* hiding of fallback text
     45    // for pending user-fonts (used for Canvas2d text).
     46    DontSkipDrawingForPendingUserFonts = 0x08,
     47 
     48    // The following flags are set by nsTextFrame
     49 
     50    IsSimpleFlow = 0x10,
     51    IncomingWhitespace = 0x20,
     52    TrailingWhitespace = 0x40,
     53    CompressedLeadingWhitespace = 0x80,
     54    NoBreaks = 0x100,
     55    IsTransformed = 0x200,
     56    // This gets set if there's a break opportunity at the end of the textrun.
     57    // We normally don't use this break opportunity because the following text
     58    // will have a break opportunity at the start, but it's useful for line
     59    // layout to know about it in case the following content is not text
     60    HasTrailingBreak = 0x400,
     61 
     62    // This is set if the textrun was created for a textframe whose
     63    // NS_FRAME_IS_IN_SINGLE_CHAR_MI flag is set.  This occurs if the textframe
     64    // belongs to a MathML <mi> element whose embedded text consists of a
     65    // single character.
     66    IsSingleCharMi = 0x800,
     67 
     68    // This is set if the text run might be observing for glyph changes.
     69    MightHaveGlyphChanges = 0x1000,
     70 
     71    // For internal use by the memory reporter when accounting for
     72    // storage used by textruns.
     73    // Because the reporter may visit each textrun multiple times while
     74    // walking the frame trees and textrun cache, it needs to mark
     75    // textruns that have been seen so as to avoid multiple-accounting.
     76    RunSizeAccounted = 0x2000,
     77 
     78    // The following are defined by gfxTextRunFactory rather than here,
     79    // so that it also has access to the _INCOMING and MATH_SCRIPT flags
     80    // for shaping purposes.
     81    // They live in the gfxShapedText::mFlags field rather than the
     82    // gfxTextRun::mFlags2 field.
     83    // TEXT_TRAILING_ARABICCHAR
     84    // TEXT_INCOMING_ARABICCHAR
     85    // TEXT_USE_MATH_SCRIPT
     86  };
     87 
     88  // These constants are used in TransformText to represent context information
     89  // from previous textruns.
     90  enum { INCOMING_NONE = 0, INCOMING_WHITESPACE = 1, INCOMING_ARABICCHAR = 2 };
     91 
     92  /**
     93   * Returns true if aChars/aLength are something that make a space
     94   * character not be whitespace when they follow the space character
     95   * (combining mark or join control, ignoring intervening direction
     96   * controls).
     97   */
     98  static bool IsSpaceCombiningSequenceTail(const char16_t* aChars,
     99                                           int32_t aLength);
    100  static bool IsSpaceCombiningSequenceTail(const uint8_t* aChars,
    101                                           int32_t aLength) {
    102    return false;
    103  }
    104 
    105  enum CompressionMode {
    106    COMPRESS_NONE,
    107    COMPRESS_WHITESPACE,
    108    COMPRESS_WHITESPACE_NEWLINE,
    109    COMPRESS_NONE_TRANSFORM_TO_SPACE
    110  };
    111 
    112  /**
    113   * Create a text run from a run of Unicode text. The text may have whitespace
    114   * compressed. A preformatted tab is sent to the text run as a single space.
    115   * (Tab spacing must be performed by textframe later.) Certain other
    116   * characters are discarded.
    117   *
    118   * @param aCompression control what is compressed to a
    119   * single space character: no compression, compress spaces (not followed
    120   * by combining mark) and tabs, compress those plus newlines, or
    121   * no compression except newlines are discarded.
    122   * @param aIncomingFlags a flag indicating whether there was whitespace
    123   * or an Arabic character preceding this text. We set it to indicate if
    124   * there's an Arabic character or whitespace preceding the end of this text.
    125   * @param aLanguage Content language (used to select Japanese/Chinese behavior
    126   * at punctuation, see https://bugzilla.mozilla.org/show_bug.cgi?id=1935148).
    127   */
    128  template <class CharT>
    129  static CharT* TransformText(const CharT* aText, uint32_t aLength,
    130                              CharT* aOutput, CompressionMode aCompression,
    131                              uint8_t* aIncomingFlags, gfxSkipChars* aSkipChars,
    132                              nsTextFrameUtils::Flags* aAnalysisFlags,
    133                              const nsAtom* aLanguage);
    134 
    135  /**
    136   * Returns whether aChar is a character that nsTextFrameUtils::TransformText
    137   * might mark as skipped.  This is used by
    138   * SVGTextContentElement::GetNumberOfChars to know whether reflowing frames,
    139   * so that we have the results of TransformText, is required, or whether we
    140   * can use a fast path instead.
    141   */
    142  template <class CharT>
    143  static bool IsSkippableCharacterForTransformText(CharT aChar);
    144 
    145  static void AppendLineBreakOffset(nsTArray<uint32_t>* aArray,
    146                                    uint32_t aOffset) {
    147    if (aArray->Length() > 0 && (*aArray)[aArray->Length() - 1] == aOffset) {
    148      return;
    149    }
    150    aArray->AppendElement(aOffset);
    151  }
    152 
    153  static uint32_t ComputeApproximateLengthWithWhitespaceCompression(
    154      mozilla::dom::Text*, const nsStyleText*);
    155  static uint32_t ComputeApproximateLengthWithWhitespaceCompression(
    156      const nsAString&, const nsStyleText*);
    157 };
    158 
    159 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrameUtils::Flags)
    160 
    161 /**
    162 * nsSkipCharsRunIterator is a layout-oriented convenience wrapper over
    163 * gfxSkipCharsIterator, which iterates over runs in the string. Each run
    164 * consists entirely of either "unskipped" or "skipped" characters.
    165 *
    166 * By default, calling NextRun() iterates over only unskipped runs. Call
    167 * SetVisitSkipped() to let NextRun() also iterates over skipped runs where
    168 * IsSkipped() is true.
    169 */
    170 class nsSkipCharsRunIterator {
    171 public:
    172  // Indicates whether the constructor's aRemainingLength counts only unskipped
    173  // characters, or unskipped + skipped characters.
    174  enum LengthMode {
    175    LENGTH_UNSKIPPED_ONLY = false,
    176    LENGTH_INCLUDES_SKIPPED = true
    177  };
    178  nsSkipCharsRunIterator(const gfxSkipCharsIterator& aStart,
    179                         LengthMode aLengthIncludesSkipped,
    180                         uint32_t aRemainingLength)
    181      : mIterator(aStart),
    182        mRemainingLength(aRemainingLength),
    183        mRunLength(0),
    184        mSkipped(false),
    185        mVisitSkipped(false),
    186        mLengthIncludesSkipped(aLengthIncludesSkipped) {}
    187 
    188  // Include skipped runs in iteration results.
    189  void SetVisitSkipped() { mVisitSkipped = true; }
    190 
    191  void SetOriginalOffset(int32_t aOffset) {
    192    mIterator.SetOriginalOffset(aOffset);
    193  }
    194  void SetSkippedOffset(uint32_t aOffset) {
    195    mIterator.SetSkippedOffset(aOffset);
    196  }
    197 
    198  // Advance to the next run. Return false when no runs remain. On success,
    199  // GetRunLength() is guaranteed to return positive length.
    200  bool NextRun();
    201 
    202  // Return true if the current run consists of skipped characters.
    203  bool IsSkipped() const { return mSkipped; }
    204 
    205  // Length of the current run. The return value is always positive.
    206  int32_t GetRunLength() const { return mRunLength; }
    207 
    208  const gfxSkipCharsIterator& GetPos() const { return mIterator; }
    209  int32_t GetOriginalOffset() const { return mIterator.GetOriginalOffset(); }
    210  uint32_t GetSkippedOffset() const { return mIterator.GetSkippedOffset(); }
    211 
    212 private:
    213  gfxSkipCharsIterator mIterator;
    214  int32_t mRemainingLength;
    215  int32_t mRunLength;
    216  bool mSkipped;
    217  bool mVisitSkipped;
    218  bool mLengthIncludesSkipped;
    219 };
    220 
    221 #endif /*NSTEXTFRAMEUTILS_H_*/