// Run modification. TextAnalysis::LinkedRun& TextAnalysis::FetchNextRun( _Inout_ UINT32* textLength ) { // Used by the sink setters, this returns a reference to the next run. // Position and length are adjusted to now point after the current run // being returned. UINT32 runIndex = m_currentRunIndex; UINT32 runTextLength = m_runs[m_currentRunIndex].textLength; // Split the tail if needed (the length remaining is less than the // current run's size). if (*textLength < runTextLength) { runTextLength = *textLength; // Limit to what's actually left. UINT32 runTextStart = m_runs[m_currentRunIndex].textStart; SplitCurrentRun(runTextStart + runTextLength); } else { // Just advance the current run. m_currentRunIndex = m_runs[m_currentRunIndex].nextRunIndex; } *textLength -= runTextLength; // Return a reference to the run that was just current. return m_runs[runIndex]; }
IFACEMETHODIMP TextAnalysis::SetBidiLevel( UINT32 textPosition, UINT32 textLength, UINT8 explicitLevel, UINT8 resolvedLevel ) { try { SetCurrentRun(textPosition); SplitCurrentRun(textPosition); while (textLength > 0) { LinkedRun& run = FetchNextRun(&textLength); run.bidiLevel = resolvedLevel; run.isReversed = !!(resolvedLevel & 1); } } catch (...) { return E_FAIL; // Unknown error, probably out of memory. } return S_OK; }
IFACEMETHODIMP TextAnalysis::SetScriptAnalysis(UINT32 textPosition, UINT32 textLength, DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis) { SetCurrentRun(textPosition); SplitCurrentRun(textPosition); while (textLength > 0) { Run *run = FetchNextRun(&textLength); run->mScript = *scriptAnalysis; } return S_OK; }
IFACEMETHODIMP TextAnalysis::SetBidiLevel(UINT32 textPosition, UINT32 textLength, UINT8 explicitLevel, UINT8 resolvedLevel) { SetCurrentRun(textPosition); SplitCurrentRun(textPosition); while (textLength > 0) { Run *run = FetchNextRun(&textLength); run->mBidiLevel = resolvedLevel; } return S_OK; }
TextAnalysis::Run * TextAnalysis::FetchNextRun(IN OUT UINT32* textLength) { // Used by the sink setters, this returns a reference to the next run. // Position and length are adjusted to now point after the current run // being returned. Run *origRun = mCurrentRun; // Split the tail if needed (the length remaining is less than the // current run's size). if (*textLength < mCurrentRun->mTextLength) { SplitCurrentRun(mCurrentRun->mTextStart + *textLength); } else { // Just advance the current run. mCurrentRun = mCurrentRun->nextRun; } *textLength -= origRun->mTextLength; // Return a reference to the run that was just current. return origRun; }
IFACEMETHODIMP TextAnalysis::SetNumberSubstitution( UINT32 textPosition, UINT32 textLength, IDWriteNumberSubstitution* numberSubstitution ) { try { SetCurrentRun(textPosition); SplitCurrentRun(textPosition); while (textLength > 0) { LinkedRun& run = FetchNextRun(&textLength); run.isNumberSubstituted = (numberSubstitution != nullptr); } } catch (...) { return E_FAIL; // Unknown error, probably out of memory. } return S_OK; }
IFACEMETHODIMP TextAnalysis::SetScriptAnalysis( UINT32 textPosition, UINT32 textLength, DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis ) { try { SetCurrentRun(textPosition); SplitCurrentRun(textPosition); while (textLength > 0) { LinkedRun& run = FetchNextRun(&textLength); run.script = *scriptAnalysis; } } catch (...) { return E_FAIL; // Unknown error, probably out of memory. } return S_OK; }
IFACEMETHODIMP TextAnalysis::SetGlyphOrientation( UINT32 textPosition, UINT32 textLength, DWRITE_GLYPH_ORIENTATION_ANGLE glyphOrientationAngle, UINT8 adjustedBidiLevel, BOOL isSideways, BOOL isRightToLeft ) { try { // Mapping from angle down to small orientation. const static UINT8 glyphOrientations[] = { GlyphOrientationCW0, GlyphOrientationCW90, GlyphOrientationCW180, GlyphOrientationCW270, }; SetCurrentRun(textPosition); SplitCurrentRun(textPosition); while (textLength > 0) { LinkedRun& run = FetchNextRun(&textLength); run.glyphOrientation = glyphOrientations[glyphOrientationAngle & 3]; run.isSideways = !!isSideways; run.isReversed = !!isRightToLeft; run.bidiLevel = adjustedBidiLevel; } } catch (...) { return E_FAIL; // Unknown error, probably out of memory. } return S_OK; }