diff options
Diffstat (limited to 'binfilter/bf_svx/source/xoutdev/svx__xfont.cxx')
-rw-r--r-- | binfilter/bf_svx/source/xoutdev/svx__xfont.cxx | 703 |
1 files changed, 703 insertions, 0 deletions
diff --git a/binfilter/bf_svx/source/xoutdev/svx__xfont.cxx b/binfilter/bf_svx/source/xoutdev/svx__xfont.cxx new file mode 100644 index 000000000000..fdbb82be370d --- /dev/null +++ b/binfilter/bf_svx/source/xoutdev/svx__xfont.cxx @@ -0,0 +1,703 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <vcl/metric.hxx> +#include <vcl/virdev.hxx> +#include <math.h> + +#include <bf_svx/xdef.hxx> + +#include "xoutx.hxx" + +// #101498# +#include "outliner.hxx" + + +#include <com/sun/star/i18n/ScriptType.hdl> + +#include <com/sun/star/i18n/XBreakIterator.hpp> + + +#include <com/sun/star/i18n/CharacterIteratorMode.hdl> + +#include "unolingu.hxx" +#include <legacysmgr/legacy_binfilters_smgr.hxx> //STRIP002 +namespace binfilter { +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::i18n; + +/************************************************************************* +|* +|* XOutGetCharOutline() +|* +|* Ein Zeichen eines Outlinefonts in ein Bezier-PolyPolygon umwandeln +|* Wenn keine Umwandlung moeglich ist, wird ein leeres PolyPolygon +|* zurueckgegeben +|* Ersterstellung 12.01.95 ESO +|* Letzte Aenderung 09.05.95 ESO +|* +*************************************************************************/ + +// #102382# Remove XOutGetCharOutline +// #100318# deprecated, use XOutGetTextOutline +//XPolyPolygon XOutGetCharOutline( USHORT nChar, OutputDevice& rOut, BOOL bOptimizeSize ) +//{ +// PolyPolygon aPolyPoly; +// +// //if( !rOut.GetGlyphOutline( (xub_Unicode) nChar, aPolyPoly, bOptimizeSize ) && rOut.GetOutDevType() == OUTDEV_PRINTER ) +// // #97492# +// String aGlyphString((xub_Unicode) nChar); +// +// if( !rOut.GetTextOutline(aPolyPoly, aGlyphString) && OUTDEV_PRINTER == rOut.GetOutDevType()) +// { +// VirtualDevice aVDev; +// aVDev.SetMapMode( rOut.GetMapMode() ); +// aVDev.SetFont( rOut.GetFont() ); +// aVDev.SetTextAlign( rOut.GetTextAlign() ); +// // #97492# +// //aVDev.GetGlyphOutline( (xub_Unicode) nChar, aPolyPoly, FALSE ); +// aVDev.GetTextOutline(aPolyPoly, aGlyphString); +// } +// +// // #97492# since GetTextOutline(...) is base line oriented, the +// // polygon needs to be moved one line height +// aPolyPoly.Move(0, rOut.GetFontMetric().GetAscent()); +// +// return XPolyPolygon( aPolyPoly ); +//} + +// #100318# new for XOutGetCharOutline +// #102382# new interface for XOutGetTextOutline to support PolyPolyVector +/*N*/ sal_Bool XOutGetTextOutlines(PolyPolyVector& rPolyPolyVector, const String& rText, OutputDevice& rOut, +/*N*/ xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen) +/*N*/ { +/*N*/ // #102382# use GetTextOutlines and PolyPolyVector now +/*N*/ if(!rOut.GetTextOutlines(rPolyPolyVector, rText, nBase, nIndex, nLen) && OUTDEV_PRINTER == rOut.GetOutDevType()) +/*N*/ { +/*?*/ VirtualDevice aVDev; +/*?*/ +/*?*/ aVDev.SetMapMode(rOut.GetMapMode()); +/*?*/ aVDev.SetFont(rOut.GetFont()); +/*?*/ aVDev.SetTextAlign(rOut.GetTextAlign()); +/*?*/ +/*?*/ // #102382# use GetTextOutlines and PolyPolyVector now +/*?*/ aVDev.GetTextOutlines(rPolyPolyVector, rText, nBase, nIndex, nLen); +/*N*/ } + + // since GetTextOutline(...) is base line oriented, the + // polygon needs to be moved one line height + // #102382# now a loop is necessary for moving all contained single PolyPolygons +/*N*/ for(sal_uInt32 a(0); a < rPolyPolyVector.size(); a++) +/*N*/ { +/*N*/ rPolyPolyVector[a].Move(0, rOut.GetFontMetric().GetAscent()); +/*N*/ } +/*N*/ +/*N*/ return (rPolyPolyVector.size() != 0); +/*N*/ } + +/************************************************************************* +|* +|* XOutputDevice::ImpDrawFormText(String, Polygon, Font, nAbsStart) +|* +|* Einen String entlang eines Polygons ausgeben; nAbsStart +|* ueberschreibt den XFormTextStartItem-Wert und wird fuer die +|* Ausgabe mehrerer Strings entlang des gleichen Polygons benoetigt. +|* Rueckgabewert ist die Endposition des ausgegebenen Textes in +|* Bezug auf den Linienanfang. +|* +|* nAbsStart < 0: Die Gesamtlaenge aller Strings, notwendig fuer +|* alle Formatierungen ausser Linksbuendig +|* <= 0: Item-Startwert verwenden +|* > 0: Text an dieser absoluten Position ausgeben; ist +|* normalerweise der Rueckgabewert eines vorigen +|* DrawFormText-Aufrufs +|* +|* bToLastPoint: alle Linien einschliesslich der letzten Zeichnen, +|* sonst die letzte Linie auslassen +|* +|* bDraw: wenn FALSE, wird nichts ausgegeben, sondern nur das BoundRect +|* berechnet +|* +|* pDXArray: wenn vorhanden, enthaelt dieses Array die horizontalen +|* Positionen der einzelnen Zeichen, beginnend beim ersten +|* und endend hinter dem letzten Zeichen; es muß also +|* rText.Len()-1 long-Werte enthalten +|* +|* +|* Ersterstellung 02.02.95 ESO +|* Letzte Aenderung 11.10.95 ESO +|* +*************************************************************************/ + +// #101498# Helper method ImpGetTextLength to get text length taking into account +// hor/vertical and BIDI, especially right-to-left. +/*N*/ sal_Int32 ImpGetTextLength(OutputDevice* pOut, DrawPortionInfo* pInfo, sal_Int32* pDXArray, +/*N*/ xub_StrLen nIndex, xub_StrLen nLen) +/*N*/ { +/*N*/ sal_Bool bRightToLeft = pInfo->IsRTL(); +/*N*/ sal_Int32 nRetval(0L); +/*N*/ +/*N*/ if(pInfo->rFont.IsVertical()) +/*N*/ { +/*?*/ nRetval = pOut->GetTextHeight() * (sal_Int32)nLen; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ if(bRightToLeft) +/*N*/ { +/*?*/ nRetval = pOut->GetTextArray(pInfo->rText, pDXArray, +/*?*/ pInfo->nTextStart + (pInfo->nTextLen - (nIndex + nLen)), +/*?*/ nLen); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nRetval = pOut->GetTextArray(pInfo->rText, pDXArray, +/*N*/ pInfo->nTextStart + nIndex, +/*N*/ nLen); +/*N*/ } +/*N*/ } +/*N*/ +/*N*/ return nRetval; +/*N*/ } + +// #101498# Helper method ImpDrawTextArray to draw text taking into account +// hor/vertical and BIDI, especially right-to-left. + +// #101498# Helper method ImpXOutGetTextOutline to get text outline taking into account +// hor/vertical and BIDI, especially right-to-left. +// #102382# new interface for XOutGetTextOutline to support PolyPolyVector +/*N*/ sal_Bool ImpXOutGetTextOutlines(PolyPolyVector& rPolyPolyVector, OutputDevice* pOut, DrawPortionInfo* pInfo, +/*N*/ xub_StrLen nIndex, xub_StrLen nLen) +/*N*/ { +/*N*/ sal_Bool bRightToLeft(pInfo->IsRTL()); +/*N*/ +/*N*/ if(bRightToLeft) +/*N*/ { +/*?*/ return XOutGetTextOutlines(rPolyPolyVector, pInfo->rText, *pOut, +/*?*/ pInfo->nTextStart + (pInfo->nTextLen - (nIndex + nLen)), +/*?*/ pInfo->nTextStart + (pInfo->nTextLen - (nIndex + nLen)), +/*?*/ nLen); +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ return XOutGetTextOutlines(rPolyPolyVector, pInfo->rText, *pOut, +/*N*/ pInfo->nTextStart + nIndex, +/*N*/ pInfo->nTextStart + nIndex, +/*N*/ nLen); +/*N*/ } +/*N*/ } + +// #101498# changed interface due to bidi requirements +/*N*/ sal_Int32 XOutputDevice::ImpDrawFormText(DrawPortionInfo* pInfo, const Polygon& rPoly, sal_Int32 nAbsStart, +/*N*/ sal_Bool bToLastPoint, sal_Bool bDraw, sal_Bool bIsShadow) +/*N*/ { +/*N*/ Font aFont = pInfo->rFont; +/*N*/ const sal_Int32* pDXArray = pInfo->pDXArray; +/*N*/ sal_Bool bUseBreakIterator(sal_False); +/*N*/ +/*N*/ Reference < ::com::sun::star::i18n::XBreakIterator > xBreak; +/*N*/ Reference < XMultiServiceFactory > xMSF = ::legacy_binfilters::getLegacyProcessServiceFactory(); +/*N*/ Reference < XInterface > xInterface = xMSF->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")); +/*N*/ ::com::sun::star::lang::Locale aFontLocale = SvxCreateLocale(pInfo->rFont.GetLanguage()); +/*N*/ +/*N*/ if(xInterface.is()) +/*N*/ { +/*N*/ Any x = xInterface->queryInterface(::getCppuType((const Reference< XBreakIterator >*)0)); +/*N*/ x >>= xBreak; +/*N*/ } +/*N*/ +/*N*/ if(xBreak.is()) +/*N*/ { +/*N*/ bUseBreakIterator = sal_True; +/*N*/ } +/*N*/ +/*N*/ long nXMin = LONG_MAX, nYMin = LONG_MAX; +/*N*/ long nXMax = LONG_MIN, nYMax = LONG_MIN; +/*N*/ long nMaxCharExtent; +/*N*/ long nPolyLen = 0; +/*N*/ long nTextLen = 0; +/*N*/ long nTotal = 0; +/*N*/ long nTextWidth; +/*N*/ long nStart; +/*N*/ long nShadowX; +/*N*/ USHORT nPntCnt = rPoly.GetSize(); +/*N*/ USHORT nLastPnt; +/*N*/ USHORT nPnt; +/*N*/ xub_StrLen nChar(0); +/*N*/ const xub_StrLen nCharCnt(pInfo->nTextLen); +/*N*/ short nDirection; + +/*N*/ if ( nPntCnt < 2 || !nCharCnt) +/*N*/ return 0; + +/*N*/ BOOL bIsSlantShadow = ( bIsShadow && eFormTextShadow == XFTSHADOW_SLANT ); +/*N*/ BOOL bDrawAsPoly = ( bFormTextOutline || bIsSlantShadow ); + +/*N*/ if ( nAbsStart > 0 ) nStart = nAbsStart; +/*N*/ else nStart = nFormTextStart; + +/*N*/ aFont.SetTransparent(TRUE); + + // Attribute sichern +/*N*/ XLineStyle eOldLineStyle = eLineStyle; +/*N*/ XFillStyle eOldFillStyle = eFillStyle; + +/*N*/ Color aOldLineColor( pOut->GetLineColor() ); + +/*N*/ pOut->SetFillColor( aFont.GetColor() ); + +/*N*/ if ( !(bFormTextOutline && bHair) || bIsShadow ) +/*N*/ pOut->SetLineColor(); +/*N*/ +/*N*/ if ( !bFormTextOutline || bIsShadow ) +/*N*/ eLineStyle = XLINE_NONE; +/*N*/ +/*N*/ eFillStyle = XFILL_SOLID; +/*N*/ +/*N*/ if ( eFormTextAdjust == XFT_AUTOSIZE && nAbsStart > 0 ) +/*?*/ aFont.SetSize(Size(0, nFtAutoHeightSave)); +/*N*/ +/*N*/ Font aOldFont = pOut->GetFont(); +/*N*/ pOut->SetFont(aFont); +/*N*/ long nAscent = pOut->GetFontMetric().GetAscent(); +/*N*/ +/*N*/ // #78478# outline text in FontWork +/*N*/ if(bFormTextOutline) +/*N*/ { +/*?*/ eLineStyle = XLINE_SOLID; +/*?*/ pOut->SetLineColor(aLineColor); +/*N*/ } +/*N*/ +/*N*/ if ( eFormTextAdjust == XFT_AUTOSIZE ) +/*N*/ { +/*N*/ // bei Autosize den Arrayinhalt immer ignorieren +/*N*/ pDXArray = NULL; +/*N*/ } +/*N*/ +/*N*/ nTextWidth = ImpGetTextLength(pOut, pInfo, const_cast<sal_Int32*>(pDXArray), 0, pInfo->nTextLen); +/*N*/ +/*N*/ if ( eFormTextAdjust != XFT_LEFT && nAbsStart <= 0 ) +/*N*/ { +/*N*/ // Gesamtlaenge des Polygons berechnen +/*N*/ USHORT nMax = nPntCnt; +/*N*/ nPnt = 1; +/*N*/ +/*N*/ if ( !bToLastPoint ) +/*N*/ nMax--; +/*N*/ +/*N*/ for ( ; nPnt < nMax; nPnt++) +/*N*/ { +/*N*/ double fDx = rPoly[nPnt].X() - rPoly[nPnt-1].X(); +/*N*/ double fDy = rPoly[nPnt].Y() - rPoly[nPnt-1].Y(); +/*N*/ nPolyLen += (long) (sqrt(fDx * fDx + fDy * fDy) + 0.5); +/*N*/ } +/*N*/ +/*N*/ if ( nAbsStart == 0 ) +/*N*/ nAbsStart = - nTextWidth; +/*N*/ +/*N*/ if ( eFormTextAdjust == XFT_AUTOSIZE ) +/*N*/ { +/*N*/ nFtAutoHeightSave = aFont.GetSize().Height(); +/*N*/ nFtAutoHeightSave = - (nPolyLen * nFtAutoHeightSave / nAbsStart); +/*N*/ aFont.SetSize(Size(0, nFtAutoHeightSave)); +/*N*/ pOut->SetFont(aFont); +/*N*/ nFtAutoHeightSave = aFont.GetSize().Height(); +/*N*/ nTextWidth = pOut->GetTextWidth(pInfo->rText, pInfo->nTextStart, pInfo->nTextLen); +/*N*/ nAscent = pOut->GetFontMetric().GetAscent(); +/*N*/ nAbsStart = - nPolyLen; +/*N*/ } +/*N*/ // Bei rechtsbuendiger Ausgabe auch Startposition beruecksichtigen +/*N*/ if ( eFormTextAdjust == XFT_RIGHT ) +/*N*/ nAbsStart -= nStart; +/*N*/ nStart = nPolyLen + nAbsStart; +/*N*/ +/*N*/ if ( eFormTextAdjust != XFT_RIGHT ) +/*N*/ nStart /= 2; +/*N*/ } +/*N*/ if ( nStart < 0 ) +/*N*/ nStart = 0; +/*N*/ +/*N*/ if ( bIsShadow && eFormTextShadow != XFTSHADOW_SLANT ) +/*N*/ nShadowX = nFormTextShdwXVal; +/*N*/ else +/*N*/ nShadowX = 0; +/*N*/ +/*N*/ nTotal = nStart + nTextWidth; +/*N*/ +/*N*/ if ( bIsShadow && eFormTextShadow == XFTSHADOW_SLANT && +/*N*/ nFormTextShdwYVal && nFormTextShdwYVal != 100 ) +/*N*/ nAscent = nAscent * nFormTextShdwYVal / 100; +/*N*/ +/*N*/ // Maximaler Zeichenbereich ca. 1,4 (sqrt(2)) * Ascent fuer BoundRect +/*N*/ nMaxCharExtent = nAscent * 7 / 5; +/*N*/ +/*N*/ // Laufrichtung des Polygons ggf. spiegeln +/*N*/ if ( bFormTextMirror ) +/*N*/ { +/*N*/ nDirection = -1; +/*N*/ nLastPnt = (USHORT) -1; +/*N*/ nPnt = nPntCnt - 2; +/*N*/ if ( !bToLastPoint ) +/*N*/ nPnt--; +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ nDirection = 1; +/*N*/ nLastPnt = nPntCnt - 1; +/*N*/ nPnt = 1; +/*N*/ if ( bToLastPoint ) +/*N*/ nLastPnt++; +/*N*/ } +/*N*/ +/*N*/ while ( nChar < nCharCnt && nPnt != nLastPnt ) +/*N*/ { +/*N*/ xub_StrLen nGlyphLen(1); +/*N*/ +/*N*/ if(bUseBreakIterator) +/*N*/ { +/*N*/ sal_Int32 nDone(0L); +/*N*/ nGlyphLen = (xub_StrLen)xBreak->nextCharacters( pInfo->rText, nChar + pInfo->nTextStart, aFontLocale, +/*N*/ CharacterIteratorMode::SKIPCELL, 1, nDone) - (nChar + pInfo->nTextStart); +/*N*/ } +/*N*/ +/*N*/ Point aPos = rPoly[nPnt]; +/*N*/ double fDx, fDy, fLen; +/*N*/ long nLen, nChar1Len; +/*N*/ +/*N*/ fDx = aPos.X() - rPoly[nPnt-nDirection].X(); +/*N*/ fDy = aPos.Y() - rPoly[nPnt-nDirection].Y(); +/*N*/ fLen = sqrt(fDx * fDx + fDy * fDy); +/*N*/ nLen = (long) (fLen + 0.5); +/*N*/ +/*N*/ nChar1Len = ImpGetTextLength(pOut, pInfo, const_cast<sal_Int32*>(pDXArray), nChar, nGlyphLen); +/*N*/ +/*N*/ double fXDist, fYDist; +/*N*/ double fCos = fDx; +/*N*/ double fSin = fDy; +/*N*/ double fPartLen = fLen; +/*N*/ double fLenSum = fLen - nTextLen; +/*N*/ USHORT nSumPnt = nPnt + nDirection; +/*N*/ +/*N*/ // Laenge halbieren, um Zeichenmitte als Referenzpunkt zu verwenden +/*N*/ nChar1Len /= 2; +/*N*/ +/*N*/ while ( nSumPnt != nLastPnt && fLenSum < nChar1Len ) +/*N*/ { +/*N*/ fCos = rPoly[nSumPnt].X() - rPoly[nSumPnt-nDirection].X(); +/*N*/ fSin = rPoly[nSumPnt].Y() - rPoly[nSumPnt-nDirection].Y(); +/*N*/ fPartLen = sqrt(fSin * fSin + fCos * fCos); +/*N*/ fLenSum += fPartLen; +/*N*/ nSumPnt += nDirection; +/*N*/ } +/*N*/ fSin /= - fPartLen; +/*N*/ fCos /= fPartLen; +/*N*/ +/*N*/ fXDist = fSin * nFormTextDistance; +/*N*/ fYDist = fCos * nFormTextDistance; +/*N*/ +/*N*/ if ( nStart > 0 ) +/*N*/ nStart -= nLen; +/*N*/ else +/*N*/ { +/*N*/ nLen -= nTextLen; +/*N*/ nTextLen = - nLen; +/*N*/ } +/*N*/ +/*N*/ if ( nLen > 0 && nStart <= 0 ) +/*N*/ { +/*N*/ xub_StrLen nCnt(0); +/*N*/ +/*N*/ if ( nStart < 0 ) +/*N*/ { +/*N*/ nLen = - nStart; +/*N*/ nStart = 0; +/*N*/ } +/*N*/ +/*N*/ do +/*N*/ { +/*N*/ xub_StrLen nNextGlyphLen(1); +/*N*/ +/*N*/ if(bUseBreakIterator) +/*N*/ { +/*N*/ sal_Int32 nDone(0L); +/*N*/ nNextGlyphLen = (xub_StrLen)xBreak->nextCharacters( pInfo->rText, nChar + pInfo->nTextStart + nCnt, aFontLocale, +/*N*/ CharacterIteratorMode::SKIPCELL, 1, nDone) - (nChar + pInfo->nTextStart + nCnt); +/*N*/ } +/*N*/ +/*N*/ nTextLen = ImpGetTextLength(pOut, pInfo, const_cast<sal_Int32*>(pDXArray), nChar, nCnt + nNextGlyphLen); +/*N*/ +/*N*/ nCnt += nNextGlyphLen; +/*N*/ } +/*N*/ while ( nChar + nCnt < nCharCnt && nTextLen < nLen ); +/*N*/ +/*N*/ aPos.X() -= (long) (fDx * (nLen - nShadowX) / fLen + fXDist); +/*N*/ aPos.Y() -= (long) (fDy * (nLen - nShadowX) / fLen + fYDist); +/*N*/ +/*N*/ // BoundRect-Approximation +/*N*/ nXMin = Min(nXMin, aPos.X() - nMaxCharExtent); +/*N*/ nYMin = Min(nYMin, aPos.Y() - nMaxCharExtent); +/*N*/ nXMax = Max(nXMax, aPos.X() + nMaxCharExtent); +/*N*/ nYMax = Max(nYMax, aPos.Y() + nMaxCharExtent); +/*N*/ +/*N*/ if ( eFormTextStyle == XFT_ROTATE ) +/*N*/ { +/*N*/ if ( bDrawAsPoly ) +/*N*/ { +/*N*/ // #101145# Do create outline polygons more efficient +/*N*/ // #102382# new interface supporting PolyPolyVector +/*N*/ PolyPolyVector aPolyPolyVector; +/*N*/ sal_Bool bOkay(ImpXOutGetTextOutlines(aPolyPolyVector, pOut, pInfo, nChar, nCnt)); +/*N*/ +/*N*/ // #102382# iterate over single PolyPolygons +/*N*/ for(sal_uInt32 a(0); a < aPolyPolyVector.size(); a++) +/*N*/ { +/*N*/ PolyPolygon aPolyPoly(aPolyPolyVector[a]); +/*N*/ +/*N*/ if(aPolyPoly.Count() > 0 && aPolyPoly[0].GetSize() > 0) +/*N*/ { +/*N*/ XPolyPolygon aChar(aPolyPoly); +/*N*/ +/*N*/ // #102382# new interface supporting PolyPolyVector +/*N*/ if(bIsSlantShadow) +/*N*/ { +/*N*/ if(nFormTextShdwYVal && 100 != nFormTextShdwYVal) +/*N*/ { +/*?*/ aChar.Scale(1.0, (double)nFormTextShdwYVal / 100.0); +/*N*/ } +/*N*/ +/*N*/ aChar.SlantX(nAscent, +/*N*/ sin(- F_PI * nFormTextShdwXVal / 1800.0), +/*N*/ cos(- F_PI * nFormTextShdwXVal / 1800.0)); +/*N*/ } +/*N*/ +/*N*/ aChar.Translate(Point(aPos.X(), aPos.Y() - nAscent)); +/*N*/ aChar.Rotate(aPos, fSin, fCos); +/*N*/ +/*N*/ if(bDraw) +/*N*/ { +/*?*/ DrawXPolyPolygon(aChar); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ // #83801# vertical writing for contour +/*?*/ if(aFont.IsVertical()) +/*?*/ { +/*?*/ short nAngle = (short) (acos(fCos) * 1800 / F_PI + 0.5); +/*?*/ if(fSin < 0) +/*?*/ nAngle = 3600 - nAngle; +/*?*/ nAngle += 2700; +/*?*/ aFont.SetOrientation(nAngle); +/*?*/ pOut->SetFont(aFont); +/*?*/ if(bDraw) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*?*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*N*/ short nAngle = (short) (acos(fCos) * 1800 / F_PI + 0.5); +/*N*/ if(fSin < 0) +/*N*/ nAngle = 3600 - nAngle; +/*N*/ aFont.SetOrientation(nAngle); +/*N*/ pOut->SetFont(aFont); +/*N*/ if(bDraw) +/*N*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ImpDrawTextArray(pOut, aPos, pInfo, (long*)pDXArray, nChar, nCnt); +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ } +/*N*/ else +/*N*/ { +/*?*/ bDrawAsPoly = ( bDrawAsPoly || eFormTextStyle != XFT_UPRIGHT); +/*?*/ +/*?*/ for (xub_StrLen i = 0; i < nCnt;) +/*?*/ { +/*?*/ xub_StrLen nNextGlyphLen(1); +/*?*/ +/*?*/ if(bUseBreakIterator) +/*?*/ { +/*?*/ sal_Int32 nDone(0L); +/*?*/ nNextGlyphLen = (xub_StrLen)xBreak->nextCharacters( pInfo->rText, nChar + pInfo->nTextStart + i, aFontLocale, +/*?*/ CharacterIteratorMode::SKIPCELL, 1, nDone) - (nChar + pInfo->nTextStart + i); +/*?*/ } +/*?*/ +/*?*/ XPolyPolygon aChar(0); +/*?*/ Point aPolyPos = aPos; +/*?*/ +/*?*/ if ( i > 0 ) +/*?*/ { +/*?*/ long nW; +/*?*/ +/*?*/ nW = ImpGetTextLength(pOut, pInfo, const_cast<sal_Int32*>(pDXArray), nChar, i); +/*?*/ +/*?*/ aPolyPos.X() += (long) (fDx * nW / fLen); +/*?*/ aPolyPos.Y() += (long) (fDy * nW / fLen); +/*?*/ } +/*?*/ if ( bDrawAsPoly ) +/*?*/ { +/*?*/ // #100318# new for XOutGetCharOutline +/*?*/ // #102382# new interface supporting PolyPolyVector +/*?*/ PolyPolyVector aPolyPolyVector; +/*?*/ +/*?*/ // #108756# +/*?*/ // Here the wrong index was called for the ImpXOutGetTextOutlines(...) +/*?*/ // call. nChar needs to be added here to index the different characters. +/*?*/ sal_Bool bOkay(ImpXOutGetTextOutlines(aPolyPolyVector, pOut, pInfo, nChar + i, nNextGlyphLen)); +/*?*/ +/*?*/ // #102382# iterate over single PolyPolygons +/*?*/ for(sal_uInt32 a(0); a < aPolyPolyVector.size(); a++) +/*?*/ { +/*?*/ PolyPolygon aPolyPoly(aPolyPolyVector[a]); +/*?*/ +/*?*/ if(aPolyPoly.Count() > 0 && aPolyPoly[0].GetSize() > 0) +/*?*/ {DBG_BF_ASSERT(0, "STRIP");//STRIP001 +/*?*/ } +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ if ( eFormTextStyle == XFT_SLANTY ) +/*?*/ {DBG_BF_ASSERT(0, "STRIP"); //STRIP001 +/*?*/ } +/*?*/ else +/*?*/ { +/*?*/ long nW; +/*?*/ +/*?*/ nW = ImpGetTextLength(pOut, pInfo, const_cast<sal_Int32*>(pDXArray), nChar + i, nNextGlyphLen); +/*?*/ +/*?*/ aPolyPos.X() -= nW / 2; +/*?*/ +/*?*/ if ( eFormTextStyle == XFT_SLANTX ) +/*?*/ { +/*?*/ aPolyPos.X() += (long) (fDy * nAscent / fLen); +/*?*/ aPolyPos.Y() -= (long) (fDx * nAscent / fLen); +/*?*/ aChar.SlantX(0, fSin, fCos); +/*?*/ } +/*?*/ else if ( bDrawAsPoly ) +/*?*/ aPolyPos.Y() -= nAscent; +/*?*/ } +/*?*/ aChar.Translate(aPolyPos); +/*?*/ +/*?*/ if ( bDraw ) +/*?*/ { +/*?*/ if ( bDrawAsPoly ) +/*?*/ DrawXPolyPolygon(aChar); +/*?*/ else +/*?*/ { +/*?*/ DBG_BF_ASSERT(0, "STRIP"); //STRIP001 ImpDrawTextArray(pOut, aPolyPos, pInfo, (long*)pDXArray, nChar + i, nNextGlyphLen); +/*?*/ } +/*?*/ } +/*?*/ +/*?*/ i += nNextGlyphLen; +/*?*/ } +/*N*/ } +/*N*/ nChar += nCnt; +/*N*/ nTextLen -= nLen; +/*N*/ } +/*N*/ nPnt += nDirection; +/*N*/ } +/*N*/ // auch letzten Punkt fuer BoundRect-Approximation beruecksichtigen +/*N*/ Point aPos = rPoly[nPnt - nDirection]; +/*N*/ nXMin = Min(nXMin, aPos.X() - nMaxCharExtent); +/*N*/ nYMin = Min(nYMin, aPos.Y() - nMaxCharExtent); +/*N*/ nXMax = Max(nXMax, aPos.X() + nMaxCharExtent); +/*N*/ nYMax = Max(nYMax, aPos.Y() + nMaxCharExtent); + +/*N*/ aFormTextBoundRect.Union(Rectangle(nXMin, nYMin, nXMax, nYMax)); +/*N*/ +/*N*/ pOut->SetFont(aOldFont); +/*N*/ pOut->SetLineColor( aOldLineColor ); +/*N*/ eLineStyle = eOldLineStyle; +/*N*/ eFillStyle = eOldFillStyle; +/*N*/ +/*N*/ return nTotal; +/*N*/ } + +// #101498# changed interface due to bidi requirements +/*N*/ void XOutputDevice::ImpDrawFormTextShadow(DrawPortionInfo* pInfo, const Polygon& rPoly, sal_Int32 nAbsStart, sal_Bool bToLastPoint, sal_Bool bDraw) +/*N*/ { +/*N*/ if(XFTSHADOW_NONE != eFormTextShadow) +/*N*/ { +/*N*/ sal_Bool bOutline(bFormTextOutline); +/*N*/ Font aShadowFont(pInfo->rFont); +/*N*/ +/*N*/ aShadowFont.SetColor(aFormTextShdwColor); +/*N*/ +/*N*/ DrawPortionInfo aNewInfo( +/*N*/ pInfo->rStartPos, +/*N*/ pInfo->rText, +/*N*/ pInfo->nTextStart, +/*N*/ pInfo->nTextLen, +/*N*/ aShadowFont, +/*N*/ pInfo->nPara, +/*N*/ pInfo->nIndex, +/*N*/ pInfo->pDXArray, +/*N*/ pInfo->GetBiDiLevel()); +/*N*/ +/*N*/ if(XFTSHADOW_SLANT != eFormTextShadow) +/*N*/ { +/*N*/ nFormTextDistance += nFormTextShdwYVal; +/*N*/ } +/*N*/ +/*N*/ ImpDrawFormText(&aNewInfo, rPoly, nAbsStart, bToLastPoint, bDraw, sal_True); +/*N*/ +/*N*/ if(XFTSHADOW_SLANT != eFormTextShadow) +/*N*/ { +/*N*/ nFormTextDistance -= nFormTextShdwYVal; +/*N*/ } +/*N*/ +/*N*/ bFormTextOutline = bOutline; +/*N*/ } +/*N*/ } + +/************************************************************************* +|* +*************************************************************************/ + +// #101498# changed interface due to bidi requirements +/*N*/ sal_Int32 XOutputDevice::DrawFormText(DrawPortionInfo* pInfo, const Polygon& rPoly, +/*N*/ sal_Int32 nAbsStart, sal_Bool bToLastPoint, sal_Bool bDraw) +/*N*/ { +/*N*/ if(nAbsStart <= 0L) +/*N*/ { +/*N*/ // empty BoundRect at first call +/*N*/ aFormTextBoundRect = Rectangle(); +/*N*/ } +/*N*/ +/*N*/ ImpDrawFormTextShadow(pInfo, rPoly, nAbsStart, bToLastPoint, bDraw); +/*N*/ +/*N*/ return ImpDrawFormText(pInfo, rPoly, nAbsStart, bToLastPoint, bDraw, sal_False); +/*N*/ } + +// eof +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |