Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/nsTextFrameUtils.h
Line
Count
Source (jump to first uncovered line)
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
#include "nsUnicodeProperties.h"
13
14
class nsIContent;
15
struct nsStyleText;
16
17
#define BIG_TEXT_NODE_SIZE 4096
18
19
0
#define CH_NBSP   160
20
0
#define CH_SHY    173
21
#define CH_CJKSP  12288 // U+3000 IDEOGRAPHIC SPACE (CJK Full-Width Space)
22
23
class nsTextFrameUtils {
24
public:
25
  // These constants are used as textrun flags for textframe textruns.
26
  enum class Flags : uint16_t {
27
    // The following flags are set by TransformText
28
29
    // the text has at least one untransformed tab character
30
    TEXT_HAS_TAB             = 0x01,
31
    // the original text has at least one soft hyphen character
32
    TEXT_HAS_SHY             = 0x02,
33
    TEXT_UNUSED_FLAGS        = 0x0C,
34
35
    // The following flags are set by nsTextFrame
36
37
    TEXT_IS_SIMPLE_FLOW      = 0x10,
38
    TEXT_INCOMING_WHITESPACE = 0x20,
39
    TEXT_TRAILING_WHITESPACE = 0x40,
40
    TEXT_COMPRESSED_LEADING_WHITESPACE = 0x80,
41
    TEXT_NO_BREAKS           = 0x100,
42
    TEXT_IS_TRANSFORMED      = 0x200,
43
    // This gets set if there's a break opportunity at the end of the textrun.
44
    // We normally don't use this break opportunity because the following text
45
    // will have a break opportunity at the start, but it's useful for line
46
    // layout to know about it in case the following content is not text
47
    TEXT_HAS_TRAILING_BREAK  = 0x400,
48
49
    // This is set if the textrun was created for a textframe whose
50
    // NS_FRAME_IS_IN_SINGLE_CHAR_MI flag is set.  This occurs if the textframe
51
    // belongs to a MathML <mi> element whose embedded text consists of a
52
    // single character.
53
    TEXT_IS_SINGLE_CHAR_MI   = 0x800,
54
55
    // This is set if the text run might be observing for glyph changes.
56
    TEXT_MIGHT_HAVE_GLYPH_CHANGES = 0x1000,
57
58
    // For internal use by the memory reporter when accounting for
59
    // storage used by textruns.
60
    // Because the reporter may visit each textrun multiple times while
61
    // walking the frame trees and textrun cache, it needs to mark
62
    // textruns that have been seen so as to avoid multiple-accounting.
63
    TEXT_RUN_SIZE_ACCOUNTED      = 0x2000,
64
65
    // The following are defined by gfxTextRunFactory rather than here,
66
    // so that it also has access to the _INCOMING and MATH_SCRIPT flags
67
    // for shaping purposes.
68
    // They live in the gfxShapedText::mFlags field rather than the
69
    // gfxTextRun::mFlags2 field.
70
    // TEXT_TRAILING_ARABICCHAR
71
    // TEXT_INCOMING_ARABICCHAR
72
    // TEXT_USE_MATH_SCRIPT
73
  };
74
75
  // These constants are used in TransformText to represent context information
76
  // from previous textruns.
77
  enum {
78
    INCOMING_NONE       = 0,
79
    INCOMING_WHITESPACE = 1,
80
    INCOMING_ARABICCHAR = 2
81
  };
82
83
  /**
84
   * Returns true if aChars/aLength are something that make a space
85
   * character not be whitespace when they follow the space character
86
   * (combining mark or join control, ignoring intervening direction
87
   * controls).
88
   */
89
  static bool
90
0
  IsSpaceCombiningSequenceTail(const char16_t* aChars, int32_t aLength) {
91
0
    return aLength > 0 &&
92
0
      (mozilla::unicode::IsClusterExtender(aChars[0]) ||
93
0
       (IsBidiControl(aChars[0]) &&
94
0
        IsSpaceCombiningSequenceTail(aChars + 1, aLength - 1)
95
0
       )
96
0
      );
97
0
  }
98
  static bool
99
  IsSpaceCombiningSequenceTail(const uint8_t* aChars, int32_t aLength) {
100
    return false;
101
  }
102
103
  enum CompressionMode {
104
    COMPRESS_NONE,
105
    COMPRESS_WHITESPACE,
106
    COMPRESS_WHITESPACE_NEWLINE,
107
    COMPRESS_NONE_TRANSFORM_TO_SPACE
108
  };
109
110
  /**
111
   * Create a text run from a run of Unicode text. The text may have whitespace
112
   * compressed. A preformatted tab is sent to the text run as a single space.
113
   * (Tab spacing must be performed by textframe later.) Certain other
114
   * characters are discarded.
115
   *
116
   * @param aCompression control what is compressed to a
117
   * single space character: no compression, compress spaces (not followed
118
   * by combining mark) and tabs, compress those plus newlines, or
119
   * no compression except newlines are discarded.
120
   * @param aIncomingFlags a flag indicating whether there was whitespace
121
   * or an Arabic character preceding this text. We set it to indicate if
122
   * there's an Arabic character or whitespace preceding the end of this text.
123
   */
124
  template<class CharT>
125
  static CharT* TransformText(const CharT* aText, uint32_t aLength,
126
                              CharT* aOutput,
127
                              CompressionMode aCompression,
128
                              uint8_t* aIncomingFlags,
129
                              gfxSkipChars* aSkipChars,
130
                              nsTextFrameUtils::Flags* aAnalysisFlags);
131
132
  /**
133
   * Returns whether aChar is a character that nsTextFrameUtils::TransformText
134
   * might mark as skipped.  This is used by
135
   * SVGTextContentElement::GetNumberOfChars to know whether reflowing frames,
136
   * so that we have the results of TransformText, is required, or whether we
137
   * can use a fast path instead.
138
   */
139
  template<class CharT>
140
  static bool IsSkippableCharacterForTransformText(CharT aChar);
141
142
  static void
143
  AppendLineBreakOffset(nsTArray<uint32_t>* aArray, uint32_t aOffset)
144
0
  {
145
0
    if (aArray->Length() > 0 && (*aArray)[aArray->Length() - 1] == aOffset)
146
0
      return;
147
0
    aArray->AppendElement(aOffset);
148
0
  }
149
150
  static uint32_t
151
  ComputeApproximateLengthWithWhitespaceCompression(nsIContent *aContent,
152
                                                    const nsStyleText*
153
                                                      aStyleText);
154
};
155
156
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsTextFrameUtils::Flags)
157
158
class nsSkipCharsRunIterator {
159
public:
160
  enum LengthMode {
161
    LENGTH_UNSKIPPED_ONLY   = false,
162
    LENGTH_INCLUDES_SKIPPED = true
163
  };
164
  nsSkipCharsRunIterator(const gfxSkipCharsIterator& aStart,
165
      LengthMode aLengthIncludesSkipped, uint32_t aLength)
166
    : mIterator(aStart), mRemainingLength(aLength), mRunLength(0),
167
      mSkipped(false), mVisitSkipped(false),
168
0
      mLengthIncludesSkipped(aLengthIncludesSkipped) {
169
0
  }
170
0
  void SetVisitSkipped() { mVisitSkipped = true; }
171
0
  void SetOriginalOffset(int32_t aOffset) {
172
0
    mIterator.SetOriginalOffset(aOffset);
173
0
  }
174
0
  void SetSkippedOffset(uint32_t aOffset) {
175
0
    mIterator.SetSkippedOffset(aOffset);
176
0
  }
177
178
  // guaranteed to return only positive-length runs
179
  bool NextRun();
180
0
  bool IsSkipped() const { return mSkipped; }
181
  // Always returns something > 0
182
0
  int32_t GetRunLength() const { return mRunLength; }
183
0
  const gfxSkipCharsIterator& GetPos() const { return mIterator; }
184
0
  int32_t GetOriginalOffset() const { return mIterator.GetOriginalOffset(); }
185
0
  uint32_t GetSkippedOffset() const { return mIterator.GetSkippedOffset(); }
186
187
private:
188
  gfxSkipCharsIterator mIterator;
189
  int32_t              mRemainingLength;
190
  int32_t              mRunLength;
191
  bool                 mSkipped;
192
  bool                 mVisitSkipped;
193
  bool                 mLengthIncludesSkipped;
194
};
195
196
#endif /*NSTEXTFRAMEUTILS_H_*/