michael@0: /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- 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 GFX_DWRITETEXTANALYSIS_H michael@0: #define GFX_DWRITETEXTANALYSIS_H michael@0: michael@0: #include "gfxDWriteCommon.h" michael@0: michael@0: // Helper source/sink class for text analysis. michael@0: class TextAnalysis michael@0: : public IDWriteTextAnalysisSource, michael@0: public IDWriteTextAnalysisSink michael@0: { michael@0: public: michael@0: michael@0: // IUnknown interface michael@0: IFACEMETHOD(QueryInterface)(IID const& iid, OUT void** ppObject) michael@0: { michael@0: if (iid == __uuidof(IDWriteTextAnalysisSource)) { michael@0: *ppObject = static_cast(this); michael@0: return S_OK; michael@0: } else if (iid == __uuidof(IDWriteTextAnalysisSink)) { michael@0: *ppObject = static_cast(this); michael@0: return S_OK; michael@0: } else if (iid == __uuidof(IUnknown)) { michael@0: *ppObject = michael@0: static_cast(static_cast(this)); michael@0: return S_OK; michael@0: } else { michael@0: return E_NOINTERFACE; michael@0: } michael@0: } michael@0: michael@0: IFACEMETHOD_(ULONG, AddRef)() michael@0: { michael@0: return 1; michael@0: } michael@0: michael@0: IFACEMETHOD_(ULONG, Release)() michael@0: { michael@0: return 1; michael@0: } michael@0: michael@0: // A single contiguous run of characters containing the same analysis michael@0: // results. michael@0: struct Run michael@0: { michael@0: UINT32 mTextStart; // starting text position of this run michael@0: UINT32 mTextLength; // number of contiguous code units covered michael@0: UINT32 mGlyphStart; // starting glyph in the glyphs array michael@0: UINT32 mGlyphCount; // number of glyphs associated with this run of michael@0: // text michael@0: DWRITE_SCRIPT_ANALYSIS mScript; michael@0: UINT8 mBidiLevel; michael@0: bool mIsSideways; michael@0: michael@0: inline bool ContainsTextPosition(UINT32 aTextPosition) const michael@0: { michael@0: return aTextPosition >= mTextStart michael@0: && aTextPosition < mTextStart + mTextLength; michael@0: } michael@0: michael@0: Run *nextRun; michael@0: }; michael@0: michael@0: public: michael@0: TextAnalysis(const wchar_t* text, michael@0: UINT32 textLength, michael@0: const wchar_t* localeName, michael@0: DWRITE_READING_DIRECTION readingDirection); michael@0: michael@0: ~TextAnalysis(); michael@0: michael@0: STDMETHODIMP GenerateResults(IDWriteTextAnalyzer* textAnalyzer, michael@0: Run **runHead); michael@0: michael@0: // IDWriteTextAnalysisSource implementation michael@0: michael@0: IFACEMETHODIMP GetTextAtPosition(UINT32 textPosition, michael@0: OUT WCHAR const** textString, michael@0: OUT UINT32* textLength); michael@0: michael@0: IFACEMETHODIMP GetTextBeforePosition(UINT32 textPosition, michael@0: OUT WCHAR const** textString, michael@0: OUT UINT32* textLength); michael@0: michael@0: IFACEMETHODIMP_(DWRITE_READING_DIRECTION) michael@0: GetParagraphReadingDirection() throw(); michael@0: michael@0: IFACEMETHODIMP GetLocaleName(UINT32 textPosition, michael@0: OUT UINT32* textLength, michael@0: OUT WCHAR const** localeName); michael@0: michael@0: IFACEMETHODIMP michael@0: GetNumberSubstitution(UINT32 textPosition, michael@0: OUT UINT32* textLength, michael@0: OUT IDWriteNumberSubstitution** numberSubstitution); michael@0: michael@0: // IDWriteTextAnalysisSink implementation michael@0: michael@0: IFACEMETHODIMP michael@0: SetScriptAnalysis(UINT32 textPosition, michael@0: UINT32 textLength, michael@0: DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis); michael@0: michael@0: IFACEMETHODIMP michael@0: SetLineBreakpoints(UINT32 textPosition, michael@0: UINT32 textLength, michael@0: const DWRITE_LINE_BREAKPOINT* lineBreakpoints); michael@0: michael@0: IFACEMETHODIMP SetBidiLevel(UINT32 textPosition, michael@0: UINT32 textLength, michael@0: UINT8 explicitLevel, michael@0: UINT8 resolvedLevel); michael@0: michael@0: IFACEMETHODIMP michael@0: SetNumberSubstitution(UINT32 textPosition, michael@0: UINT32 textLength, michael@0: IDWriteNumberSubstitution* numberSubstitution); michael@0: michael@0: protected: michael@0: Run *FetchNextRun(IN OUT UINT32* textLength); michael@0: michael@0: void SetCurrentRun(UINT32 textPosition); michael@0: michael@0: void SplitCurrentRun(UINT32 splitPosition); michael@0: michael@0: protected: michael@0: // Input michael@0: // (weak references are fine here, since this class is a transient michael@0: // stack-based helper that doesn't need to copy data) michael@0: UINT32 mTextLength; michael@0: const wchar_t* mText; michael@0: const wchar_t* mLocaleName; michael@0: DWRITE_READING_DIRECTION mReadingDirection; michael@0: michael@0: // Current processing state. michael@0: Run *mCurrentRun; michael@0: michael@0: // Output is a list of runs starting here michael@0: Run mRunHead; michael@0: }; michael@0: michael@0: #endif /* GFX_DWRITETEXTANALYSIS_H */