diff options
author | Frank Schönheit <fs@openoffice.org> | 2009-09-25 12:01:08 +0000 |
---|---|---|
committer | Frank Schönheit <fs@openoffice.org> | 2009-09-25 12:01:08 +0000 |
commit | 5742e4ccc1b89d7db95cb9bdcfce4f5f1d46c1a4 (patch) | |
tree | ea0b09695188956bd6546db8928cecc73d97da2f /vcl | |
parent | 0a4c38a2a2f8c4c78cfff7d2e097be9155f666cc (diff) |
#b6875455# for the target device, always use the ref-device MapUnit during drawing, to have less rounding errors in case the ref device does not use TWIP. Also, implement filling the MetricVector
Diffstat (limited to 'vcl')
-rwxr-xr-x | vcl/source/gdi/textlayout.cxx | 90 |
1 files changed, 33 insertions, 57 deletions
diff --git a/vcl/source/gdi/textlayout.cxx b/vcl/source/gdi/textlayout.cxx index 3e9cdfad8c12..75d594258d1c 100755 --- a/vcl/source/gdi/textlayout.cxx +++ b/vcl/source/gdi/textlayout.cxx @@ -107,7 +107,7 @@ namespace vcl public: // equivalents to the respective OutputDevice methods, which take the reference device into account long GetTextArray( const XubString& _rText, sal_Int32* _pDXAry, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const; - Rectangle DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText); + Rectangle DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText ); protected: void onBeginDrawText() @@ -154,11 +154,13 @@ namespace vcl // also, use a higher-resolution map unit than "pixels", which should save us some rounding errors when // translating coordinates between the reference device and the target device. - const MapUnit eTargetMapUnit = MAP_TWIP; OSL_ENSURE( aTargetMapMode.GetMapUnit() == MAP_PIXEL, "ReferenceDeviceTextLayout::ReferenceDeviceTextLayout: this class is not expected to work with such target devices!" ); // we *could* adjust all the code in this class to handle this case, but at the moment, it's not necessary + const MapUnit eTargetMapUnit = m_rReferenceDevice.GetMapMode().GetMapUnit(); aTargetMapMode.SetMapUnit( eTargetMapUnit ); + OSL_ENSURE( aTargetMapMode.GetMapUnit() != MAP_PIXEL, + "ReferenceDeviceTextLayout::ReferenceDeviceTextLayout: a reference device which has map mode PIXEL?!" ); m_rTargetDevice.SetMapMode( aTargetMapMode ); @@ -195,48 +197,17 @@ namespace vcl _io_nLength = nTextLength - _nStartIndex; return true; } - - //................................................................ - class DeviceUnitMapping - { - public: - DeviceUnitMapping( const OutputDevice& _rTargetDevice, const OutputDevice& _rReferenceDevice ) - :m_eTargetMapUnit( _rTargetDevice.GetMapMode().GetMapUnit() ) - ,m_eRefMapUnit( _rReferenceDevice.GetMapMode().GetMapUnit() ) - { - OSL_ENSURE( m_eRefMapUnit != MAP_PIXEL, "a reference device with MAP_PIXEL?" ); - OSL_ENSURE( m_eTargetMapUnit != MAP_PIXEL, "we should have reset the target's map mode to TWIP!" ); - } - - long mapToTarget( long _nWidth ) - { - return OutputDevice::LogicToLogic( Size( _nWidth, 0 ), m_eRefMapUnit, m_eTargetMapUnit ).Width(); - } - long mapToReference( long _nWidth ) - { - return OutputDevice::LogicToLogic( Size( _nWidth, 0 ), m_eTargetMapUnit, m_eRefMapUnit ).Width(); - } - - private: - const MapUnit m_eTargetMapUnit; - const MapUnit m_eRefMapUnit; - }; } //-------------------------------------------------------------------- - long ReferenceDeviceTextLayout::GetTextArray( const XubString& _rText, sal_Int32* _pDXAry, xub_StrLen _nStartIndex, xub_StrLen _nLength ) const + long ReferenceDeviceTextLayout::GetTextArray( const XubString& _rText, sal_Int32* _pDXAry, xub_StrLen _nStartIndex, + xub_StrLen _nLength ) const { if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) ) return 0; - m_rReferenceDevice.SetLayoutMode( TEXT_LAYOUT_BIDI_LTR ); - // TODO: make this layout mode dependent on some educated guess about the text - // TODO: even better: break the text into script type portions ... but this way too far goes into the direction - // of re-implementing EditEngine and Writer-Code features here. - // retrieve the character widths from the reference device long nTextWidth = m_rReferenceDevice.GetTextArray( _rText, _pDXAry, _nStartIndex, _nLength ); - #if OSL_DEBUG_LEVEL > 1 if ( _pDXAry ) { @@ -256,15 +227,6 @@ namespace vcl OSL_TRACE( aTrace.makeStringAndClear().getStr() ); } #endif - // adjust the widths, which are in ref-device units, to the target device - DeviceUnitMapping aMapping( m_rTargetDevice, m_rReferenceDevice ); - if ( _pDXAry ) - { - for ( size_t i=0; i<_nLength; ++i ) - _pDXAry[i] = aMapping.mapToTarget( _pDXAry[i] ); - } - nTextWidth = aMapping.mapToTarget( nTextWidth ); - return nTextWidth; } @@ -280,16 +242,23 @@ namespace vcl if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) ) return; + if ( _pVector && _pDisplayText ) + { + MetricVector aGlyphBounds; + m_rReferenceDevice.GetGlyphBoundRects( _rStartPoint, _rText, _nStartIndex, _nLength, _nStartIndex, aGlyphBounds ); + ::std::copy( + aGlyphBounds.begin(), aGlyphBounds.end(), + ::std::insert_iterator< MetricVector > ( *_pVector, _pVector->end() ) ); + _pDisplayText->Append( _rText.Copy( _nStartIndex, _nLength ) ); + return; + } + sal_Int32* pCharWidths = new sal_Int32[ _nLength ]; long nTextWidth = GetTextArray( _rText, pCharWidths, _nStartIndex, _nLength ); m_rTargetDevice.DrawTextArray( _rStartPoint, _rText, pCharWidths, _nStartIndex, _nLength ); delete[] pCharWidths; m_aCompleteTextRect.Union( Rectangle( _rStartPoint, Size( nTextWidth, m_rTargetDevice.GetTextHeight() ) ) ); - - // TODO: use/fill those: - (void)_pVector; - (void)_pDisplayText; } //-------------------------------------------------------------------- @@ -303,11 +272,6 @@ namespace vcl if ( !m_rReferenceDevice.GetCaretPositions( _rText, _pCaretXArray, _nStartIndex, _nLength ) ) return false; - // adjust the positions, which are in ref-device units, to the target device - DeviceUnitMapping aMapping( m_rTargetDevice, m_rReferenceDevice ); - for ( size_t i=0; i<2*size_t(_nLength); ++i ) - _pCaretXArray[i] = aMapping.mapToTarget( _pCaretXArray[i] ); - return true; } @@ -317,8 +281,7 @@ namespace vcl if ( !lcl_normalizeLength( _rText, _nStartIndex, _nLength ) ) return 0; - DeviceUnitMapping aMapping( m_rTargetDevice, m_rReferenceDevice ); - return m_rReferenceDevice.GetTextBreak( _rText, aMapping.mapToReference( _nMaxTextWidth ), _nStartIndex, _nLength ); + return m_rReferenceDevice.GetTextBreak( _rText, _nMaxTextWidth, _nStartIndex, _nLength ); } //-------------------------------------------------------------------- @@ -344,7 +307,7 @@ namespace vcl } //-------------------------------------------------------------------- - Rectangle ReferenceDeviceTextLayout::DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText) + Rectangle ReferenceDeviceTextLayout::DrawText( const Rectangle& _rRect, const XubString& _rText, USHORT _nStyle, MetricVector* _pVector, String* _pDisplayText ) { if ( !_rText.Len() ) return Rectangle(); @@ -376,9 +339,22 @@ namespace vcl aTextRect = m_rTargetDevice.GetTextRect( aRect, _rText, _nStyle, NULL, this ); } - // similar to above, the text rect now contains TWIPs, but the caller expects pixel coordinates + // similar to above, the text rect now contains TWIPs (or whatever unit the ref device has), but the caller + // expects pixel coordinates aTextRect = m_rTargetDevice.LogicToPixel( aTextRect ); + // convert the metric vector + if ( _pVector ) + { + for ( MetricVector::iterator charRect = _pVector->begin(); + charRect != _pVector->end(); + ++charRect + ) + { + *charRect = m_rTargetDevice.LogicToPixel( *charRect ); + } + } + return aTextRect; } |