michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_TextRage_h_ michael@0: #define mozilla_TextRage_h_ michael@0: michael@0: #include michael@0: michael@0: #include "nsAutoPtr.h" michael@0: #include "nsColor.h" michael@0: #include "nsStyleConsts.h" michael@0: #include "nsTArray.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: /****************************************************************************** michael@0: * mozilla::TextRangeStyle michael@0: ******************************************************************************/ michael@0: michael@0: struct TextRangeStyle michael@0: { michael@0: enum michael@0: { michael@0: LINESTYLE_NONE = NS_STYLE_TEXT_DECORATION_STYLE_NONE, michael@0: LINESTYLE_SOLID = NS_STYLE_TEXT_DECORATION_STYLE_SOLID, michael@0: LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED, michael@0: LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED, michael@0: LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE, michael@0: LINESTYLE_WAVY = NS_STYLE_TEXT_DECORATION_STYLE_WAVY michael@0: }; michael@0: michael@0: enum michael@0: { michael@0: DEFINED_NONE = 0x00, michael@0: DEFINED_LINESTYLE = 0x01, michael@0: DEFINED_FOREGROUND_COLOR = 0x02, michael@0: DEFINED_BACKGROUND_COLOR = 0x04, michael@0: DEFINED_UNDERLINE_COLOR = 0x08 michael@0: }; michael@0: michael@0: // Initialize all members, because TextRange instances may be compared by michael@0: // memcomp. michael@0: TextRangeStyle() michael@0: { michael@0: Clear(); michael@0: } michael@0: michael@0: void Clear() michael@0: { michael@0: mDefinedStyles = DEFINED_NONE; michael@0: mLineStyle = LINESTYLE_NONE; michael@0: mIsBoldLine = false; michael@0: mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0); michael@0: } michael@0: michael@0: bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; } michael@0: michael@0: bool IsLineStyleDefined() const michael@0: { michael@0: return (mDefinedStyles & DEFINED_LINESTYLE) != 0; michael@0: } michael@0: michael@0: bool IsForegroundColorDefined() const michael@0: { michael@0: return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0; michael@0: } michael@0: michael@0: bool IsBackgroundColorDefined() const michael@0: { michael@0: return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0; michael@0: } michael@0: michael@0: bool IsUnderlineColorDefined() const michael@0: { michael@0: return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0; michael@0: } michael@0: michael@0: bool IsNoChangeStyle() const michael@0: { michael@0: return !IsForegroundColorDefined() && !IsBackgroundColorDefined() && michael@0: IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE; michael@0: } michael@0: michael@0: bool Equals(const TextRangeStyle& aOther) michael@0: { michael@0: if (mDefinedStyles != aOther.mDefinedStyles) michael@0: return false; michael@0: if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle || michael@0: !mIsBoldLine != !aOther.mIsBoldLine)) michael@0: return false; michael@0: if (IsForegroundColorDefined() && michael@0: (mForegroundColor != aOther.mForegroundColor)) michael@0: return false; michael@0: if (IsBackgroundColorDefined() && michael@0: (mBackgroundColor != aOther.mBackgroundColor)) michael@0: return false; michael@0: if (IsUnderlineColorDefined() && michael@0: (mUnderlineColor != aOther.mUnderlineColor)) michael@0: return false; michael@0: return true; michael@0: } michael@0: michael@0: bool operator !=(const TextRangeStyle &aOther) michael@0: { michael@0: return !Equals(aOther); michael@0: } michael@0: michael@0: bool operator ==(const TextRangeStyle &aOther) michael@0: { michael@0: return Equals(aOther); michael@0: } michael@0: michael@0: uint8_t mDefinedStyles; michael@0: uint8_t mLineStyle; // DEFINED_LINESTYLE michael@0: michael@0: bool mIsBoldLine; // DEFINED_LINESTYLE michael@0: michael@0: nscolor mForegroundColor; // DEFINED_FOREGROUND_COLOR michael@0: nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR michael@0: nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR michael@0: }; michael@0: michael@0: /****************************************************************************** michael@0: * mozilla::TextRange michael@0: ******************************************************************************/ michael@0: michael@0: #define NS_TEXTRANGE_CARETPOSITION 0x01 michael@0: #define NS_TEXTRANGE_RAWINPUT 0x02 michael@0: #define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 michael@0: #define NS_TEXTRANGE_CONVERTEDTEXT 0x04 michael@0: #define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 michael@0: michael@0: struct TextRange michael@0: { michael@0: TextRange() : michael@0: mStartOffset(0), mEndOffset(0), mRangeType(0) michael@0: { michael@0: } michael@0: michael@0: uint32_t mStartOffset; michael@0: // XXX Storing end offset makes the initializing code very complicated. michael@0: // We should replace it with mLength. michael@0: uint32_t mEndOffset; michael@0: uint32_t mRangeType; michael@0: michael@0: TextRangeStyle mRangeStyle; michael@0: michael@0: uint32_t Length() const { return mEndOffset - mStartOffset; } michael@0: michael@0: bool IsClause() const michael@0: { michael@0: MOZ_ASSERT(mRangeType >= NS_TEXTRANGE_CARETPOSITION && michael@0: mRangeType <= NS_TEXTRANGE_SELECTEDCONVERTEDTEXT, michael@0: "Invalid range type"); michael@0: return mRangeType != NS_TEXTRANGE_CARETPOSITION; michael@0: } michael@0: }; michael@0: michael@0: /****************************************************************************** michael@0: * mozilla::TextRangeArray michael@0: ******************************************************************************/ michael@0: class TextRangeArray MOZ_FINAL : public nsAutoTArray michael@0: { michael@0: NS_INLINE_DECL_REFCOUNTING(TextRangeArray) michael@0: michael@0: public: michael@0: bool IsComposing() const michael@0: { michael@0: for (uint32_t i = 0; i < Length(); ++i) { michael@0: if (ElementAt(i).IsClause()) { michael@0: return true; michael@0: } michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: // Returns target clase offset. If there are selected clauses, this returns michael@0: // the first selected clause offset. Otherwise, 0. michael@0: uint32_t TargetClauseOffset() const michael@0: { michael@0: for (uint32_t i = 0; i < Length(); ++i) { michael@0: const TextRange& range = ElementAt(i); michael@0: if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT || michael@0: range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) { michael@0: return range.mStartOffset; michael@0: } michael@0: } michael@0: return 0; michael@0: } michael@0: }; michael@0: michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_TextRage_h_