diff options
233 files changed, 14276 insertions, 3741 deletions
diff --git a/basebmp/test/makefile.mk b/basebmp/test/makefile.mk index 43165b831a64..7d0dc6e3967a 100644 --- a/basebmp/test/makefile.mk +++ b/basebmp/test/makefile.mk @@ -132,6 +132,6 @@ unittest : $(SHL1TARGETN) @echo ---------------------------------------------------------- @echo - start unit test on library $(SHL1TARGETN) @echo ---------------------------------------------------------- - $(AUGMENT_LIBRARY_PATH) testshl2 -sf $(mktmp ) $(SHL1TARGETN) + $(TESTSHL2) -sf $(mktmp ) $(SHL1TARGETN) ALLTAR : unittest diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx index 9474e51e3904..12532ff078f3 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolypolygoncutter.hxx @@ -104,6 +104,15 @@ namespace basegfx // DIFF: Return all areas where CandidateA is not covered by CandidateB (cut B out of A) B2DPolyPolygon solvePolygonOperationDiff(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + /** merge all single PolyPolygons to a single, OR-ed PolyPolygon + + @param rInput + The source PolyPolygons + + @return A single PolyPolygon containing the Or-merged result + */ + B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput); + } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx index 5c75edd7f262..c4687b3cfc5f 100644 --- a/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx +++ b/basegfx/inc/basegfx/polygon/b2dpolypolygontools.hxx @@ -262,6 +262,20 @@ namespace basegfx bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB, const double& rfSmallValue); bool equal(const B2DPolyPolygon& rCandidateA, const B2DPolyPolygon& rCandidateB); + /** snap some polygon coordinates to discrete coordinates + + This method allows to snap some polygon points to discrete (integer) values + which equals e.g. a snap to discrete coordinates. It will snap points of + horizontal and vertical edges + + @param rCandidate + The source polygon + + @return + The modified version of the source polygon + */ + B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate); + } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/source/curve/b2dcubicbezier.cxx b/basegfx/source/curve/b2dcubicbezier.cxx index 76d1b74ddbca..e7247a95333b 100644 --- a/basegfx/source/curve/b2dcubicbezier.cxx +++ b/basegfx/source/curve/b2dcubicbezier.cxx @@ -443,21 +443,32 @@ namespace basegfx bool bAIsTrivial(aVecA.equalZero()); bool bBIsTrivial(aVecB.equalZero()); + // #i102241# prepare inverse edge length to normalize cross values; + // else the small compare value used in fTools::equalZero + // will be length dependent and this detection will work as less + // precise as longer the edge is. In principle, the length of the control + // vector would need to be used too, but to be trivial it is assumed to + // be of roughly equal length to the edge, so edge length can be used + // for both. Only needed when one of both is not trivial per se. + const double fInverseEdgeLength(bAIsTrivial && bBIsTrivial + ? 1.0 + : 1.0 / aEdge.getLength()); + // if A is not zero, check if it could be if(!bAIsTrivial) { - // parallel to edge? Check aVecA, aEdge - // B2DVector::areParallel is too correct, uses differences in the e15 region, - // thus do own test here - const double fValA(aVecA.getX() * aEdge.getY()); - const double fValB(aVecA.getY() * aEdge.getX()); + // #i102241# parallel to edge? Check aVecA, aEdge. Use cross() which does what + // we need here with the precision we need + const double fCross(aVecA.cross(aEdge) * fInverseEdgeLength); - if(fTools::equalZero(fabs(fValA) - fabs(fValB))) + if(fTools::equalZero(fCross)) { // get scale to edge. Use bigger distance for numeric quality - const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) ? aVecA.getX() / aEdge.getX() : aVecA.getY() / aEdge.getY()); + const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) + ? aVecA.getX() / aEdge.getX() + : aVecA.getY() / aEdge.getY()); - // end point of vector in edge range? + // relative end point of vector in edge range? if(fTools::moreOrEqual(fScale, 0.0) && fTools::lessOrEqual(fScale, 1.0)) { bAIsTrivial = true; @@ -470,13 +481,14 @@ namespace basegfx if(bAIsTrivial && !bBIsTrivial) { // parallel to edge? Check aVecB, aEdge - const double fValA(aVecB.getX() * aEdge.getY()); - const double fValB(aVecB.getY() * aEdge.getX()); + const double fCross(aVecB.cross(aEdge) * fInverseEdgeLength); - if(fTools::equalZero(fabs(fValA) - fabs(fValB))) + if(fTools::equalZero(fCross)) { // get scale to edge. Use bigger distance for numeric quality - const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) ? aVecB.getX() / aEdge.getX() : aVecB.getY() / aEdge.getY()); + const double fScale(fabs(aEdge.getX()) > fabs(aEdge.getY()) + ? aVecB.getX() / aEdge.getX() + : aVecB.getY() / aEdge.getY()); // end point of vector in edge range? Caution: controlB is directed AGAINST edge if(fTools::lessOrEqual(fScale, 0.0) && fTools::moreOrEqual(fScale, -1.0)) diff --git a/basegfx/source/polygon/b2dlinegeometry.cxx b/basegfx/source/polygon/b2dlinegeometry.cxx index 0cda1036e13b..1a9264ab769e 100644 --- a/basegfx/source/polygon/b2dlinegeometry.cxx +++ b/basegfx/source/polygon/b2dlinegeometry.cxx @@ -352,13 +352,12 @@ namespace basegfx // Unfortunately, while it would be geometrically correct to not add // the in-between points EdgeEnd and EdgeStart, it leads to rounding // errors when converting to integer polygon coordinates for painting - const B2DVector aEdgeVector(rEdge.getEndPoint() - rEdge.getStartPoint()); - if(rEdge.isBezier()) { // prepare target and data common for upper and lower B2DPolygon aBezierPolygon; - const double fEdgeLength(aEdgeVector.getLength()); + const B2DVector aPureEdgeVector(rEdge.getEndPoint() - rEdge.getStartPoint()); + const double fEdgeLength(aPureEdgeVector.getLength()); const bool bIsEdgeLengthZero(fTools::equalZero(fEdgeLength)); const B2DVector aTangentA(rEdge.getTangent(0.0)); const B2DVector aTangentB(rEdge.getTangent(1.0)); @@ -441,7 +440,11 @@ namespace basegfx } else { - const B2DVector aPerpendEdgeVector(getNormalizedPerpendicular(aEdgeVector) * fHalfLineWidth); + // #i101491# emulate rEdge.getTangent call which applies a factor of 0.3 to the + // full-length edge vector to have numerically exactly the same results as in the + // createAreaGeometryForJoin implementation + const B2DVector aEdgeTangent((rEdge.getEndPoint() - rEdge.getStartPoint()) * 0.3); + const B2DVector aPerpendEdgeVector(getNormalizedPerpendicular(aEdgeTangent) * fHalfLineWidth); B2DPolygon aEdgePolygon; // create upper edge @@ -495,45 +498,75 @@ namespace basegfx } } - // create first polygon part for edge - aEdgePolygon.append(aEndPoint); - aEdgePolygon.append(rPoint); - aEdgePolygon.append(aStartPoint); - - if(B2DLINEJOIN_MITER == eJoin) + switch(eJoin) { - // Look for the cut point between start point along rTangentPrev and - // end point along rTangentEdge. -rTangentEdge should be used, but since - // the cut value is used for interpolating along the first edge, the negation - // is not needed since the same fCut will be found on the first edge. - // If it exists, insert it to complete the mitered fill polygon. - double fCutPos(0.0); - tools::findCut(aStartPoint, rTangentPrev, aEndPoint, rTangentEdge, CUTFLAG_ALL, &fCutPos); - - if(0.0 != fCutPos) + case B2DLINEJOIN_MITER : { - const B2DPoint aCutPoint(interpolate(aStartPoint, aStartPoint + rTangentPrev, fCutPos)); - aEdgePolygon.append(aCutPoint); - } - } - else if(B2DLINEJOIN_ROUND == eJoin) - { - // use tooling to add needed EllipseSegment - double fAngleStart(atan2(rPerpendPrev.getY(), rPerpendPrev.getX())); - double fAngleEnd(atan2(rPerpendEdge.getY(), rPerpendEdge.getX())); + aEdgePolygon.append(aEndPoint); + aEdgePolygon.append(rPoint); + aEdgePolygon.append(aStartPoint); + + // Look for the cut point between start point along rTangentPrev and + // end point along rTangentEdge. -rTangentEdge should be used, but since + // the cut value is used for interpolating along the first edge, the negation + // is not needed since the same fCut will be found on the first edge. + // If it exists, insert it to complete the mitered fill polygon. + double fCutPos(0.0); + tools::findCut(aStartPoint, rTangentPrev, aEndPoint, rTangentEdge, CUTFLAG_ALL, &fCutPos); + + if(0.0 != fCutPos) + { + const B2DPoint aCutPoint(interpolate(aStartPoint, aStartPoint + rTangentPrev, fCutPos)); + aEdgePolygon.append(aCutPoint); + } - // atan2 results are [-PI .. PI], consolidate to [0.0 .. 2PI] - if(fAngleStart < 0.0) - { - fAngleStart += F_2PI; + break; } - - if(fAngleEnd < 0.0) + case B2DLINEJOIN_ROUND : { - fAngleEnd += F_2PI; + // use tooling to add needed EllipseSegment + double fAngleStart(atan2(rPerpendPrev.getY(), rPerpendPrev.getX())); + double fAngleEnd(atan2(rPerpendEdge.getY(), rPerpendEdge.getX())); + + // atan2 results are [-PI .. PI], consolidate to [0.0 .. 2PI] + if(fAngleStart < 0.0) + { + fAngleStart += F_2PI; + } + + if(fAngleEnd < 0.0) + { + fAngleEnd += F_2PI; + } + + const B2DPolygon aBow(tools::createPolygonFromEllipseSegment(rPoint, fHalfLineWidth, fHalfLineWidth, fAngleStart, fAngleEnd)); + + if(aBow.count() > 1) + { + // #i101491# + // use the original start/end positions; the ones from bow creation may be numerically + // different due to their different creation. To guarantee good merging quality with edges + // and edge roundings (and to reduce point count) + aEdgePolygon = aBow; + aEdgePolygon.setB2DPoint(0, aStartPoint); + aEdgePolygon.setB2DPoint(aEdgePolygon.count() - 1, aEndPoint); + aEdgePolygon.append(rPoint); + + break; + } + else + { + // wanted fall-through to default + } } + default: // B2DLINEJOIN_BEVEL + { + aEdgePolygon.append(aEndPoint); + aEdgePolygon.append(rPoint); + aEdgePolygon.append(aStartPoint); - aEdgePolygon.append(tools::createPolygonFromEllipseSegment(rPoint, fHalfLineWidth, fHalfLineWidth, fAngleStart, fAngleEnd)); + break; + } } // create last polygon part for edge diff --git a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx index a1b7a69775ad..26016942717d 100644 --- a/basegfx/source/polygon/b2dpolygoncutandtouch.cxx +++ b/basegfx/source/polygon/b2dpolygoncutandtouch.cxx @@ -110,7 +110,10 @@ namespace basegfx { // #i76891# mergeTemporaryPointsAndPolygon redesigned to be able to correctly handle // single edges with/without control points - if(rTempPoints.size()) + // #i101491# added counter for non-changing element count + const sal_uInt32 nTempPointCount(rTempPoints.size()); + + if(nTempPointCount) { B2DPolygon aRetval; const sal_uInt32 nCount(rCandidate.count()); @@ -138,7 +141,7 @@ namespace basegfx double fLeftStart(0.0); // now add all points targeted to be at this index - while(nNewInd < rTempPoints.size() && rTempPoints[nNewInd].getIndex() == a) + while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a) { const temporaryPoint& rTempPoint = rTempPoints[nNewInd++]; @@ -160,7 +163,7 @@ namespace basegfx else { // add all points targeted to be at this index - while(nNewInd < rTempPoints.size() && rTempPoints[nNewInd].getIndex() == a) + while(nNewInd < nTempPointCount && rTempPoints[nNewInd].getIndex() == a) { const temporaryPoint& rTempPoint = rTempPoints[nNewInd++]; const B2DPoint aNewPoint(rTempPoint.getPoint()); diff --git a/basegfx/source/polygon/b2dpolypolygoncutter.cxx b/basegfx/source/polygon/b2dpolypolygoncutter.cxx index b06e6fbafff7..0674bfe3953e 100644 --- a/basegfx/source/polygon/b2dpolypolygoncutter.cxx +++ b/basegfx/source/polygon/b2dpolypolygoncutter.cxx @@ -929,6 +929,85 @@ namespace basegfx } } + B2DPolyPolygon mergeToSinglePolyPolygon(const std::vector< basegfx::B2DPolyPolygon >& rInput) + { + std::vector< basegfx::B2DPolyPolygon > aInput(rInput); + + // first step: prepareForPolygonOperation and simple merge of non-overlapping + // PolyPolygons for speedup; this is possible for the wanted OR-operation + if(aInput.size()) + { + std::vector< basegfx::B2DPolyPolygon > aResult; + aResult.reserve(aInput.size()); + + for(sal_uInt32 a(0); a < aInput.size(); a++) + { + const basegfx::B2DPolyPolygon aCandidate(prepareForPolygonOperation(aInput[a])); + + if(aResult.size()) + { + const B2DRange aCandidateRange(aCandidate.getB2DRange()); + bool bCouldMergeSimple(false); + + for(sal_uInt32 b(0); !bCouldMergeSimple && b < aResult.size(); b++) + { + basegfx::B2DPolyPolygon aTarget(aResult[b]); + const B2DRange aTargetRange(aTarget.getB2DRange()); + + if(!aCandidateRange.overlaps(aTargetRange)) + { + aTarget.append(aCandidate); + aResult[b] = aTarget; + bCouldMergeSimple = true; + } + } + + if(!bCouldMergeSimple) + { + aResult.push_back(aCandidate); + } + } + else + { + aResult.push_back(aCandidate); + } + } + + aInput = aResult; + } + + // second step: melt pairwise to a single PolyPolygon + while(aInput.size() > 1) + { + std::vector< basegfx::B2DPolyPolygon > aResult; + aResult.reserve((aInput.size() / 2) + 1); + + for(sal_uInt32 a(0); a < aInput.size(); a += 2) + { + if(a + 1 < aInput.size()) + { + // a pair for processing + aResult.push_back(solvePolygonOperationOr(aInput[a], aInput[a + 1])); + } + else + { + // last single PolyPolygon; copy to target to not lose it + aResult.push_back(aInput[a]); + } + } + + aInput = aResult; + } + + // third step: get result + if(1 == aInput.size()) + { + return aInput[0]; + } + + return B2DPolyPolygon(); + } + ////////////////////////////////////////////////////////////////////////////// } // end of namespace tools diff --git a/basegfx/source/polygon/b2dpolypolygontools.cxx b/basegfx/source/polygon/b2dpolypolygontools.cxx index c92f2f29147b..e6b3a448530d 100644 --- a/basegfx/source/polygon/b2dpolypolygontools.cxx +++ b/basegfx/source/polygon/b2dpolypolygontools.cxx @@ -569,6 +569,18 @@ namespace basegfx return equal(rCandidateA, rCandidateB, fSmallValue); } + B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate) + { + B2DPolyPolygon aRetval; + + for(sal_uInt32 a(0L); a < rCandidate.count(); a++) + { + aRetval.append(snapPointsOfHorizontalOrVerticalEdges(rCandidate.getB2DPolygon(a))); + } + + return aRetval; + } + } // end of namespace tools } // end of namespace basegfx diff --git a/basegfx/test/makefile.mk b/basegfx/test/makefile.mk index d0fbfaf9e7c6..8e47a13defdd 100644 --- a/basegfx/test/makefile.mk +++ b/basegfx/test/makefile.mk @@ -89,7 +89,7 @@ $(MISC)$/unittest_succeeded : $(SHL1TARGETN) @echo ---------------------------------------------------------- @echo - start unit test on library $(SHL1TARGETN) @echo ---------------------------------------------------------- - $(AUGMENT_LIBRARY_PATH) testshl2 -sf $(mktmp ) -forward $(BIN)$/ $(SHL1TARGETN) + $(TESTSHL2) -sf $(mktmp ) -forward $(BIN)$/ $(SHL1TARGETN) $(TOUCH) $@ ALLTAR : $(MISC)$/unittest_succeeded diff --git a/canvas/source/cairo/cairo_canvasfont.cxx b/canvas/source/cairo/cairo_canvasfont.cxx index 3ef5db762c60..c6fa0847e660 100644 --- a/canvas/source/cairo/cairo_canvasfont.cxx +++ b/canvas/source/cairo/cairo_canvasfont.cxx @@ -37,6 +37,7 @@ #include <basegfx/numeric/ftools.hxx> #include <vcl/metric.hxx> +#include <i18npool/mslangid.hxx> #include "cairo_canvasfont.hxx" #include "cairo_textlayout.hxx" @@ -86,6 +87,8 @@ namespace cairocanvas maFont->SetWeight( static_cast<FontWeight>(rFontRequest.FontDescription.FontDescription.Weight) ); maFont->SetItalic( (rFontRequest.FontDescription.FontDescription.Letterform<=8) ? ITALIC_NONE : ITALIC_NORMAL ); + maFont->SetLanguage(MsLangId::convertLocaleToLanguage(rFontRequest.Locale)); + // adjust to stretched/shrinked font if( !::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) ) { diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx index f1c54e9b4ab7..9cf2dd978759 100644 --- a/canvas/source/cairo/cairo_canvashelper.cxx +++ b/canvas/source/cairo/cairo_canvashelper.cxx @@ -888,7 +888,7 @@ namespace cairocanvas nY = aP.getY(); cairo_matrix_transform_point( &aOrigMatrix, &nX, &nY ); - if( ! bIsBezier && bIsRectangle ) { + if( ! bIsBezier && (bIsRectangle || aOperation == Clip) ) { nX = basegfx::fround( nX ); nY = basegfx::fround( nY ); } diff --git a/canvas/source/cairo/makefile.mk b/canvas/source/cairo/makefile.mk index bd54254abf7e..2ab726da3464 100644 --- a/canvas/source/cairo/makefile.mk +++ b/canvas/source/cairo/makefile.mk @@ -84,7 +84,7 @@ SLOFILES = $(SLO)$/cairo_cachedbitmap.obj \ SHL1TARGET=$(TARGET).uno -SHL1STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(TOOLSLIB) +SHL1STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(TOOLSLIB) $(I18NISOLANGLIB) .IF "$(GUI)"=="UNX" diff --git a/canvas/source/directx/dx_textlayout_drawhelper.cxx b/canvas/source/directx/dx_textlayout_drawhelper.cxx index f44d8aa4a518..358bd1e9d74f 100755 --- a/canvas/source/directx/dx_textlayout_drawhelper.cxx +++ b/canvas/source/directx/dx_textlayout_drawhelper.cxx @@ -52,6 +52,7 @@ #include <canvas/debug.hxx> #include "dx_impltools.hxx" #include <vcl/sysdata.hxx> +#include <i18npool/mslangid.hxx> #include "dx_textlayout_drawhelper.hxx" #include "dx_bitmap.hxx" #include "dx_canvasfont.hxx" @@ -135,6 +136,8 @@ namespace dxcanvas aFont.SetWeight( static_cast<FontWeight>(rFontRequest.FontDescription.FontDescription.Weight) ); aFont.SetItalic( (rFontRequest.FontDescription.FontDescription.Letterform<=8) ? ITALIC_NONE : ITALIC_NORMAL ); + aFont.SetLanguage(MsLangId::convertLocaleToLanguage(rFontRequest.Locale)); + // setup font color aFont.SetColor( aColor ); aFont.SetFillColor( aColor ); diff --git a/canvas/source/directx/makefile.mk b/canvas/source/directx/makefile.mk index c1d210dfcf64..1a9db2ec51c0 100644 --- a/canvas/source/directx/makefile.mk +++ b/canvas/source/directx/makefile.mk @@ -96,7 +96,7 @@ GDIPLUS_SLOFILES = \ $(SLO)$/dx_canvas.obj GDIPLUS_SLOFILES += $(SHARED_SLOFILES) -STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(VCLLIB) $(TOOLSLIB) $(UNOTOOLSLIB) +STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(VCLLIB) $(TOOLSLIB) $(UNOTOOLSLIB) $(I18NISOLANGLIB) ######################################################## @@ -194,7 +194,7 @@ LIB3OBJFILES = $(GDIPLUS_SLOFILES) SHL3TARGET=$(TARGET3).uno # Links import libraries. -SHL3STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(VCLLIB) $(TOOLSLIB) $(UNOTOOLSLIB) +SHL3STDLIBS= $(CPPULIB) $(TKLIB) $(SALLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(VCLLIB) $(TOOLSLIB) $(UNOTOOLSLIB) $(I18NISOLANGLIB) # Specifies an import library to create. For Win32 only. SHL3IMPLIB=i$(TARGET3).lib diff --git a/canvas/source/vcl/canvasfont.cxx b/canvas/source/vcl/canvasfont.cxx index 9fb69875ecde..b049e1e4f317 100644 --- a/canvas/source/vcl/canvasfont.cxx +++ b/canvas/source/vcl/canvasfont.cxx @@ -35,7 +35,7 @@ #include <rtl/math.hxx> #include <basegfx/numeric/ftools.hxx> - +#include <i18npool/mslangid.hxx> #include <vcl/metric.hxx> #include "canvasfont.hxx" @@ -67,6 +67,8 @@ namespace vclcanvas maFont->SetWeight( static_cast<FontWeight>(rFontRequest.FontDescription.FontDescription.Weight) ); maFont->SetItalic( (rFontRequest.FontDescription.FontDescription.Letterform<=8) ? ITALIC_NONE : ITALIC_NORMAL ); + maFont->SetLanguage(MsLangId::convertLocaleToLanguage(rFontRequest.Locale)); + // adjust to stretched/shrinked font if( !::rtl::math::approxEqual( rFontMatrix.m00, rFontMatrix.m11) ) { diff --git a/canvas/source/vcl/makefile.mk b/canvas/source/vcl/makefile.mk index 781cd58d8b91..fdfdd62d16b8 100644 --- a/canvas/source/vcl/makefile.mk +++ b/canvas/source/vcl/makefile.mk @@ -73,7 +73,7 @@ SLOFILES = $(SLO)$/backbuffer.obj \ SHL1TARGET=$(TARGET).uno -SHL1STDLIBS= $(TOOLSLIB) $(TKLIB) $(CPPULIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(GOODIESLIB) +SHL1STDLIBS= $(TOOLSLIB) $(TKLIB) $(CPPULIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(CANVASTOOLSLIB) $(GOODIESLIB) $(I18NISOLANGLIB) SHL1IMPLIB=i$(TARGET) SHL1LIBS=$(SLB)$/$(TARGET).lib diff --git a/comphelper/inc/comphelper/processfactory.hxx b/comphelper/inc/comphelper/processfactory.hxx index d2ae887ba341..9b24f8e784ac 100644 --- a/comphelper/inc/comphelper/processfactory.hxx +++ b/comphelper/inc/comphelper/processfactory.hxx @@ -79,10 +79,19 @@ COMPHELPER_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::uno::XI const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArgs ) SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) ); +/** + * This function gets the process service factory's default component context. + * If no service factory is set the function returns a null interface. + */ +COMPHELPER_DLLPUBLIC +::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > +getProcessComponentContext(); + } + extern "C" { -/// @internal +/// @internal ATTENTION returns ACQUIRED pointer! release it explicitly! COMPHELPER_DLLPUBLIC ::com::sun::star::uno::XComponentContext * comphelper_getProcessComponentContext(); diff --git a/comphelper/inc/comphelper/stl_types.hxx b/comphelper/inc/comphelper/stl_types.hxx index aeb6342048c9..4b3126043a08 100644 --- a/comphelper/inc/comphelper/stl_types.hxx +++ b/comphelper/inc/comphelper/stl_types.hxx @@ -49,6 +49,7 @@ #include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/beans/PropertyValue.hpp> @@ -192,6 +193,59 @@ inline mem_fun1_t<_Tp,_Arg> mem_fun(void (_Tp::*__f)(_Arg)) } //......................................................................... +/** output iterator that appends OUStrings into an OUStringBuffer. + */ +class OUStringBufferAppender : + public ::std::iterator< ::std::output_iterator_tag, void, void, void, void> +{ +public: + typedef OUStringBufferAppender Self; + typedef ::std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void reference; + typedef void pointer; + typedef size_t difference_type; + + OUStringBufferAppender(::rtl::OUStringBuffer & i_rBuffer) + : m_rBuffer(i_rBuffer) { } + Self & operator=(::rtl::OUString const & i_rStr) + { + m_rBuffer.append( i_rStr ); + return *this; + } + Self & operator*() { return *this; } // so operator= works + Self & operator++() { return *this; } + Self & operator++(int) { return *this; } + +private: + ::rtl::OUStringBuffer & m_rBuffer; +}; + +//......................................................................... +/** algorithm similar to std::copy, but inserts a separator between elements. + */ +template< typename ForwardIter, typename OutputIter, typename T > +OutputIter intersperse( + ForwardIter start, ForwardIter end, OutputIter out, T const & separator) +{ + if (start != end) { + *out = *start; + ++start; + ++out; + } + + while (start != end) { + *out = separator; + ++out; + *out = *start; + ++start; + ++out; + } + + return out; +} + +//......................................................................... } //... namespace comphelper ................................................ diff --git a/comphelper/inc/comphelper/stlunosequence.hxx b/comphelper/inc/comphelper/stlunosequence.hxx index 2ffe08cb6b75..a0ace84e8a6e 100644 --- a/comphelper/inc/comphelper/stlunosequence.hxx +++ b/comphelper/inc/comphelper/stlunosequence.hxx @@ -312,7 +312,8 @@ namespace comphelper { namespace stlunosequence { template<typename S, typename V> inline typename StlSequence<S,V>::iterator StlSequence<S,V>::begin() { - return typename StlSequence<S,V>::iterator(m_UnoSequence, begin_of_sequence); + return typename StlSequence<S,V>::iterator(m_UnoSequence, + size() ? begin_of_sequence : end_of_sequence); } template<typename S, typename V> @@ -324,7 +325,8 @@ namespace comphelper { namespace stlunosequence { template<typename S, typename V> inline typename StlSequence<S,V>::const_iterator StlSequence<S,V>::begin() const { - return typename StlSequence<S,V>::const_iterator(m_UnoSequence, begin_of_sequence); + return typename StlSequence<S,V>::const_iterator(m_UnoSequence, + size() ? begin_of_sequence : end_of_sequence); } template<typename S, typename V> diff --git a/comphelper/inc/comphelper/storagehelper.hxx b/comphelper/inc/comphelper/storagehelper.hxx index b99f7e1233ca..efb5431959ba 100644 --- a/comphelper/inc/comphelper/storagehelper.hxx +++ b/comphelper/inc/comphelper/storagehelper.hxx @@ -48,9 +48,6 @@ namespace comphelper { -sal_Bool COMPHELPER_DLLPUBLIC IsValidZipEntryFileName( - const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed ); - class COMPHELPER_DLLPUBLIC OStorageHelper { public: diff --git a/comphelper/source/misc/documentiologring.cxx b/comphelper/source/misc/documentiologring.cxx new file mode 100644 index 000000000000..7969b938e108 --- /dev/null +++ b/comphelper/source/misc/documentiologring.cxx @@ -0,0 +1,175 @@ +/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: documentiologring.hxx,v $
+ * $Revision: 1.0 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+
+#include <com/sun/star/frame/DoubleInitializationException.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+
+#include "documentiologring.hxx"
+
+using namespace ::com::sun::star;
+
+namespace comphelper
+{
+
+// ----------------------------------------------------------
+OSimpleLogRing::OSimpleLogRing( const uno::Reference< uno::XComponentContext >& /*xContext*/ )
+: m_aMessages( SIMPLELOGRING_SIZE )
+, m_bInitialized( sal_False )
+, m_bFull( sal_False )
+, m_nPos( 0 )
+{
+}
+
+// ----------------------------------------------------------
+OSimpleLogRing::~OSimpleLogRing()
+{
+}
+
+// ----------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OSimpleLogRing::impl_staticGetSupportedServiceNames()
+{
+ uno::Sequence< rtl::OUString > aResult( 1 );
+ aResult[0] = impl_staticGetServiceName();
+ return aResult;
+}
+
+// ----------------------------------------------------------
+::rtl::OUString SAL_CALL OSimpleLogRing::impl_staticGetImplementationName()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.logging.SimpleLogRing" ) );
+}
+
+// ----------------------------------------------------------
+::rtl::OUString SAL_CALL OSimpleLogRing::impl_staticGetSingletonName()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.DocumentIOLogRing" ) );
+}
+
+// ----------------------------------------------------------
+::rtl::OUString SAL_CALL OSimpleLogRing::impl_staticGetServiceName()
+{
+ return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.logging.SimpleLogRing" ) );
+}
+
+// ----------------------------------------------------------
+uno::Reference< uno::XInterface > SAL_CALL OSimpleLogRing::impl_staticCreateSelfInstance( const uno::Reference< uno::XComponentContext >& rxContext )
+{
+ return static_cast< cppu::OWeakObject* >( new OSimpleLogRing( rxContext ) );
+}
+
+// XSimpleLogRing
+// ----------------------------------------------------------
+void SAL_CALL OSimpleLogRing::logString( const ::rtl::OUString& aMessage ) throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ m_aMessages[m_nPos] = aMessage;
+ if ( ++m_nPos >= m_aMessages.getLength() )
+ {
+ m_nPos = 0;
+ m_bFull = sal_True;
+ }
+
+ // if used once then default initialized
+ m_bInitialized = sal_True;
+}
+
+// ----------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OSimpleLogRing::getCollectedLog() throw (uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ sal_Int32 nResLen = m_bFull ? m_aMessages.getLength() : m_nPos;
+ sal_Int32 nStart = m_bFull ? m_nPos : 0;
+ uno::Sequence< ::rtl::OUString > aResult( nResLen );
+
+ for ( sal_Int32 nInd = 0; nInd < nResLen; nInd++ )
+ aResult[nInd] = m_aMessages[ ( nStart + nInd ) % m_aMessages.getLength() ];
+
+ // if used once then default initialized
+ m_bInitialized = sal_True;
+
+ return aResult;
+}
+
+// XInitialization
+// ----------------------------------------------------------
+void SAL_CALL OSimpleLogRing::initialize( const uno::Sequence< uno::Any >& aArguments ) throw (uno::Exception, uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( m_bInitialized )
+ throw frame::DoubleInitializationException();
+
+ if ( !m_refCount )
+ throw uno::RuntimeException(); // the object must be refcounted already!
+
+ sal_Int32 nLen = 0;
+ if ( aArguments.getLength() == 1 && ( aArguments[0] >>= nLen ) && nLen )
+ m_aMessages.realloc( nLen );
+ else
+ throw lang::IllegalArgumentException(
+ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonnull size is expected as the first argument!" ) ),
+ uno::Reference< uno::XInterface >(),
+ 0 );
+
+ m_bInitialized = sal_True;
+}
+
+// XServiceInfo
+// ----------------------------------------------------------
+::rtl::OUString SAL_CALL OSimpleLogRing::getImplementationName() throw (uno::RuntimeException)
+{
+ return impl_staticGetImplementationName();
+}
+
+// ----------------------------------------------------------
+::sal_Bool SAL_CALL OSimpleLogRing::supportsService( const ::rtl::OUString& aServiceName ) throw (uno::RuntimeException)
+{
+ const uno::Sequence< rtl::OUString > & aSupportedNames = impl_staticGetSupportedServiceNames();
+ for ( sal_Int32 nInd = 0; nInd < aSupportedNames.getLength(); nInd++ )
+ {
+ if ( aSupportedNames[ nInd ].equals( aServiceName ) )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+// ----------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL OSimpleLogRing::getSupportedServiceNames() throw (uno::RuntimeException)
+{
+ return impl_staticGetSupportedServiceNames();
+}
+
+} // namespace comphelper
+
diff --git a/comphelper/source/misc/documentiologring.hxx b/comphelper/source/misc/documentiologring.hxx new file mode 100644 index 000000000000..ae7d2a6eaf19 --- /dev/null +++ b/comphelper/source/misc/documentiologring.hxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: documentiologring.hxx,v $ + * $Revision: 1.0 $ + * + * 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. + * + ************************************************************************/ + +#ifndef __DOCUMENTIOLOGRING_HXX_ +#define __DOCUMENTIOLOGRING_HXX_ + +#include <com/sun/star/logging/XSimpleLogRing.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + +#include <osl/mutex.hxx> +#include <cppuhelper/implbase3.hxx> + +#define SIMPLELOGRING_SIZE 256 + +namespace comphelper +{ + +class OSimpleLogRing : public ::cppu::WeakImplHelper3< ::com::sun::star::logging::XSimpleLogRing, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::lang::XServiceInfo > +{ + ::osl::Mutex m_aMutex; + ::com::sun::star::uno::Sequence< ::rtl::OUString > m_aMessages; + + sal_Bool m_bInitialized; + sal_Bool m_bFull; + sal_Int32 m_nPos; + +public: + OSimpleLogRing( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& xContext ); + virtual ~OSimpleLogRing(); + + static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + impl_staticGetSupportedServiceNames(); + + static ::rtl::OUString SAL_CALL impl_staticGetImplementationName(); + + static ::rtl::OUString SAL_CALL impl_staticGetSingletonName(); + + static ::rtl::OUString SAL_CALL impl_staticGetServiceName(); + + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + impl_staticCreateSelfInstance( + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext ); + +// XSimpleLogRing + virtual void SAL_CALL logString( const ::rtl::OUString& aMessage ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getCollectedLog() throw (::com::sun::star::uno::RuntimeException); + +// XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + +// XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); + +}; + +} // namespace comphelper + +#endif + diff --git a/comphelper/source/misc/makefile.mk b/comphelper/source/misc/makefile.mk index 1d473e6c5365..f50f57c47eb3 100644 --- a/comphelper/source/misc/makefile.mk +++ b/comphelper/source/misc/makefile.mk @@ -58,6 +58,7 @@ SLOFILES= \ $(SLO)$/componentmodule.obj \ $(SLO)$/configurationhelper.obj \ $(SLO)$/documentinfo.obj \ + $(SLO)$/documentiologring.obj \ $(SLO)$/evtlistenerhlp.obj \ $(SLO)$/ihwrapnofilter.obj \ $(SLO)$/instancelocker.obj \ diff --git a/comphelper/source/misc/mediadescriptor.cxx b/comphelper/source/misc/mediadescriptor.cxx index da0dd71a5520..9f463cdf0380 100644 --- a/comphelper/source/misc/mediadescriptor.cxx +++ b/comphelper/source/misc/mediadescriptor.cxx @@ -726,8 +726,13 @@ class StillReadWriteInteraction : public ::ucbhelper::InterceptedInteraction css::ucb::InteractiveIOException exIO; xRequest->getRequest() >>= exIO; bAbort = ( - (exIO.Code == css::ucb::IOErrorCode_ACCESS_DENIED ) || - (exIO.Code == css::ucb::IOErrorCode_LOCKING_VIOLATION ) + (exIO.Code == css::ucb::IOErrorCode_ACCESS_DENIED ) + || (exIO.Code == css::ucb::IOErrorCode_LOCKING_VIOLATION ) +#ifdef MACOSX + // this is a workaround for MAC, on this platform if the file is locked + // the returned error code looks to be wrong + || (exIO.Code == css::ucb::IOErrorCode_GENERAL ) +#endif ); } break; diff --git a/comphelper/source/misc/string.cxx b/comphelper/source/misc/string.cxx index 77a251372d85..e9437528b0de 100644 --- a/comphelper/source/misc/string.cxx +++ b/comphelper/source/misc/string.cxx @@ -36,10 +36,13 @@ #include <vector> #include <algorithm> -#include "comphelper/string.hxx" -#include "rtl/ustring.hxx" -#include "sal/types.h" -#include "comphelper/stlunosequence.hxx" +#include <rtl/ustring.hxx> +#include <rtl/ustrbuf.hxx> +#include <sal/types.h> + +#include <comphelper/string.hxx> +#include <comphelper/stlunosequence.hxx> +#include <comphelper/stl_types.hxx> namespace comphelper { namespace string { @@ -96,12 +99,12 @@ rtl::OUString searchAndReplaceAsciiL( ::rtl::OUString convertCommaSeparated( ::com::sun::star::uno::Sequence< ::rtl::OUString > const& i_rSeq) { - ::rtl::OUString ret; - for (sal_Int32 i = 0; i < i_rSeq.getLength(); ++i) { - if (i != 0) ret += ::rtl::OUString::createFromAscii(", "); - ret += i_rSeq[i]; - } - return ret; + ::rtl::OUStringBuffer buf; + ::comphelper::intersperse( + ::comphelper::stl_begin(i_rSeq), ::comphelper::stl_end(i_rSeq), + ::comphelper::OUStringBufferAppender(buf), + ::rtl::OUString::createFromAscii(", ")); + return buf.makeStringAndClear(); } ::com::sun::star::uno::Sequence< ::rtl::OUString > @@ -119,10 +122,6 @@ rtl::OUString searchAndReplaceAsciiL( } while (idx >= 0); ::com::sun::star::uno::Sequence< ::rtl::OUString > kws(vec.size()); std::copy(vec.begin(), vec.end(), stl_begin(kws)); - /* - for (size_t i = 0; i < vec.size(); ++i) { - kws[i] = vec.at(i); - }*/ return kws; } diff --git a/comphelper/source/misc/types.cxx b/comphelper/source/misc/types.cxx index 2b20fd9acca3..2a9180c038b0 100644 --- a/comphelper/source/misc/types.cxx +++ b/comphelper/source/misc/types.cxx @@ -87,8 +87,7 @@ sal_Bool operator ==(const Time& _rLeft, const Time& _rRight) sal_Int32 getINT32(const Any& _rAny) { sal_Int32 nReturn = 0; - _rAny >>= nReturn; - + OSL_VERIFY( _rAny >>= nReturn ); return nReturn; } @@ -96,7 +95,7 @@ sal_Int32 getINT32(const Any& _rAny) sal_Int16 getINT16(const Any& _rAny) { sal_Int16 nReturn = 0; - _rAny >>= nReturn; + OSL_VERIFY( _rAny >>= nReturn ); return nReturn; } @@ -104,7 +103,7 @@ sal_Int16 getINT16(const Any& _rAny) double getDouble(const Any& _rAny) { double nReturn = 0.0; - _rAny >>= nReturn; + OSL_VERIFY( _rAny >>= nReturn ); return nReturn; } @@ -112,7 +111,7 @@ double getDouble(const Any& _rAny) float getFloat(const Any& _rAny) { float nReturn = 0.0; - _rAny >>= nReturn; + OSL_VERIFY( _rAny >>= nReturn ); return nReturn; } @@ -120,7 +119,7 @@ float getFloat(const Any& _rAny) ::rtl::OUString getString(const Any& _rAny) { ::rtl::OUString nReturn; - _rAny >>= nReturn; + OSL_VERIFY( _rAny >>= nReturn ); return nReturn; } diff --git a/comphelper/source/misc/uieventslogger.cxx b/comphelper/source/misc/uieventslogger.cxx index 3ff875a4e67d..a55d5b58854d 100644 --- a/comphelper/source/misc/uieventslogger.cxx +++ b/comphelper/source/misc/uieventslogger.cxx @@ -375,9 +375,10 @@ namespace comphelper } else logdata[2] = UNKNOWN_ORIGIN; - logdata[3] = url.Complete; if(url.Complete.match(URL_FILE)) logdata[3] = URL_FILE; + else + logdata[3] = url.Main; m_Logger->log(LogLevel::INFO, m_Formatter->formatMultiColumn(logdata)); m_SessionLogEventCount++; } diff --git a/comphelper/source/processfactory/processfactory.cxx b/comphelper/source/processfactory/processfactory.cxx index 0f50f4a4cb01..c4eac583e3c0 100644 --- a/comphelper/source/processfactory/processfactory.cxx +++ b/comphelper/source/processfactory/processfactory.cxx @@ -98,24 +98,30 @@ Reference< XInterface > createProcessComponentWithArguments( const ::rtl::OUStri return xComponent; } -} // namesapce comphelper - -extern "C" { -uno::XComponentContext * comphelper_getProcessComponentContext() +Reference< XComponentContext > getProcessComponentContext() { - uno::Reference<uno::XComponentContext> xRet; + Reference< XComponentContext > xRet; uno::Reference<beans::XPropertySet> const xProps( comphelper::getProcessServiceFactory(), uno::UNO_QUERY ); if (xProps.is()) { try { - xRet.set( xProps->getPropertyValue( - rtl::OUString( + xRet.set( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ), uno::UNO_QUERY ); } catch (beans::UnknownPropertyException const&) { } } + return xRet; +} + +} // namespace comphelper + +extern "C" { +uno::XComponentContext * comphelper_getProcessComponentContext() +{ + uno::Reference<uno::XComponentContext> xRet; + xRet = ::comphelper::getProcessComponentContext(); if (xRet.is()) xRet->acquire(); return xRet.get(); diff --git a/comphelper/source/property/propertybag.cxx b/comphelper/source/property/propertybag.cxx index a56793e05769..383e1cc2c5aa 100644 --- a/comphelper/source/property/propertybag.cxx +++ b/comphelper/source/property/propertybag.cxx @@ -168,10 +168,11 @@ namespace comphelper // will throw an UnknownPropertyException if necessary if ( ( rProp.Attributes & PropertyAttribute::REMOVEABLE ) == 0 ) throw NotRemoveableException( ::rtl::OUString(), NULL ); + const sal_Int32 nHandle = rProp.Handle; - revokeProperty( rProp.Handle ); + revokeProperty( nHandle ); - m_pImpl->aDefaults.erase( rProp.Handle ); + m_pImpl->aDefaults.erase( nHandle ); } //-------------------------------------------------------------------- diff --git a/comphelper/source/property/propertycontainerhelper.cxx b/comphelper/source/property/propertycontainerhelper.cxx index 9d1662d1ecf2..7f5db1d6cf7e 100644 --- a/comphelper/source/property/propertycontainerhelper.cxx +++ b/comphelper/source/property/propertycontainerhelper.cxx @@ -76,12 +76,12 @@ namespace // comparing two property descriptions (by name) struct PropertyDescriptionNameMatch : public ::std::unary_function< PropertyDescription, bool > { - const ::rtl::OUString& m_rCompare; + ::rtl::OUString m_rCompare; PropertyDescriptionNameMatch( const ::rtl::OUString& _rCompare ) : m_rCompare( _rCompare ) { } bool operator() (const PropertyDescription& x ) const { - return x.aProperty.Name == m_rCompare; + return x.aProperty.Name.equals(m_rCompare); } }; } diff --git a/comphelper/source/streaming/memorystream.cxx b/comphelper/source/streaming/memorystream.cxx index 3afd9b555a84..a2baef21010e 100644 --- a/comphelper/source/streaming/memorystream.cxx +++ b/comphelper/source/streaming/memorystream.cxx @@ -35,15 +35,16 @@ #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/io/XSeekableInputStream.hpp> +#include <com/sun/star/io/XTruncate.hpp> #include <com/sun/star/uno/XComponentContext.hpp> -#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/implbase4.hxx> #include <string.h> #include <vector> using ::rtl::OUString; using ::cppu::OWeakObject; -using ::cppu::WeakImplHelper3; +using ::cppu::WeakImplHelper4; using namespace ::com::sun::star::io; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; @@ -52,7 +53,7 @@ using namespace ::osl; namespace comphelper { -class UNOMemoryStream : public WeakImplHelper3 < XStream, XSeekableInputStream, XOutputStream > +class UNOMemoryStream : public WeakImplHelper4 < XStream, XSeekableInputStream, XOutputStream, XTruncate > { public: UNOMemoryStream(); @@ -79,6 +80,9 @@ public: virtual void SAL_CALL flush() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); virtual void SAL_CALL closeOutput() throw (NotConnectedException, BufferSizeExceededException, IOException, RuntimeException); + // XTruncate + virtual void SAL_CALL truncate() throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException); + // XServiceInfo - static versions (used for component registration) static ::rtl::OUString SAL_CALL getImplementationName_static(); static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(); @@ -116,8 +120,7 @@ sal_Int32 SAL_CALL UNOMemoryStream::readBytes( Sequence< sal_Int8 >& aData, sal_ throw IOException(); nBytesToRead = std::min( nBytesToRead, available() ); - if( aData.getLength() < nBytesToRead ) - aData.realloc( nBytesToRead ); + aData.realloc( nBytesToRead ); if( nBytesToRead ) { @@ -157,9 +160,16 @@ void SAL_CALL UNOMemoryStream::closeInput() throw (NotConnectedException, IOExce // XSeekable void SAL_CALL UNOMemoryStream::seek( sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException) { - if( (location < 0) || (location > SAL_MAX_INT32) || (location > static_cast< sal_Int64 >( maData.size() )) ) + if( (location < 0) || (location > SAL_MAX_INT32) ) throw IllegalArgumentException( OUString(RTL_CONSTASCII_USTRINGPARAM("this implementation does not support more than 2GB!")), Reference< XInterface >(static_cast<OWeakObject*>(this)), 0 ); + // seek operation should be able to resize the stream + if ( location > static_cast< sal_Int64 >( maData.size() ) ) + maData.resize( static_cast< sal_Int32 >( location ) ); + + if ( location > static_cast< sal_Int64 >( maData.size() ) ) + maData.resize( static_cast< sal_Int32 >( location ) ); + mnCursor = static_cast< sal_Int32 >( location ); } @@ -206,6 +216,13 @@ void SAL_CALL UNOMemoryStream::closeOutput() throw (NotConnectedException, Buffe mnCursor = 0; } +//XTruncate +void SAL_CALL UNOMemoryStream::truncate() throw (IOException, RuntimeException) +{ + maData.resize( 0 ); + mnCursor = 0; +} + ::rtl::OUString SAL_CALL UNOMemoryStream::getImplementationName_static() { static const OUString sImplName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.MemoryStream" ) ); diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx index 6269cfb11ef4..c6f9a295b332 100644 --- a/cppcanvas/source/mtfrenderer/implrenderer.cxx +++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx @@ -83,6 +83,7 @@ #include <vcl/metric.hxx> #include <vcl/graphictools.hxx> #include <tools/poly.hxx> +#include <i18npool/mslangid.hxx> #include <implrenderer.hxx> #include <tools.hxx> @@ -956,6 +957,9 @@ namespace cppcanvas rParms.mrParms.maFontLetterForm.getValue() : (rFont.GetItalic() == ITALIC_NONE) ? 0 : 9; + LanguageType aLang = rFont.GetLanguage(); + aFontRequest.Locale = MsLangId::convertLanguageToLocale(aLang, false); + // setup state-local text transformation, // if the font be rotated const short nFontAngle( rFont.GetOrientation() ); diff --git a/cppcanvas/util/makefile.mk b/cppcanvas/util/makefile.mk index a5ac026e262c..4d0ff2a8dc55 100644 --- a/cppcanvas/util/makefile.mk +++ b/cppcanvas/util/makefile.mk @@ -50,7 +50,7 @@ LIB1FILES=\ SHL1TARGET= $(TARGET)$(DLLPOSTFIX) SHL1IMPLIB= i$(TARGET) -SHL1STDLIBS= $(TOOLSLIB) $(CPPULIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CANVASTOOLSLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) +SHL1STDLIBS= $(TOOLSLIB) $(CPPULIB) $(SALLIB) $(VCLLIB) $(COMPHELPERLIB) $(CANVASTOOLSLIB) $(CPPUHELPERLIB) $(BASEGFXLIB) $(I18NISOLANGLIB) .IF "$(debug)$(dbgutil)"!="" SHL1STDLIBS += $(CPPUHELPERLIB) diff --git a/dtrans/source/X11/X11_droptarget.cxx b/dtrans/source/X11/X11_droptarget.cxx index 501eff09ead8..4f71a0507790 100644 --- a/dtrans/source/X11/X11_droptarget.cxx +++ b/dtrans/source/X11/X11_droptarget.cxx @@ -143,15 +143,13 @@ void DropTarget::setDefaultActions( sal_Int8 actions ) throw() void DropTarget::drop( const DropTargetDropEvent& dtde ) throw() { - ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + osl::ClearableGuard< ::osl::Mutex > aGuard( m_aMutex ); + std::list< Reference< XDropTargetListener > > aListeners( m_aListeners ); + aGuard.clear(); - ::std::list< Reference< XDropTargetListener > >::iterator it1, it2; - it1 = m_aListeners.begin(); - while( it1 != m_aListeners.end() ) + for( std::list< Reference< XDropTargetListener > >::iterator it = aListeners.begin(); it!= aListeners.end(); ++it ) { - it2 = it1; - it1++; - (*it2)->drop( dtde ); + (*it)->drop( dtde ); } } @@ -159,15 +157,13 @@ void DropTarget::drop( const DropTargetDropEvent& dtde ) throw() void DropTarget::dragEnter( const DropTargetDragEnterEvent& dtde ) throw() { - ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + osl::ClearableGuard< ::osl::Mutex > aGuard( m_aMutex ); + std::list< Reference< XDropTargetListener > > aListeners( m_aListeners ); + aGuard.clear(); - ::std::list< Reference< XDropTargetListener > >::iterator it1, it2; - it1 = m_aListeners.begin(); - while( it1 != m_aListeners.end() ) + for( std::list< Reference< XDropTargetListener > >::iterator it = aListeners.begin(); it!= aListeners.end(); ++it ) { - it2 = it1; - it1++; - (*it2)->dragEnter( dtde ); + (*it)->dragEnter( dtde ); } } @@ -175,15 +171,13 @@ void DropTarget::dragEnter( const DropTargetDragEnterEvent& dtde ) throw() void DropTarget::dragExit( const DropTargetEvent& dte ) throw() { - ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + osl::ClearableGuard< ::osl::Mutex > aGuard( m_aMutex ); + std::list< Reference< XDropTargetListener > > aListeners( m_aListeners ); + aGuard.clear(); - ::std::list< Reference< XDropTargetListener > >::iterator it1, it2; - it1 = m_aListeners.begin(); - while( it1 != m_aListeners.end() ) + for( std::list< Reference< XDropTargetListener > >::iterator it = aListeners.begin(); it!= aListeners.end(); ++it ) { - it2 = it1; - it1++; - (*it2)->dragExit( dte ); + (*it)->dragExit( dte ); } } @@ -191,15 +185,13 @@ void DropTarget::dragExit( const DropTargetEvent& dte ) throw() void DropTarget::dragOver( const DropTargetDragEvent& dtde ) throw() { - ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); + osl::ClearableGuard< ::osl::Mutex > aGuard( m_aMutex ); + std::list< Reference< XDropTargetListener > > aListeners( m_aListeners ); + aGuard.clear(); - ::std::list< Reference< XDropTargetListener > >::iterator it1, it2; - it1 = m_aListeners.begin(); - while( it1 != m_aListeners.end() ) + for( std::list< Reference< XDropTargetListener > >::iterator it = aListeners.begin(); it!= aListeners.end(); ++it ) { - it2 = it1; - it1++; - (*it2)->dragOver( dtde ); + (*it)->dragOver( dtde ); } } diff --git a/dtrans/source/X11/X11_selection.cxx b/dtrans/source/X11/X11_selection.cxx index 2a424984850a..21030a220917 100644 --- a/dtrans/source/X11/X11_selection.cxx +++ b/dtrans/source/X11/X11_selection.cxx @@ -515,6 +515,15 @@ SelectionManager::~SelectionManager() // destroy message window if( m_aWindow ) XDestroyWindow( m_pDisplay, m_aWindow ); + // release cursors + if (m_aMoveCursor != None) + XFreeCursor(m_pDisplay, m_aMoveCursor); + if (m_aCopyCursor != None) + XFreeCursor(m_pDisplay, m_aCopyCursor); + if (m_aLinkCursor != None) + XFreeCursor(m_pDisplay, m_aLinkCursor); + if (m_aNoneCursor != None) + XFreeCursor(m_pDisplay, m_aNoneCursor); // paranoia setting, the drag thread should have // done that already @@ -1117,7 +1126,7 @@ bool SelectionManager::getPasteData( Atom selection, const ::rtl::OUString& rTyp bSuccess = getPasteData( selection, m_nImageBmpAtom, rData ); #if OSL_DEBUG_LEVEL > 1 if( bSuccess ) - fprintf( stderr, "got %d bytes of image/bmp\n" ), (int)rData.getLength(); + fprintf( stderr, "got %d bytes of image/bmp\n", (int)rData.getLength() ); #endif if( ! bSuccess ) { @@ -1685,7 +1694,7 @@ bool SelectionManager::handleSelectionRequest( XSelectionRequestEvent& rRequest XA_INTEGER, 32, PropModeReplace, (const unsigned char*)&nTimeStamp, 1 ); aNotify.xselection.property = rRequest.property; #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "sending timestamp: %d\n", nTimeStamp ); + fprintf( stderr, "sending timestamp: %d\n", (int)nTimeStamp ); #endif } else diff --git a/dtrans/source/aqua/DropTarget.cxx b/dtrans/source/aqua/DropTarget.cxx index bb45742732e7..6f973d7aa08f 100644 --- a/dtrans/source/aqua/DropTarget.cxx +++ b/dtrans/source/aqua/DropTarget.cxx @@ -245,8 +245,8 @@ NSDragOperation DropTarget::draggingEntered(id sender) CocoaToVCL(dragLocation, bounds); - sal_Int32 posX = dragLocation.x; - sal_Int32 posY = dragLocation.y; + sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x); + sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y); NSPasteboard* dragPboard = [sender draggingPasteboard]; mXCurrentDragClipboard = new AquaClipboard(mXComponentContext, dragPboard, false); @@ -284,8 +284,8 @@ NSDragOperation DropTarget::draggingUpdated(id sender) CocoaToVCL(dragLocation, bounds); - sal_Int32 posX = dragLocation.x; - sal_Int32 posY = dragLocation.y; + sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x); + sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y); DropTargetDragEvent dtde(static_cast<OWeakObject*>(this), 0, @@ -350,8 +350,8 @@ MacOSBOOL DropTarget::performDragOperation(id sender) CocoaToVCL(dragLocation, bounds); - sal_Int32 posX = dragLocation.x; - sal_Int32 posY = dragLocation.y; + sal_Int32 posX = static_cast<sal_Int32>(dragLocation.x); + sal_Int32 posY = static_cast<sal_Int32>(dragLocation.y); DropTargetDropEvent dtde(static_cast<OWeakObject*>(this), 0, diff --git a/dtrans/source/aqua/aqua_clipboard.cxx b/dtrans/source/aqua/aqua_clipboard.cxx index d0b821099ea0..370edee90eb7 100644 --- a/dtrans/source/aqua/aqua_clipboard.cxx +++ b/dtrans/source/aqua/aqua_clipboard.cxx @@ -323,8 +323,13 @@ void AquaClipboard::fireLostClipboardOwnershipEvent(Reference<XClipboardOwner> o void AquaClipboard::provideDataForType(NSPasteboard* sender, NSString* type) { DataProviderPtr_t dp = mpDataFlavorMapper->getDataProvider(type, mXClipboardContent); - NSData* pBoardData = (NSData*)dp->getSystemData(); - [sender setData: pBoardData forType: type]; + NSData* pBoardData = NULL; + + if (dp.get() != NULL) + { + pBoardData = (NSData*)dp->getSystemData(); + [sender setData: pBoardData forType: type]; + } } diff --git a/goodies/prj/build.lst b/goodies/prj/build.lst index fb1f7a0f1aca..f8edce86c4f8 100644 --- a/goodies/prj/build.lst +++ b/goodies/prj/build.lst @@ -1,4 +1,4 @@ -go goodies : svtools NULL +go goodies : l10n svtools NULL go goodies usr1 - all g_mkout NULL go goodies\inc nmake - all g_inc NULL go goodies\prj get - all g_prj NULL diff --git a/goodies/source/filter.vcl/idxf/dxf2mtf.cxx b/goodies/source/filter.vcl/idxf/dxf2mtf.cxx index a2547bcae232..654b66888f67 100644 --- a/goodies/source/filter.vcl/idxf/dxf2mtf.cxx +++ b/goodies/source/filter.vcl/idxf/dxf2mtf.cxx @@ -91,41 +91,93 @@ long DXF2GDIMetaFile::GetEntityColor(const DXFBasicEntity & rE) return nColor; } - -PenStyle DXF2GDIMetaFile::LTypeToPStyle(const char * sLineType) +DXFLineInfo DXF2GDIMetaFile::LTypeToDXFLineInfo(const char * sLineType) { const DXFLType * pLT; - PenStyle ePStyle; + DXFLineInfo aDXFLineInfo; + pLT=pDXF->aTables.SearchLType(sLineType); - if (pLT==NULL) ePStyle=PEN_SOLID; - else if (pLT->nDashCount<=1) ePStyle=PEN_SOLID; - else if (pLT->nDashCount==2) { - if (fabs(pLT->fDash[0])*4<fabs(pLT->fPatternLength)) ePStyle=PEN_DOT; - else ePStyle=PEN_DASH; - } - else ePStyle=PEN_DASHDOT; - return ePStyle; -} + if (pLT==NULL || pLT->nDashCount == 0) { + aDXFLineInfo.eStyle = LINE_SOLID; + } + else { + sal_Int32 i; + double x; + aDXFLineInfo.eStyle = LINE_DASH; + for (i=0; i < (pLT->nDashCount); i++) { + x = pLT->fDash[i] * pDXF->getGlobalLineTypeScale(); +// #### + // x = (sal_Int32) rTransform.TransLineWidth( pLT->fDash[i] * pDXF->getGlobalLineTypeScale() ); + if ( x >= 0.0 ) { + if ( aDXFLineInfo.nDotCount == 0 ) { + aDXFLineInfo.nDotCount ++; + aDXFLineInfo.fDotLen = x; + } + else if ( aDXFLineInfo.fDotLen == x ) { + aDXFLineInfo.nDotCount ++; + } + else if ( aDXFLineInfo.nDashCount == 0 ) { + aDXFLineInfo.nDashCount ++; + aDXFLineInfo.fDashLen = x; + } + else if ( aDXFLineInfo.fDashLen == x ) { + aDXFLineInfo.nDashCount ++; + } + else { + // It is impossible to be converted. + } + } + else { + if ( aDXFLineInfo.fDistance == 0 ) { + aDXFLineInfo.fDistance = -1 * x; + } + else { + // It is impossible to be converted. + } + } + + } + } +#if 0 + if (aDXFLineInfo.DashCount > 0 && aDXFLineInfo.DashLen == 0.0) + aDXFLineInfo.DashLen ( 1 ); + if (aDXFLineInfo.DotCount > 0 && aDXFLineInfo.DotLen() == 0.0) + aDXFLineInfo.SetDotLen( 1 ); + if (aDXFLineInfo.GetDashCount > 0 || aDXFLineInfo.GetDotCount > 0) + if (aDXFLineInfo.GetDistance() == 0) + aDXFLineInfo.SetDistance( 1 ); +#endif -PenStyle DXF2GDIMetaFile::GetEntityPStyle(const DXFBasicEntity & rE) + return aDXFLineInfo; +} + +DXFLineInfo DXF2GDIMetaFile::GetEntityDXFLineInfo(const DXFBasicEntity & rE) { - PenStyle ePStyle; + DXFLineInfo aDXFLineInfo; const DXFLayer * pLayer; + aDXFLineInfo.eStyle = LINE_SOLID; + aDXFLineInfo.fWidth = 0; + aDXFLineInfo.nDashCount = 0; + aDXFLineInfo.fDashLen = 0; + aDXFLineInfo.nDotCount = 0; + aDXFLineInfo.fDotLen = 0; + aDXFLineInfo.fDistance = 0; + if (strcmp(rE.sLineType,"BYLAYER")==0) { - if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) ePStyle=eParentLayerPStyle; + if (rE.sLayer[0]=='0' && rE.sLayer[1]==0) aDXFLineInfo=aParentLayerDXFLineInfo; else { pLayer=pDXF->aTables.SearchLayer(rE.sLayer); - if (pLayer!=NULL) ePStyle=LTypeToPStyle(pLayer->sLineType); - else ePStyle=eParentLayerPStyle; + if (pLayer!=NULL) aDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); + else aDXFLineInfo=aParentLayerDXFLineInfo; } } else if (strcmp(rE.sLineType,"BYBLOCK")==0) { - ePStyle=eBlockPStyle; + aDXFLineInfo=aBlockDXFLineInfo; } - else ePStyle=LTypeToPStyle(rE.sLineType); - return ePStyle; + else aDXFLineInfo=LTypeToDXFLineInfo(rE.sLineType); + return aDXFLineInfo; } @@ -133,12 +185,10 @@ BOOL DXF2GDIMetaFile::SetLineAttribute(const DXFBasicEntity & rE, ULONG /*nWidth { long nColor; Color aColor; - PenStyle ePStyle; nColor=GetEntityColor(rE); if (nColor<0) return FALSE; aColor=ConvertColor((BYTE)nColor); - ePStyle=GetEntityPStyle(rE); if (aActLineColor!=aColor) { pVirDev->SetLineColor( aActLineColor = aColor ); @@ -202,12 +252,30 @@ BOOL DXF2GDIMetaFile::SetFontAttribute(const DXFBasicEntity & rE, short nAngle, void DXF2GDIMetaFile::DrawLineEntity(const DXFLineEntity & rE, const DXFTransform & rTransform) { - if (SetLineAttribute(rE)) { Point aP0,aP1; rTransform.Transform(rE.aP0,aP0); rTransform.Transform(rE.aP1,aP1); - pVirDev->DrawLine(aP0,aP1); + + DXFLineInfo aDXFLineInfo; + aDXFLineInfo=GetEntityDXFLineInfo(rE); + LineInfo aLineInfo; + aLineInfo = rTransform.Transform(aDXFLineInfo); + +#if 0 + printf("%f\n", rTransform.TransLineWidth(1000.0)); + + // LINE_NONE = 0, LINE_SOLID = 1, LINE_DASH = 2, LineStyle_FORCE_EQUAL_SIZE = SAL_MAX_ENUM + aLineInfo.SetStyle( LINE_DASH ); + aLineInfo.SetWidth( 300 ); + aLineInfo.SetDashCount( 2 ); + aLineInfo.SetDashLen( 100 ); + aLineInfo.SetDotCount( 1 ); + aLineInfo.SetDotLen( 0 ); + aLineInfo.SetDistance( 500 ); +#endif + + pVirDev->DrawLine(aP0,aP1,aLineInfo); if (rE.fThickness!=0) { Point aP2,aP3; rTransform.Transform(rE.aP0+DXFVector(0,0,rE.fThickness),aP2); @@ -426,23 +494,23 @@ void DXF2GDIMetaFile::DrawInsertEntity(const DXFInsertEntity & rE, const DXFTran rTransform ); long nSavedBlockColor, nSavedParentLayerColor; - PenStyle eSavedBlockPStyle, eSavedParentLayerPStyle; + DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo; nSavedBlockColor=nBlockColor; nSavedParentLayerColor=nParentLayerColor; - eSavedBlockPStyle=eBlockPStyle; - eSavedParentLayerPStyle=eParentLayerPStyle; + aSavedBlockDXFLineInfo=aBlockDXFLineInfo; + aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo; nBlockColor=GetEntityColor(rE); - eBlockPStyle=GetEntityPStyle(rE); + aBlockDXFLineInfo=GetEntityDXFLineInfo(rE); if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) { DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer); if (pLayer!=NULL) { nParentLayerColor=pLayer->nColor; - eParentLayerPStyle=LTypeToPStyle(pLayer->sLineType); + aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); } } DrawEntities(*pB,aT,FALSE); - eBlockPStyle=eSavedBlockPStyle; - eParentLayerPStyle=eSavedParentLayerPStyle; + aBlockDXFLineInfo=aSavedBlockDXFLineInfo; + aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo; nBlockColor=nSavedBlockColor; nParentLayerColor=nSavedParentLayerColor; } @@ -540,6 +608,8 @@ void DXF2GDIMetaFile::DrawLWPolyLineEntity(const DXFLWPolyLineEntity & rE, const pVirDev->DrawPolygon( aPoly ); else pVirDev->DrawPolyLine( aPoly ); + // #### + //pVirDev->DrawPolyLine( aPoly, aDXFLineInfo ); } } } @@ -675,23 +745,23 @@ void DXF2GDIMetaFile::DrawDimensionEntity(const DXFDimensionEntity & rE, const D rTransform ); long nSavedBlockColor, nSavedParentLayerColor; - PenStyle eSavedBlockPStyle, eSavedParentLayerPStyle; + DXFLineInfo aSavedBlockDXFLineInfo, aSavedParentLayerDXFLineInfo; nSavedBlockColor=nBlockColor; nSavedParentLayerColor=nParentLayerColor; - eSavedBlockPStyle=eBlockPStyle; - eSavedParentLayerPStyle=eParentLayerPStyle; + aSavedBlockDXFLineInfo=aBlockDXFLineInfo; + aSavedParentLayerDXFLineInfo=aParentLayerDXFLineInfo; nBlockColor=GetEntityColor(rE); - eBlockPStyle=GetEntityPStyle(rE); + aBlockDXFLineInfo=GetEntityDXFLineInfo(rE); if (rE.sLayer[0]!='0' || rE.sLayer[1]!=0) { DXFLayer * pLayer=pDXF->aTables.SearchLayer(rE.sLayer); if (pLayer!=NULL) { nParentLayerColor=pLayer->nColor; - eParentLayerPStyle=LTypeToPStyle(pLayer->sLineType); + aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); } } DrawEntities(*pB,aT,FALSE); - eBlockPStyle=eSavedBlockPStyle; - eParentLayerPStyle=eSavedParentLayerPStyle; + aBlockDXFLineInfo=aSavedBlockDXFLineInfo; + aParentLayerDXFLineInfo=aSavedParentLayerDXFLineInfo; nBlockColor=nSavedBlockColor; nParentLayerColor=nSavedParentLayerColor; } @@ -801,16 +871,28 @@ BOOL DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF nMainEntitiesCount=CountEntities(pDXF->aEntities); nBlockColor=7; - eBlockPStyle=PEN_SOLID; + aBlockDXFLineInfo.eStyle = LINE_SOLID; + aBlockDXFLineInfo.fWidth = 0; + aBlockDXFLineInfo.nDashCount = 0; + aBlockDXFLineInfo.fDashLen = 0; + aBlockDXFLineInfo.nDotCount = 0; + aBlockDXFLineInfo.fDotLen = 0; + aBlockDXFLineInfo.fDistance = 0; pLayer=pDXF->aTables.SearchLayer("0"); if (pLayer!=NULL) { nParentLayerColor=pLayer->nColor & 0xff; - eParentLayerPStyle=LTypeToPStyle(pLayer->sLineType); + aParentLayerDXFLineInfo=LTypeToDXFLineInfo(pLayer->sLineType); } else { nParentLayerColor=7; - eParentLayerPStyle=PEN_SOLID; + aParentLayerDXFLineInfo.eStyle = LINE_SOLID; + aParentLayerDXFLineInfo.fWidth = 0; + aParentLayerDXFLineInfo.nDashCount = 0; + aParentLayerDXFLineInfo.fDashLen = 0; + aParentLayerDXFLineInfo.nDotCount = 0; + aParentLayerDXFLineInfo.fDotLen = 0; + aParentLayerDXFLineInfo.fDistance = 0; } pVirDev->EnableOutput(FALSE); @@ -837,14 +919,14 @@ BOOL DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF fScale = 0; // -Wall added this... } else { - if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) { +// if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) { if (fWidth>fHeight) fScale=10000.0/fWidth; else fScale=10000.0/fHeight; - } - else - fScale=1.0; +// } +// else +// fScale=1.0; aTransform=DXFTransform(fScale,-fScale,fScale, DXFVector(-pDXF->aBoundingBox.fMinX*fScale, pDXF->aBoundingBox.fMaxY*fScale, @@ -857,14 +939,14 @@ BOOL DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF else { fHeight=pVPort->fHeight; fWidth=fHeight*pVPort->fAspectRatio; - if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) { +// if (fWidth<500.0 || fHeight<500.0 || fWidth>32767.0 || fHeight>32767.0) { if (fWidth>fHeight) fScale=10000.0/fWidth; else fScale=10000.0/fHeight; - } - else - fScale=1.0; +// } +// else +// fScale=1.0; aTransform=DXFTransform( DXFTransform(pVPort->aDirection,pVPort->aTarget), DXFTransform( @@ -894,7 +976,6 @@ BOOL DXF2GDIMetaFile::Convert(const DXFRepresentation & rDXF, GDIMetaFile & rMTF } delete pVirDev; - return bStatus; } diff --git a/goodies/source/filter.vcl/idxf/dxf2mtf.hxx b/goodies/source/filter.vcl/idxf/dxf2mtf.hxx index bf32750cc0af..a1bf99639430 100644 --- a/goodies/source/filter.vcl/idxf/dxf2mtf.hxx +++ b/goodies/source/filter.vcl/idxf/dxf2mtf.hxx @@ -33,6 +33,7 @@ #include "dxfreprd.hxx" #include <vcl/font.hxx> +#include <vcl/lineinfo.hxx> // MT: NOOLDSV, someone should change the code... enum PenStyle { PEN_NULL, PEN_SOLID, PEN_DOT, PEN_DASH, PEN_DASHDOT }; @@ -41,6 +42,7 @@ enum BrushStyle { BRUSH_NULL, BRUSH_SOLID, BRUSH_HORZ, BRUSH_VERT, BRUSH_25, BRUSH_50, BRUSH_75, BRUSH_BITMAP }; + class DXF2GDIMetaFile { private: @@ -56,9 +58,9 @@ private: ULONG nMainEntitiesCount; long nBlockColor; - PenStyle eBlockPStyle; + DXFLineInfo aBlockDXFLineInfo; long nParentLayerColor; - PenStyle eParentLayerPStyle; + DXFLineInfo aParentLayerDXFLineInfo; Color aActLineColor; Color aActFillColor; Font aActFont; @@ -71,9 +73,9 @@ private: long GetEntityColor(const DXFBasicEntity & rE); - PenStyle LTypeToPStyle(const char * sLineType); + DXFLineInfo LTypeToDXFLineInfo(const char * sLineType); - PenStyle GetEntityPStyle(const DXFBasicEntity & rE); + DXFLineInfo GetEntityDXFLineInfo(const DXFBasicEntity & rE); BOOL SetLineAttribute(const DXFBasicEntity & rE, ULONG nWidth=0); diff --git a/goodies/source/filter.vcl/idxf/dxfreprd.cxx b/goodies/source/filter.vcl/idxf/dxfreprd.cxx index 7dc2f5d8d58d..80b4cb599b73 100644 --- a/goodies/source/filter.vcl/idxf/dxfreprd.cxx +++ b/goodies/source/filter.vcl/idxf/dxfreprd.cxx @@ -142,7 +142,8 @@ void DXFPalette::SetColor(BYTE nIndex, BYTE nRed, BYTE nGreen, BYTE nBlue) DXFRepresentation::DXFRepresentation() { - setTextEncoding(RTL_TEXTENCODING_IBM_437); + setTextEncoding(RTL_TEXTENCODING_IBM_437); + setGlobalLineTypeScale(1.0); } @@ -217,11 +218,18 @@ void DXFRepresentation::ReadHeader(DXFGroupReader & rDGR) // FIXME: we really need a whole table of // $DWGCODEPAGE to encodings mappings if ( (strcmp(rDGR.GetS(),"ANSI_932")==0) || - (strcmp(rDGR.GetS(),"DOS932")==0) ) + (strcmp(rDGR.GetS(),"ansi_932")==0) || + (strcmp(rDGR.GetS(),"DOS932")==0) || + (strcmp(rDGR.GetS(),"dos932")==0) ) { setTextEncoding(RTL_TEXTENCODING_MS_932); } } + else if (strcmp(rDGR.GetS(),"$LTSCALE")==0) + { + rDGR.Read(); + setGlobalLineTypeScale(getGlobalLineTypeScale() * rDGR.GetF()); + } else rDGR.Read(); } } diff --git a/goodies/source/filter.vcl/idxf/dxfreprd.hxx b/goodies/source/filter.vcl/idxf/dxfreprd.hxx index 490f7af57223..13ca7d022697 100644 --- a/goodies/source/filter.vcl/idxf/dxfreprd.hxx +++ b/goodies/source/filter.vcl/idxf/dxfreprd.hxx @@ -101,7 +101,9 @@ public: DXFEntities aEntities; // Die Entities (aus der Entities-Section) der DXF-Datei - rtl_TextEncoding mEnc; + rtl_TextEncoding mEnc; // $DWGCODEPAGE + + double mfGlobalLineTypeScale; // $LTSCALE DXFRepresentation(); ~DXFRepresentation(); @@ -109,6 +111,9 @@ public: rtl_TextEncoding getTextEncoding() const; void setTextEncoding(rtl_TextEncoding aEnc); + double getGlobalLineTypeScale() const; + void setGlobalLineTypeScale(double fGlobalLineTypeScale); + BOOL Read( SvStream & rIStream, USHORT nMinPercent, USHORT nMaxPercent); // Liesst die komplette DXF-Datei ein. @@ -128,7 +133,8 @@ inline BYTE DXFPalette::GetGreen(BYTE nIndex) const { return pGreen[nIndex]; } inline BYTE DXFPalette::GetBlue(BYTE nIndex) const { return pBlue[nIndex]; } inline rtl_TextEncoding DXFRepresentation::getTextEncoding() const { return mEnc; } inline void DXFRepresentation::setTextEncoding(rtl_TextEncoding aEnc) { mEnc = aEnc; } - +inline double DXFRepresentation::getGlobalLineTypeScale() const { return mfGlobalLineTypeScale; } +inline void DXFRepresentation::setGlobalLineTypeScale(double fGlobalLineTypeScale) { mfGlobalLineTypeScale = fGlobalLineTypeScale; } #endif diff --git a/goodies/source/filter.vcl/idxf/dxfvec.cxx b/goodies/source/filter.vcl/idxf/dxfvec.cxx index ee5a923a8684..48bc93ae3eb6 100644 --- a/goodies/source/filter.vcl/idxf/dxfvec.cxx +++ b/goodies/source/filter.vcl/idxf/dxfvec.cxx @@ -206,6 +206,32 @@ BOOL DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & r else return FALSE; } +LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const +{ + double fex,fey,scale; + + fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy); + fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy); + scale = (fex+fey)/2.0; + + LineInfo aLineInfo; + + aLineInfo.SetStyle( aDXFLineInfo.eStyle ); + aLineInfo.SetWidth( (sal_Int32) (aDXFLineInfo.fWidth * scale + 0.5) ); + aLineInfo.SetDashCount( static_cast< USHORT >( aDXFLineInfo.nDashCount ) ); + aLineInfo.SetDashLen( (sal_Int32) (aDXFLineInfo.fDashLen * scale + 0.5) ); + aLineInfo.SetDotCount( static_cast< USHORT >( aDXFLineInfo.nDotCount ) ); + aLineInfo.SetDotLen( (sal_Int32) (aDXFLineInfo.fDotLen * scale + 0.5) ); + aLineInfo.SetDistance( (sal_Int32) (aDXFLineInfo.fDistance * scale + 0.5) ); + + if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 ) + aLineInfo.SetDashLen(1); + + if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 ) + aLineInfo.SetDotLen(1); + + return aLineInfo; +} ULONG DXFTransform::TransLineWidth(double fW) const { @@ -213,6 +239,8 @@ ULONG DXFTransform::TransLineWidth(double fW) const fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy); fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy); + // ### + // printf("fex=%f fey=%f\n", fex, fey); return (ULONG)(fabs(fW)*(fex+fey)/2.0+0.5); } @@ -227,4 +255,3 @@ BOOL DXFTransform::Mirror() const if (aMZ.SProd(aMX*aMY)<0) return TRUE; else return FALSE; } - diff --git a/goodies/source/filter.vcl/idxf/dxfvec.hxx b/goodies/source/filter.vcl/idxf/dxfvec.hxx index 5ccc0be25774..aca26df46676 100644 --- a/goodies/source/filter.vcl/idxf/dxfvec.hxx +++ b/goodies/source/filter.vcl/idxf/dxfvec.hxx @@ -32,6 +32,37 @@ #define _DXFVEC_HXX #include <tools/gen.hxx> +#include <vcl/lineinfo.hxx> + +class DXFLineInfo { +public: + LineStyle eStyle; + double fWidth; + sal_Int32 nDashCount; + double fDashLen; + sal_Int32 nDotCount; + double fDotLen; + double fDistance; + + DXFLineInfo() : + eStyle(LINE_SOLID), + fWidth(0), + nDashCount(0), + fDashLen(0), + nDotCount(0), + fDotLen(0), + fDistance(0) {} + + DXFLineInfo(const DXFLineInfo& x) : + eStyle(x.eStyle), + fWidth(x.fWidth), + nDashCount(x.nDashCount), + fDashLen(x.fDashLen), + nDotCount(x.nDotCount), + fDotLen(x.fDotLen), + fDistance(x.fDistance) {} + +}; //------------------------------------------------------------------------------ @@ -135,6 +166,9 @@ public: BOOL Mirror() const; // Liefert TRUE, wenn die Matrix ein Linkssystem bildet + LineInfo Transform(const DXFLineInfo& aDXFLineInfo) const; + // Transform to LineInfo + private: DXFVector aMX; DXFVector aMY; diff --git a/goodies/source/graphic/grfmgr.cxx b/goodies/source/graphic/grfmgr.cxx index bece8389d270..5cb37a51e81f 100644 --- a/goodies/source/graphic/grfmgr.cxx +++ b/goodies/source/graphic/grfmgr.cxx @@ -44,7 +44,6 @@ #include <vcl/metaact.hxx> #include <vcl/virdev.hxx> #include <vcl/salbtype.hxx> -#include <vcl/pdfextoutdevdata.hxx> #include <svtools/cacheoptions.hxx> #include "grfmgr.hxx" @@ -674,31 +673,11 @@ BOOL GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz, const sal_uInt32 nOldDrawMode = pOut->GetDrawMode(); BOOL bCropped = aAttr.IsCropped(); BOOL bCached = FALSE; - BOOL bWritingPdfLinkedGraphic = FALSE; BOOL bRet; // #i29534# Provide output rects for PDF writer Rectangle aCropRect; - // #i29534# Notify PDF writer about linked graphic (if any) - vcl::ExtOutDevData* pExtOutDevData = pOut->GetExtOutDevData(); - if( pExtOutDevData && pExtOutDevData->ISA(vcl::PDFExtOutDevData) ) - { - // #i29534# Only delegate image handling to PDF, if no special - // treatment is necessary - if( GetGraphic().IsLink() && - aSz.Width() > 0L && - aSz.Height() > 0L && - !aAttr.IsSpecialDrawMode() && - !aAttr.IsMirrored() && - !aAttr.IsRotated() && - !aAttr.IsAdjusted() ) - { - bWritingPdfLinkedGraphic = TRUE; - static_cast< vcl::PDFExtOutDevData* >( pExtOutDevData )->BeginGroup(); - } - } - if( !( GRFMGR_DRAW_USE_DRAWMODE_SETTINGS & nFlags ) ) pOut->SetDrawMode( nOldDrawMode & ( ~( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ) ) ); @@ -749,16 +728,6 @@ BOOL GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz, pOut->SetDrawMode( nOldDrawMode ); - // #i29534# Notify PDF writer about linked graphic (if any) - if( bWritingPdfLinkedGraphic ) - { - static_cast< vcl::PDFExtOutDevData* >( pExtOutDevData )->EndGroup( - const_cast< Graphic& >(GetGraphic()), - aAttr.GetTransparency(), - Rectangle( aPt, aSz ), - aCropRect ); - } - // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins // (code above needs to call GetGraphic twice) if( bCached ) diff --git a/i18npool/inc/breakiterator_ctl.hxx b/i18npool/inc/breakiterator_ctl.hxx index 9e753e8ae16f..3e687b5e8e68 100644 --- a/i18npool/inc/breakiterator_ctl.hxx +++ b/i18npool/inc/breakiterator_ctl.hxx @@ -58,6 +58,7 @@ protected: sal_Int32* nextCellIndex; sal_Int32* previousCellIndex; sal_Int32 cellIndexSize; + virtual void SAL_CALL makeIndex(const rtl::OUString& text, sal_Int32 pos) throw(com::sun::star::uno::RuntimeException); }; diff --git a/i18npool/inc/breakiterator_unicode.hxx b/i18npool/inc/breakiterator_unicode.hxx index 3a0720f27545..654df424b237 100644 --- a/i18npool/inc/breakiterator_unicode.hxx +++ b/i18npool/inc/breakiterator_unicode.hxx @@ -86,12 +86,16 @@ protected: const sal_Char *cBreakIterator, *wordRule, *lineRule; Boundary result; // for word break iterator - struct { + struct BI_Data { UnicodeString aICUText; icu::BreakIterator *aBreakIterator; + + BI_Data() : aICUText(), aBreakIterator(NULL) {} } character, word, sentence, line, *icuBI; + com::sun::star::lang::Locale aLocale; sal_Int16 aBreakType, aWordType; + void SAL_CALL loadICUBreakIterator(const com::sun::star::lang::Locale& rLocale, sal_Int16 rBreakType, sal_Int16 rWordType, const sal_Char* name, const rtl::OUString& rText) throw(com::sun::star::uno::RuntimeException); }; diff --git a/i18npool/inc/i18npool/paper.hxx b/i18npool/inc/i18npool/paper.hxx new file mode 100644 index 000000000000..5690a8fe7254 --- /dev/null +++ b/i18npool/inc/i18npool/paper.hxx @@ -0,0 +1,155 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * + * $Revision$ + * + * last change: $Author$ $Date$ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#ifndef INCLUDED_I18NPOOL_PAPER_HXX +#define INCLUDED_I18NPOOL_PAPER_HXX + +#include <sal/config.h> + +#include "i18npool/i18npooldllapi.h" +#include <rtl/string.hxx> +#include <com/sun/star/lang/Locale.hpp> + +enum Paper +{ + PAPER_A0, + PAPER_A1, + PAPER_A2, + PAPER_A3, + PAPER_A4, + PAPER_A5, + PAPER_B4_ISO, + PAPER_B5_ISO, + PAPER_LETTER, + PAPER_LEGAL, + PAPER_TABLOID, + PAPER_USER, + PAPER_B6_ISO, + PAPER_ENV_C4, + PAPER_ENV_C5, + PAPER_ENV_C6, + PAPER_ENV_C65, + PAPER_ENV_DL, + PAPER_SLIDE_DIA, + PAPER_SCREEN, + PAPER_C, + PAPER_D, + PAPER_E, + PAPER_EXECUTIVE, + PAPER_FANFOLD_LEGAL_DE, + PAPER_ENV_MONARCH, + PAPER_ENV_PERSONAL, + PAPER_ENV_9, + PAPER_ENV_10, + PAPER_ENV_11, + PAPER_ENV_12, + PAPER_KAI16, + PAPER_KAI32, + PAPER_KAI32BIG, + PAPER_B4_JIS, + PAPER_B5_JIS, + PAPER_B6_JIS, + PAPER_LEDGER, + PAPER_STATEMENT, + PAPER_QUARTO, + PAPER_10x14, + PAPER_ENV_14, + PAPER_ENV_C3, + PAPER_ENV_ITALY, + PAPER_FANFOLD_US, + PAPER_FANFOLD_DE, + PAPER_POSTCARD_JP, + PAPER_9x11, + PAPER_10x11, + PAPER_15x11, + PAPER_ENV_INVITE, + PAPER_A_PLUS, + PAPER_B_PLUS, + PAPER_LETTER_PLUS, + PAPER_A4_PLUS, + PAPER_DOUBLEPOSTCARD_JP, + PAPER_A6, + PAPER_12x11, + PAPER_A7, + PAPER_A8, + PAPER_A9, + PAPER_A10, + PAPER_B0_ISO, + PAPER_B1_ISO, + PAPER_B2_ISO, + PAPER_B3_ISO, + PAPER_B7_ISO, + PAPER_B8_ISO, + PAPER_B9_ISO, + PAPER_B10_ISO, + PAPER_ENV_C2, + PAPER_ENV_C7, + PAPER_ENV_C8, + PAPER_ARCHA, + PAPER_ARCHB, + PAPER_ARCHC, + PAPER_ARCHD, + PAPER_ARCHE +}; + +// --------- +// - Paper - +// --------- + +class I18NPOOL_DLLPUBLIC PaperInfo +{ + Paper m_eType; + long m_nPaperWidth; // width in 100thMM + long m_nPaperHeight; // height in 100thMM +public: + PaperInfo(Paper eType); + PaperInfo(long nPaperWidth, long nPaperHeight); + + Paper getPaper() const { return m_eType; } + long getWidth() const { return m_nPaperWidth; } + long getHeight() const { return m_nPaperHeight; } + bool sloppyEqual(const PaperInfo &rOther) const; + bool doSloppyFit(); + + static PaperInfo getSystemDefaultPaper(); + static PaperInfo getDefaultPaperForLocale(const ::com::sun::star::lang::Locale & rLocale); + + static Paper fromPSName(const rtl::OString &rName); + static rtl::OString toPSName(Paper eType); + + static long sloppyFitPageDimension(long nDimension); +}; + +#endif // INCLUDED_I18NPOOL_PAPER_HXX diff --git a/i18npool/inc/xdictionary.hxx b/i18npool/inc/xdictionary.hxx index 32ffdbbfe377..04c5836aaaea 100644 --- a/i18npool/inc/xdictionary.hxx +++ b/i18npool/inc/xdictionary.hxx @@ -45,11 +45,13 @@ namespace com { namespace sun { namespace star { namespace i18n { // cache structure. struct WordBreakCache { - sal_Bool equals(const sal_Unicode *str, Boundary& boundary); // checking cached string sal_Int32 length; // contents length saved here. sal_Unicode *contents; // seperated segment contents. sal_Int32* wordboundary; // word boundaries in segments. sal_Int32 size; // size of wordboundary + + WordBreakCache(); + sal_Bool equals(const sal_Unicode *str, Boundary& boundary); // checking cached string }; class xdictionary diff --git a/i18npool/prj/build.lst b/i18npool/prj/build.lst index 98fec96d0149..24e9607596ac 100644 --- a/i18npool/prj/build.lst +++ b/i18npool/prj/build.lst @@ -9,6 +9,7 @@ inp i18npool\source\transliteration nmake - all inp_translit inp inp i18npool\source\isolang nmake - all inp_isolang inp_inc NULL inp i18npool\source\localedata nmake - all inp_localedata inp_isolang inp_inc NULL inp i18npool\source\localedata\data nmake - all inp_locdata_data inp_localedata inp_inc NULL +inp i18npool\source\paper nmake - all inp_paper inp_isolang inp_inc NULL inp i18npool\source\calendar nmake - all inp_cal inp_inc NULL inp i18npool\source\numberformatcode nmake - all inp_numformat inp_inc NULL inp i18npool\source\defaultnumberingprovider nmake - all inp_dnum inp_inc NULL @@ -22,4 +23,4 @@ inp i18npool\source\textconversion nmake - all inp_textconversi inp i18npool\source\textconversion\data nmake - all inp_textconv_dict inp_textconversion inp_inc NULL inp i18npool\source\search nmake - all inp_search inp_inc NULL inp i18npool\source\ordinalsuffix nmake - all inp_ordinalsuffix NULL -inp i18npool\util nmake - all inp_util inp_brkit inp_dict inp_chclass inp_translit inp_cal inp_dnum inp_natnum inp_localedata inp_locdata_data inp_numformat inp_rserv inp_index inp_index_data inp_collator inp_collator_data inp_inputchecker inp_textconversion inp_textconv_dict inp_search inp_isolang inp_ordinalsuffix NULL +inp i18npool\util nmake - all inp_util inp_brkit inp_dict inp_chclass inp_translit inp_cal inp_dnum inp_natnum inp_localedata inp_locdata_data inp_numformat inp_rserv inp_index inp_index_data inp_collator inp_collator_data inp_inputchecker inp_textconversion inp_textconv_dict inp_search inp_isolang inp_paper inp_ordinalsuffix NULL diff --git a/i18npool/prj/d.lst b/i18npool/prj/d.lst index 052ad4d23273..54aefa732b89 100644 --- a/i18npool/prj/d.lst +++ b/i18npool/prj/d.lst @@ -40,3 +40,9 @@ mkdir: %_DEST%\inc%_EXT%\i18npool ..\%__SRC%\bin\i18nisol*.dll %_DEST%\bin%_EXT%\i18nisol*.dll ..\%__SRC%\lib\libi18nisolang*.so %_DEST%\lib%_EXT%\libi18nisolang*.so ..\%__SRC%\lib\libi18nisolang*.dylib %_DEST%\lib%_EXT%\libi18nisolang*.dylib + +..\%__SRC%\lib\ii18npaper*.lib %_DEST%\lib%_EXT%\ii18npaper*.lib +..\%__SRC%\bin\i18npaper*.dll %_DEST%\bin%_EXT%\i18npaper*.dll +..\%__SRC%\lib\libi18npaper*.so %_DEST%\lib%_EXT%\libi18npaper*.so +..\%__SRC%\lib\libi18npaper*.dylib %_DEST%\lib%_EXT%\libi18npaper*.dylib + diff --git a/i18npool/source/breakiterator/breakiterator_cjk.cxx b/i18npool/source/breakiterator/breakiterator_cjk.cxx index 3d684b8788df..3a44c02edc23 100644 --- a/i18npool/source/breakiterator/breakiterator_cjk.cxx +++ b/i18npool/source/breakiterator/breakiterator_cjk.cxx @@ -46,7 +46,9 @@ namespace com { namespace sun { namespace star { namespace i18n { // class BreakIterator_CJK // ----------------------------------------------------; -BreakIterator_CJK::BreakIterator_CJK() : dict(NULL) +BreakIterator_CJK::BreakIterator_CJK() : + dict( NULL ), + hangingCharacters() { cBreakIterator = "com.sun.star.i18n.BreakIterator_CJK"; } diff --git a/i18npool/source/breakiterator/breakiterator_ctl.cxx b/i18npool/source/breakiterator/breakiterator_ctl.cxx index a42014615f1a..0e1bee869cac 100644 --- a/i18npool/source/breakiterator/breakiterator_ctl.cxx +++ b/i18npool/source/breakiterator/breakiterator_ctl.cxx @@ -45,11 +45,14 @@ namespace com { namespace sun { namespace star { namespace i18n { /** * Constructor. */ -BreakIterator_CTL::BreakIterator_CTL() +BreakIterator_CTL::BreakIterator_CTL() : + cachedText(), + nextCellIndex( NULL ), + previousCellIndex( NULL ), + cellIndexSize( 512 ) { cBreakIterator = "com.sun.star.i18n.BreakIterator_CTL"; // to improve performance, alloc big enough memory in construct. - cellIndexSize = 512; nextCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32)); previousCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32)); memset(nextCellIndex, 0, cellIndexSize * sizeof(sal_Int32)); diff --git a/i18npool/source/breakiterator/breakiterator_unicode.cxx b/i18npool/source/breakiterator/breakiterator_unicode.cxx index b832bb02e7e9..f0710c996858 100644 --- a/i18npool/source/breakiterator/breakiterator_unicode.cxx +++ b/i18npool/source/breakiterator/breakiterator_unicode.cxx @@ -51,20 +51,23 @@ namespace com { namespace sun { namespace star { namespace i18n { #define ERROR ::com::sun::star::uno::RuntimeException() -#define ImplementName "com.sun.star.i18n.BreakIterator_Unicode"; - - -BreakIterator_Unicode::BreakIterator_Unicode() +//#define ImplementName "com.sun.star.i18n.BreakIterator_Unicode"; + + +BreakIterator_Unicode::BreakIterator_Unicode() : + cBreakIterator( "com.sun.star.i18n.BreakIterator_Unicode" ), // implementation name + wordRule( "word" ), + lineRule( "line" ), + result(), + character(), + word(), + sentence(), + line(), + icuBI( NULL ), + aLocale(), + aBreakType(), + aWordType() { - wordRule="word"; - lineRule="line"; - character.aBreakIterator=word.aBreakIterator=sentence.aBreakIterator=line.aBreakIterator=NULL; - character.aICUText=UnicodeString(); - word.aICUText=UnicodeString(); - sentence.aICUText=UnicodeString(); - line.aICUText=UnicodeString(); - cBreakIterator = ImplementName; - icuBI=NULL; } diff --git a/i18npool/source/breakiterator/data/dict_word.txt b/i18npool/source/breakiterator/data/dict_word.txt index 4c5c80823041..367a82db9e6f 100644 --- a/i18npool/source/breakiterator/data/dict_word.txt +++ b/i18npool/source/breakiterator/data/dict_word.txt @@ -34,7 +34,8 @@ $ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCT $MidLetter = [[:name = APOSTROPHE:] [:name = GRAVE ACCENT:] \u0084 [:name = SOFT HYPHEN:] [:name = MIDDLE DOT:] [:name = GREEK TONOS:] [:name= FULL STOP:] [:name = HEBREW PUNCTUATION GERSHAYIM:] [:name = DOUBLE VERTICAL LINE:] [:name = LEFT SINGLE QUOTATION MARK:] - [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] ]; + [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] + [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:] ]; $SufixLetter = [:name= FULL STOP:]; diff --git a/i18npool/source/breakiterator/data/dict_word_dash.txt b/i18npool/source/breakiterator/data/dict_word_nodash.txt index 7f861c7911ca..4c5c80823041 100644 --- a/i18npool/source/breakiterator/data/dict_word_dash.txt +++ b/i18npool/source/breakiterator/data/dict_word_nodash.txt @@ -34,8 +34,7 @@ $ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCT $MidLetter = [[:name = APOSTROPHE:] [:name = GRAVE ACCENT:] \u0084 [:name = SOFT HYPHEN:] [:name = MIDDLE DOT:] [:name = GREEK TONOS:] [:name= FULL STOP:] [:name = HEBREW PUNCTUATION GERSHAYIM:] [:name = DOUBLE VERTICAL LINE:] [:name = LEFT SINGLE QUOTATION MARK:] - [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] - [:name = HYPHEN-MINUS:] [:name = EN DASH:] ]; + [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] ]; $SufixLetter = [:name= FULL STOP:]; diff --git a/i18npool/source/breakiterator/data/dict_word_prepostdash.txt b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt new file mode 100644 index 000000000000..1bf94451fae2 --- /dev/null +++ b/i18npool/source/breakiterator/data/dict_word_prepostdash.txt @@ -0,0 +1,157 @@ +# +# Copyright (C) 2002-2003, International Business Machines Corporation and others. +# All Rights Reserved. +# +# file: dict_word.txt +# +# ICU Word Break Rules +# See Unicode Standard Annex #29. +# These rules are based on Version 4.0.0, dated 2003-04-17 +# + + + +#################################################################################### +# +# Character class definitions from TR 29 +# +#################################################################################### +$Katakana = [[:Script = KATAKANA:] [:name = KATAKANA-HIRAGANA PROLONGED SOUND MARK:] + [:name = HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK:] + [:name = HALFWIDTH KATAKANA VOICED SOUND MARK:] + [:name = HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK:]]; + +$Ideographic = [:Ideographic:]; +$Hangul = [:Script = HANGUL:]; + +# list of dashes or hyphens that should be accepted as part of the word if a single one of these +# pre- or postfixes a word. E.g. in German: "Arbeits-" or "-nehmer" where that hyphen needs to +# be part of the word in order to have it properly spell checked etc. +$PrePostDashHyphen = [ [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:] ]; + + +$ALetter = [\u0002 [:Alphabetic:] [:name= COMMERCIAL AT:] [:name= HEBREW PUNCTUATION GERESH:] + - $Ideographic + - $Katakana + - $Hangul + - [:Script = Thai:] + - [:Script = Lao:] + - [:Script = Hiragana:]]; + +$MidLetter = [[:name = APOSTROPHE:] [:name = GRAVE ACCENT:] \u0084 [:name = SOFT HYPHEN:] [:name = MIDDLE DOT:] [:name = GREEK TONOS:] [:name= FULL STOP:] + [:name = HEBREW PUNCTUATION GERSHAYIM:] [:name = DOUBLE VERTICAL LINE:] [:name = LEFT SINGLE QUOTATION MARK:] + [:name = RIGHT SINGLE QUOTATION MARK:] [:name = HYPHENATION POINT:] [:name = PRIME:] + [:name = HYPHEN-MINUS:] [:name = EN DASH:] [:name = EM DASH:] ]; + +$SufixLetter = [:name= FULL STOP:]; + + +$MidNum = [[:LineBreak = Infix_Numeric:] [:name= COMMERCIAL AT:] \u0084 [:name = GREEK TONOS:] [:name = ARABIC DECIMAL SEPARATOR:] + [:name = LEFT SINGLE QUOTATION MARK:] [:name = RIGHT SINGLE QUOTATION MARK:] [:name = SINGLE HIGH-REVERSED-9 QUOTATION MARK:] + [:name = PRIME:]]; +$Numeric = [:LineBreak = Numeric:]; + + +$TheZWSP = \u200b; + +# +# Character Class Definitions. +# The names are those from TR29. +# +$CR = \u000d; +$LF = \u000a; +$Control = [[[:Zl:] [:Zp:] [:Cc:] [:Cf:]] - $TheZWSP]; +$Extend = [[:Grapheme_Extend = TRUE:]]; + + + + +#################################################################################### +# +# Word Break Rules. Definitions and Rules specific to word break begin Here. +# +#################################################################################### + +$Format = [[:Cf:] - $TheZWSP]; + + + +# Rule 3: Treat a grapheme cluster as if it were a single character. +# Hangul Syllables are easier to deal with here than they are in Grapheme Clusters +# because we don't need to find the boundaries between adjacent syllables - +# they won't be word boundaries. +# + + +# +# "Extended" definitions. Grapheme Cluster + Format Chars, treated like the base char. +# +$ALetterEx = $ALetter $Extend*; +$NumericEx = $Numeric $Extend*; +$MidNumEx = $MidNum $Extend*; +$MidLetterEx = $MidLetter $Extend*; +$SufixLetterEx= $SufixLetter $Extend*; +$KatakanaEx = $Katakana $Extend*; +$IdeographicEx= $Ideographic $Extend*; +$HangulEx = $Hangul $Extend*; +$FormatEx = $Format $Extend*; + + +# +# Numbers. Rules 8, 11, 12 form the TR. +# +$NumberSequence = $NumericEx ($FormatEx* $MidNumEx? $FormatEx* $NumericEx)*; +$NumberSequence {100}; + +# +# Words. Alpha-numerics. Rule 5, 6, 7, 9, 10 +# - must include at least one letter. +# - may include both letters and numbers. +# - may include MideLetter, MidNumber punctuation. +# +# At most one leading or trailing dash/hyphen should be accepted as well. +# E.g. in German: "Arbeits-" or "-nehmer" where that hyphen needs to +# be part of the word in order to have it properly spell checked etc. +$LetterSequence = $PrePostDashHyphen? $ALetterEx ($FormatEx* $MidLetterEx? $FormatEx* $ALetterEx)* $PrePostDashHyphen?; # rules #6, #7 +($NumberSequence $FormatEx*)? $LetterSequence ($FormatEx* ($NumberSequence | $LetterSequence))* $SufixLetterEx? {200}; + +[[:P:][:S:]]*; + +# +# Do not break between Katakana. Rule #13. +# +$KatakanaEx ($FormatEx* $KatakanaEx)* {300}; +[:Hiragana:] $Extend* {300}; + +# +# Ideographic Characters. Stand by themselves as words. +# Separated from the "Everything Else" rule, below, only so that they +# can be tagged with a return value. TODO: is this what we want? +# +$IdeographicEx ($FormatEx* $IdeographicEx)* {400}; +$HangulEx ($FormatEx* $HangulEx)* {400}; + +# +# Everything Else, with no tag. +# Non-Control chars combine with $Extend (combining) chars. +# Controls are do not. +# +[^$Control [:Ideographic:]] $Extend*; +$CR $LF; + +# +# Reverse Rules. Back up over any of the chars that can group together. +# (Reverse rules do not need to be exact; they can back up too far, +# but must back up at least enough, and must stop on a boundary.) +# + +# NonStarters are the set of all characters that can appear at the 2nd - nth position of +# a word. (They may also be the first.) The reverse rule skips over these, until it +# reaches something that can only be the start (and probably only) char in a "word". +# A space or punctuation meets the test. +# +$NonStarters = [$Numeric $ALetter $Katakana $Ideographic $Hangul [:P:] [:S:] $MidLetter $MidNum $SufixLetter $Extend $Format]; + +#!.*; +! ($NonStarters* | \n \r) .; + diff --git a/i18npool/source/breakiterator/makefile.mk b/i18npool/source/breakiterator/makefile.mk index 7ba9cd3e753d..50e437e98b91 100644 --- a/i18npool/source/breakiterator/makefile.mk +++ b/i18npool/source/breakiterator/makefile.mk @@ -93,7 +93,7 @@ $(MISC)$/%_brk.c : $(MISC)$/%.brk # The output of gencmn generates warnings under Windows. We want to minimize the patches to external tools, # so the output (OpenOffice_icu_dat.c) is changed here to include a pragma to disable the warnings. # Output of gencmn is redirected to OpenOffice_icu_tmp.c with the -t switch. -$(MISC)$/OpenOffice_%.c : +$(MISC)$/OpenOffice_%.c : $(MY_BRK_BRKFILES:s/.brk/_brk.c/) $(WRAPCMD) $(GENCMN) -n OpenOffice -t tmp -S -d $(MISC) O $(mktmp $(subst,$(MISC)$/, $(MY_BRK_BRKFILES:t"\n"))) echo $(USQ)#ifdef _MSC_VER$(USQ) > $@ echo $(USQ)#pragma warning( disable : 4229 4668 )$(USQ) >> $@ diff --git a/i18npool/source/breakiterator/xdictionary.cxx b/i18npool/source/breakiterator/xdictionary.cxx index fb832f0b6468..f286dd2449ac 100644 --- a/i18npool/source/breakiterator/xdictionary.cxx +++ b/i18npool/source/breakiterator/xdictionary.cxx @@ -54,7 +54,21 @@ namespace com { namespace sun { namespace star { namespace i18n { extern "C" { static void SAL_CALL thisModule() {} } -xdictionary::xdictionary(const sal_Char *lang) +xdictionary::xdictionary(const sal_Char *lang) : + existMark( NULL ), + index1( NULL ), + index2( NULL ), + lenArray( NULL ), + dataArea( NULL ), + hModule( NULL ), + boundary(), + japaneseWordBreak( sal_False ) +#if USE_CELL_BOUNDARY_CODE + // For CTL breakiterator, where the word boundary should not be inside cell. + , + useCellBoundary( sal_False ), + cellBoundary( NULL ) +#endif { index1 = 0; #ifdef SAL_DLLPREFIX @@ -92,6 +106,7 @@ xdictionary::xdictionary(const sal_Char *lang) #if USE_CELL_BOUNDARY_CODE useCellBoundary = sal_False; + cellBoundary = NULL; #endif japaneseWordBreak = sal_False; } @@ -149,6 +164,19 @@ sal_Int32 xdictionary::getLongestMatch(const sal_Unicode* str, sal_Int32 sLen) { return 0; } + +/* + * c-tor + */ + +WordBreakCache::WordBreakCache() : + length( 0 ), + contents( NULL ), + wordboundary( NULL ), + size( 0 ) +{ +} + /* * Compare two unicode string, */ diff --git a/i18npool/source/calendar/calendar_gregorian.cxx b/i18npool/source/calendar/calendar_gregorian.cxx index 96eee0772bc1..50b61eae5cf1 100644 --- a/i18npool/source/calendar/calendar_gregorian.cxx +++ b/i18npool/source/calendar/calendar_gregorian.cxx @@ -148,10 +148,42 @@ void SAL_CALL Calendar_gregorian::init(Era *_eraArray) { cCalendar = "com.sun.star.i18n.Calendar_gregorian"; + + // #i102356# With icu::Calendar::createInstance(UErrorCode) in a Thai + // th_TH system locale we accidentally used a Buddhist calendar. Though + // the ICU documentation says that should be the case only for + // th_TH_TRADITIONAL (and ja_JP_TRADITIONAL Gengou), a plain th_TH + // already triggers that behavior, ja_JP does not. Strange enough, + // passing a th_TH locale to the calendar creation doesn't trigger + // this. + // See also http://userguide.icu-project.org/datetime/calendar + + // Whatever ICU offers as the default calendar for a locale, ensure we + // have a Gregorian calendar as requested. + + /* XXX: with the current implementation the aLocale member variable is + * not set prior to loading a calendar from locale data. This + * creates an empty (root) locale for ICU, but at least the correct + * calendar is used. The language part must not be NULL (respectively + * not all, language and country and variant), otherwise the current + * default locale would be used again and the calendar keyword ignored. + * */ + icu::Locale aIcuLocale( "", NULL, NULL, "calendar=gregorian"); + UErrorCode status; - body = icu::Calendar::createInstance(status = U_ZERO_ERROR); + body = icu::Calendar::createInstance( aIcuLocale, status = U_ZERO_ERROR); if (!body || !U_SUCCESS(status)) throw ERROR; +#if 0 + { + icu::Locale loc; + loc = body->getLocale( ULOC_ACTUAL_LOCALE, status = U_ZERO_ERROR); + fprintf( stderr, "\nICU calendar actual locale: %s\n", loc.getName()); + loc = body->getLocale( ULOC_VALID_LOCALE, status = U_ZERO_ERROR); + fprintf( stderr, "ICU calendar valid locale: %s\n", loc.getName()); + } +#endif + eraArray=_eraArray; } diff --git a/i18npool/source/localedata/data/de_DE.xml b/i18npool/source/localedata/data/de_DE.xml index 295b826a5e9f..a83b3dbb791d 100644 --- a/i18npool/source/localedata/data/de_DE.xml +++ b/i18npool/source/localedata/data/de_DE.xml @@ -328,7 +328,14 @@ </LC_CURRENCY> <LC_TRANSLITERATION ref="en_US"/> <LC_MISC> - <ReservedWords> + <BreakIteratorRules> + <EditMode/> + <DictionaryMode>dict_word_prepostdash</DictionaryMode> + <WordCountMode/> + <CharacterMode/> + <LineMode/> + </BreakIteratorRules> + <ReservedWords> <trueWord>wahr</trueWord> <falseWord>falsch</falseWord> <quarter1Word>1. Quartal</quarter1Word> diff --git a/i18npool/source/localedata/data/nl_NL.xml b/i18npool/source/localedata/data/nl_NL.xml index eedfdc146b5e..5a91c9c3e42e 100644 --- a/i18npool/source/localedata/data/nl_NL.xml +++ b/i18npool/source/localedata/data/nl_NL.xml @@ -360,20 +360,27 @@ </LC_CURRENCY> <LC_TRANSLITERATION ref="en_US"/> <LC_MISC> -<ReservedWords> -<trueWord>waar</trueWord> -<falseWord>onwaar</falseWord> -<quarter1Word>1ste kwartaal</quarter1Word> -<quarter2Word>2de kwartaal</quarter2Word> -<quarter3Word>3de kwartaal</quarter3Word> -<quarter4Word>4de kwartaal</quarter4Word> -<aboveWord>boven</aboveWord> -<belowWord>onder</belowWord> -<quarter1Abbreviation>K1</quarter1Abbreviation> -<quarter2Abbreviation>K2</quarter2Abbreviation> -<quarter3Abbreviation>K3</quarter3Abbreviation> -<quarter4Abbreviation>K4</quarter4Abbreviation> -</ReservedWords> + <BreakIteratorRules> + <EditMode/> + <DictionaryMode>dict_word_prepostdash</DictionaryMode> + <WordCountMode/> + <CharacterMode/> + <LineMode/> + </BreakIteratorRules> + <ReservedWords> + <trueWord>waar</trueWord> + <falseWord>onwaar</falseWord> + <quarter1Word>1ste kwartaal</quarter1Word> + <quarter2Word>2de kwartaal</quarter2Word> + <quarter3Word>3de kwartaal</quarter3Word> + <quarter4Word>4de kwartaal</quarter4Word> + <aboveWord>boven</aboveWord> + <belowWord>onder</belowWord> + <quarter1Abbreviation>K1</quarter1Abbreviation> + <quarter2Abbreviation>K2</quarter2Abbreviation> + <quarter3Abbreviation>K3</quarter3Abbreviation> + <quarter4Abbreviation>K4</quarter4Abbreviation> + </ReservedWords> </LC_MISC> <LC_NumberingLevel ref="en_US"/> <LC_OutLineNumberingLevel ref="en_US"/> diff --git a/i18npool/source/localedata/data/pl_PL.xml b/i18npool/source/localedata/data/pl_PL.xml index 4119060ea7df..195689666247 100644 --- a/i18npool/source/localedata/data/pl_PL.xml +++ b/i18npool/source/localedata/data/pl_PL.xml @@ -326,13 +326,6 @@ </LC_CURRENCY> <LC_TRANSLITERATION ref="en_US"/> <LC_MISC> - <BreakIteratorRules> - <EditMode/> - <DictionaryMode>dict_word_dash</DictionaryMode> - <WordCountMode/> - <CharacterMode/> - <LineMode/> - </BreakIteratorRules> <ReservedWords> <trueWord>prawda</trueWord> <falseWord>fałsz</falseWord> diff --git a/i18npool/source/localedata/data/sv_SE.xml b/i18npool/source/localedata/data/sv_SE.xml index 333690a0ef09..211f95c3e894 100644 --- a/i18npool/source/localedata/data/sv_SE.xml +++ b/i18npool/source/localedata/data/sv_SE.xml @@ -315,6 +315,13 @@ </LC_CURRENCY> <LC_TRANSLITERATION ref="en_US"/> <LC_MISC> + <BreakIteratorRules> + <EditMode/> + <DictionaryMode>dict_word_prepostdash</DictionaryMode> + <WordCountMode/> + <CharacterMode/> + <LineMode/> + </BreakIteratorRules> <ReservedWords> <trueWord>sant</trueWord> <falseWord>falskt</falseWord> diff --git a/i18npool/source/paper/makefile.mk b/i18npool/source/paper/makefile.mk new file mode 100644 index 000000000000..2aef382a32fa --- /dev/null +++ b/i18npool/source/paper/makefile.mk @@ -0,0 +1,75 @@ +#************************************************************************* +#* +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.9 $ +# +# 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. +# +#************************************************************************/ + +PRJ=..$/.. + +PRJNAME=i18npool +TARGET=i18npaper + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/version.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- +# +SLOFILES=$(SLO)$/paper.obj +SHL1OBJS=$(SLOFILES) + +SHL1TARGET=$(TARGET)$(DLLPOSTFIX) +SHL1IMPLIB=i$(TARGET) + +DEF1DEPN=$(MISC)$/$(SHL1TARGET).flt +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) +DEFLIB1NAME=$(SHL1TARGET) + +LIB1TARGET= $(SLB)$/$(SHL1TARGET).lib +LIB1OBJFILES=$(SHL1OBJS) + +SHL1STDLIBS= \ + $(I18NISOLANGLIB) \ + $(COMPHELPERLIB) \ + $(CPPULIB) \ + $(SALLIB) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +$(MISC)$/$(SHL1TARGET).flt: makefile.mk + @echo ------------------------------ + @echo Making: $@ + @echo CLEAR_THE_FILE > $@ + @echo __CT >> $@ diff --git a/i18npool/source/paper/paper.cxx b/i18npool/source/paper/paper.cxx new file mode 100644 index 000000000000..726a4c3bd898 --- /dev/null +++ b/i18npool/source/paper/paper.cxx @@ -0,0 +1,478 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile$ + * $Revision$ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_i18npool.hxx" +#include <sal/config.h> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/i18n/ScriptType.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> + +#include "i18npool/mslangid.hxx" +#include "i18npool/paper.hxx" + +#include <utility> +#include <cstdlib> + +#ifdef UNX +#include <stdio.h> +#include <string.h> +#include <locale.h> +#include <langinfo.h> +#endif + +struct PageDesc +{ + long m_nWidth; + long m_nHeight; + const char *m_pPSName; + const char *m_pAltPSName; +}; + +#define PT2MM100( v ) \ + (long)(((v) * 35.27777778) + 0.5) + +#define IN2MM100( v ) \ + ((long)(((v) * 2540) + 0.5)) + +#define MM2MM100( v ) \ + ((long)((v) * 100)) + +//PostScript Printer Description File Format Specification +//http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf +//http://www.y-adagio.com/public/committees/docsii/doc_00-49/symp_ulaan/china_ppr.pdf (Kai) +//http://www.sls.psi.ch/controls/help/howto/Howto_Print_a_A0_Poster_at_WSLA_012_2.pdf (Dia) +static PageDesc aDinTab[] = +{ + { MM2MM100( 841 ), MM2MM100( 1189 ), "A0", NULL }, + { MM2MM100( 594 ), MM2MM100( 841 ), "A1", NULL }, + { MM2MM100( 420 ), MM2MM100( 594 ), "A2", NULL }, + { MM2MM100( 297 ), MM2MM100( 420 ), "A3", NULL }, + { MM2MM100( 210 ), MM2MM100( 297 ), "A4", NULL }, + { MM2MM100( 148 ), MM2MM100( 210 ), "A5", NULL }, + { MM2MM100( 250 ), MM2MM100( 353 ), "ISOB4", NULL }, + { MM2MM100( 176 ), MM2MM100( 250 ), "ISOB5", NULL }, + { IN2MM100( 8.5 ), IN2MM100( 11 ), "Letter", "Note" }, + { IN2MM100( 8.5 ), IN2MM100( 14 ), "Legal", NULL }, + { IN2MM100( 11 ), IN2MM100( 17 ), "Tabloid", "11x17" }, + { 0, 0, NULL, NULL }, //User + { MM2MM100( 125 ), MM2MM100( 176 ), "ISOB6", NULL }, + { MM2MM100( 229 ), MM2MM100( 324 ), "EnvC4", "C4" }, + { MM2MM100( 162 ), MM2MM100( 229 ), "EnvC5", "C5" }, + { MM2MM100( 114 ), MM2MM100( 162 ), "EnvC6", "C6" }, + { MM2MM100( 114 ), MM2MM100( 229 ), "EnvC65", NULL }, + { MM2MM100( 110 ), MM2MM100( 220 ), "EnvDL", "DL" }, + { MM2MM100( 180), MM2MM100( 270 ), NULL, NULL }, //Dia + { MM2MM100( 210), MM2MM100( 280 ), NULL, NULL }, //Screen + { IN2MM100( 17 ), IN2MM100( 22 ), "AnsiC", "CSheet" }, + { IN2MM100( 22 ), IN2MM100( 34 ), "AnsiD", "DSheet" }, + { IN2MM100( 34 ), IN2MM100( 44 ), "AnsiE", "ESheet" }, + { IN2MM100( 7.25 ), IN2MM100( 10.5 ), "Executive", NULL }, + //"Folio" is a different size in the PPD documentation than 8.5x11 + //This "FanFoldGermanLegal" is known in the Philippines as + //"Legal" paper or "Long Bond Paper". The "Legal" name causing untold + //misery, given the differently sized US "Legal" paper + { IN2MM100( 8.5 ), IN2MM100( 13 ), "FanFoldGermanLegal", NULL }, + { IN2MM100( 3.875 ), IN2MM100( 7.5 ), "EnvMonarch", "Monarch" }, + { IN2MM100( 3.625 ), IN2MM100( 6.5 ), "EnvPersonal", "Personal" }, + { IN2MM100( 3.875 ), IN2MM100( 8.875 ), "Env9", NULL }, + { IN2MM100( 4.125 ), IN2MM100( 9.5 ), "Env10", "Comm10" }, + { IN2MM100( 4.5 ), IN2MM100( 10.375 ), "Env11", NULL }, + { IN2MM100( 4.75 ), IN2MM100( 11 ), "Env12", NULL }, + { MM2MM100( 184 ), MM2MM100( 260 ), NULL, NULL }, //Kai16 + { MM2MM100( 130 ), MM2MM100( 184 ), NULL, NULL }, //Kai32 + { MM2MM100( 140 ), MM2MM100( 203 ), NULL, NULL }, //BigKai32 + { MM2MM100( 257 ), MM2MM100( 364 ), "B4", NULL }, //JIS + { MM2MM100( 182 ), MM2MM100( 257 ), "B5", NULL }, //JIS + { MM2MM100( 128 ), MM2MM100( 182 ), "B6", NULL }, //JIS + { IN2MM100( 17 ), IN2MM100( 11 ), "Ledger", NULL }, + { IN2MM100( 5.5 ), IN2MM100( 8.5 ), "Statement", NULL }, + { PT2MM100( 610 ), PT2MM100( 780 ), "Quarto", NULL }, + { IN2MM100( 10 ), IN2MM100( 14 ), "10x14", NULL }, + { IN2MM100( 5.5 ), IN2MM100( 11.5 ), "Env14", NULL }, + { MM2MM100( 324 ), MM2MM100( 458 ), "EnvC3", "C3" }, + { MM2MM100( 110 ), MM2MM100( 230 ), "EnvItalian", NULL }, + { IN2MM100( 14.875 ),IN2MM100( 11 ), "FanFoldUS", NULL }, + { IN2MM100( 8.5 ), IN2MM100( 13 ), "FanFoldGerman", NULL }, + { MM2MM100( 100 ), MM2MM100( 148 ), "Postcard", NULL }, + { IN2MM100( 9 ), IN2MM100( 11 ), "9x11", NULL }, + { IN2MM100( 10 ), IN2MM100( 11 ), "10x11", NULL }, + { IN2MM100( 15 ), IN2MM100( 11 ), "15x11", NULL }, + { MM2MM100( 220 ), MM2MM100( 220 ), "EnvInvite", NULL }, + { MM2MM100( 227 ), MM2MM100( 356 ), "SuperA", NULL }, + { MM2MM100( 305 ), MM2MM100( 487 ), "SuperB", NULL }, + { IN2MM100( 8.5 ), IN2MM100( 12.69 ), "LetterPlus", NULL }, + { IN2MM100( 8.5 ), IN2MM100( 12.69 ), "LetterPlus", NULL }, + { MM2MM100( 210 ), MM2MM100( 330 ), "A4Plus", NULL }, + { MM2MM100( 200 ), MM2MM100( 148 ), "DoublePostcard", NULL }, + { MM2MM100( 105 ), MM2MM100( 148 ), "A6", NULL }, + { IN2MM100( 12 ), IN2MM100( 11 ), "12x11", NULL }, + { MM2MM100( 74 ), MM2MM100( 105 ), "A7", NULL }, + { MM2MM100( 52 ), MM2MM100( 74 ), "A8", NULL }, + { MM2MM100( 37 ), MM2MM100( 52 ), "A9", NULL }, + { MM2MM100( 26 ), MM2MM100( 37 ), "A10", NULL }, + { MM2MM100( 1000 ), MM2MM100( 1414 ), "ISOB0", NULL }, + { MM2MM100( 707 ), MM2MM100( 1000 ), "ISOB1", NULL }, + { MM2MM100( 500 ), MM2MM100( 707 ), "ISOB2", NULL }, + { MM2MM100( 353 ), MM2MM100( 500 ), "ISOB3", NULL }, + { MM2MM100( 88 ), MM2MM100( 125 ), "ISOB7", NULL }, + { MM2MM100( 62 ), MM2MM100( 88 ), "ISOB8", NULL }, + { MM2MM100( 44 ), MM2MM100( 62 ), "ISOB9", NULL }, + { MM2MM100( 31 ), MM2MM100( 44 ), "ISOB10", NULL }, + { MM2MM100( 458 ), MM2MM100( 648 ), "EnvC2", "C2" }, + { MM2MM100( 81 ), MM2MM100( 114 ), "EnvC7", "C7" }, + { MM2MM100( 57 ), MM2MM100( 81 ), "EnvC8", "C8" }, + { IN2MM100( 9 ), IN2MM100( 12 ), "ARCHA", NULL }, + { IN2MM100( 12 ), IN2MM100( 18 ), "ARCHB", NULL }, + { IN2MM100( 18 ), IN2MM100( 24 ), "ARCHC", NULL }, + { IN2MM100( 24 ), IN2MM100( 36 ), "ARCHD", NULL }, + { IN2MM100( 36 ), IN2MM100( 48 ), "ARCHE", NULL } +}; + +static const size_t nTabSize = sizeof(aDinTab) / sizeof(aDinTab[0]); + +#define MAXSLOPPY 11 + +bool PaperInfo::doSloppyFit() +{ + if (m_eType != PAPER_USER) + return true; + + for ( size_t i = 0; i < nTabSize; ++i ) + { + if (i == PAPER_USER) continue; + + long lDiffW = labs(aDinTab[i].m_nWidth - m_nPaperWidth); + long lDiffH = labs(aDinTab[i].m_nHeight - m_nPaperHeight); + + if ( lDiffW < MAXSLOPPY && lDiffH < MAXSLOPPY ) + { + m_nPaperWidth = aDinTab[i].m_nWidth; + m_nPaperHeight = aDinTab[i].m_nHeight; + m_eType = (Paper)i; + return true; + } + } + + return false; +} + +bool PaperInfo::sloppyEqual(const PaperInfo &rOther) const +{ + return + ( + (labs(m_nPaperWidth - rOther.m_nPaperWidth) < MAXSLOPPY) && + (labs(m_nPaperHeight - rOther.m_nPaperHeight) < MAXSLOPPY) + ); +} + +long PaperInfo::sloppyFitPageDimension(long nDimension) +{ + for ( size_t i = 0; i < nTabSize; ++i ) + { + if (i == PAPER_USER) continue; + long lDiff; + + lDiff = labs(aDinTab[i].m_nWidth - nDimension); + if ( lDiff < MAXSLOPPY ) + return aDinTab[i].m_nWidth; + + lDiff = labs(aDinTab[i].m_nHeight - nDimension); + if ( lDiff < MAXSLOPPY ) + return aDinTab[i].m_nHeight; + } + return nDimension; +} + +PaperInfo PaperInfo::getSystemDefaultPaper() +{ + using ::com::sun::star::uno::Reference; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Any; + using ::com::sun::star::container::XNameAccess; + using ::com::sun::star::uno::Exception; +# define CREATE_OUSTRING( ascii ) \ + rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( ascii ) ) + + rtl::OUString aLocaleStr; + + Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory(); + Reference< XMultiServiceFactory > xConfigProv( + xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationProvider" ) ), + UNO_QUERY_THROW ); + + Sequence< Any > aArgs( 1 ); + aArgs[ 0 ] <<= CREATE_OUSTRING( "org.openoffice.Setup/L10N/" ); + Reference< XNameAccess > xConfigNA( xConfigProv->createInstanceWithArguments( + CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationAccess" ), aArgs ), UNO_QUERY_THROW ); + try + { + // try user-defined locale setting + xConfigNA->getByName( CREATE_OUSTRING( "ooSetupSystemLocale" ) ) >>= aLocaleStr; + } + catch( Exception& ) {} + +#ifdef UNX + // if set to "use system", get papersize from system + if (aLocaleStr.getLength() == 0) + { + static bool bInitialized = false; + static PaperInfo aInstance(PAPER_A4); + + if (bInitialized) + return aInstance; + + // try libpaper + // #i78617# workaround missing paperconf command + FILE* pPipe = popen( "sh -c paperconf 2>/dev/null", "r" ); + if( pPipe ) + { + Paper ePaper = PAPER_USER; + + char aBuffer[ 1024 ]; + aBuffer[0] = 0; + char *pBuffer = fgets( aBuffer, sizeof(aBuffer), pPipe ); + pclose( pPipe ); + + if (pBuffer && *pBuffer != 0) + { + rtl::OString aPaper(pBuffer); + aPaper = aPaper.trim(); + static struct { const char *pName; Paper ePaper; } aCustoms [] = + { + { "B0", PAPER_B0_ISO }, + { "B1", PAPER_B1_ISO }, + { "B2", PAPER_B2_ISO }, + { "B3", PAPER_B3_ISO }, + { "B4", PAPER_B4_ISO }, + { "B5", PAPER_B5_ISO }, + { "B6", PAPER_B6_ISO }, + { "B7", PAPER_B7_ISO }, + { "B8", PAPER_B8_ISO }, + { "B9", PAPER_B9_ISO }, + { "B10", PAPER_B10_ISO }, + { "folio", PAPER_FANFOLD_LEGAL_DE }, + { "flsa", PAPER_FANFOLD_LEGAL_DE }, + { "flse", PAPER_FANFOLD_LEGAL_DE } + }; + + bool bHalve = false; + + size_t nExtraTabSize = sizeof(aCustoms) / sizeof(aCustoms[0]); + for (size_t i = 0; i < nExtraTabSize; ++i) + { + if (rtl_str_compareIgnoreAsciiCase(aCustoms[i].pName, aPaper.getStr()) == 0) + { + ePaper = aCustoms[i].ePaper; + break; + } + } + + if (ePaper == PAPER_USER) + { + bHalve = !rtl_str_shortenedCompareIgnoreAsciiCase_WithLength( + aPaper.getStr(), aPaper.getLength(), "half", 4, 4); + if (bHalve) + aPaper = aPaper.copy(4); + ePaper = PaperInfo::fromPSName(aPaper); + } + + if (ePaper != PAPER_USER) + { + aInstance = PaperInfo(ePaper); + if (bHalve) + aInstance = PaperInfo(aInstance.getHeight()/2, aInstance.getWidth()); + bInitialized = true; + return aInstance; + } + } + } + +#if defined(LC_PAPER) && defined(_GNU_SOURCE) + + union paperword { char *string; int word; }; + + // try LC_PAPER + paperword w, h; + w.string = nl_langinfo(_NL_PAPER_WIDTH); + h.string = nl_langinfo(_NL_PAPER_HEIGHT); + + //glibc stores sizes as integer mm units + w.word *= 100; + h.word *= 100; + + for ( size_t i = 0; i < nTabSize; ++i ) + { + if (i == PAPER_USER) continue; + + //glibc stores sizes as integer mm units, and so is inaccurate. To + //find a standard paper size we calculate the standard paper sizes + //into equally inaccurate mm and compare + long width = (aDinTab[i].m_nWidth + 50) / 100; + long height = (aDinTab[i].m_nHeight + 50) / 100; + + if (width == w.word/100 && height == h.word/100) + { + w.word = aDinTab[i].m_nWidth; + h.word = aDinTab[i].m_nHeight; + break; + } + } + + aInstance = PaperInfo(w.word, h.word); + bInitialized = true; + return aInstance; +#endif + } +#endif + + try + { + // if set to "use system", try to get locale from system + if( aLocaleStr.getLength() == 0 ) + { + aArgs[ 0 ] <<= CREATE_OUSTRING( "org.openoffice.System/L10N/" ); + xConfigNA.set( xConfigProv->createInstanceWithArguments( + CREATE_OUSTRING( "com.sun.star.configuration.ConfigurationAccess" ), aArgs ), + UNO_QUERY_THROW ); + xConfigNA->getByName( CREATE_OUSTRING( "Locale" ) ) >>= aLocaleStr; + } + } + catch( Exception& ) {} + + if (aLocaleStr.getLength() == 0) + aLocaleStr = CREATE_OUSTRING("en-US"); + + // convert locale string to locale struct + ::com::sun::star::lang::Locale aSysLocale; + sal_Int32 nDashPos = aLocaleStr.indexOf( '-' ); + if( nDashPos < 0 ) nDashPos = aLocaleStr.getLength(); + aSysLocale.Language = aLocaleStr.copy( 0, nDashPos ); + if( nDashPos + 1 < aLocaleStr.getLength() ) + aSysLocale.Country = aLocaleStr.copy( nDashPos + 1 ); + + return PaperInfo::getDefaultPaperForLocale(aSysLocale); +} + +PaperInfo::PaperInfo(Paper eType) : m_eType(eType) +{ + m_nPaperWidth = aDinTab[m_eType].m_nWidth; + m_nPaperHeight = aDinTab[m_eType].m_nHeight; +} + +PaperInfo::PaperInfo(long nPaperWidth, long nPaperHeight) + : m_eType(PAPER_USER), + m_nPaperWidth(nPaperWidth), + m_nPaperHeight(nPaperHeight) +{ + for ( size_t i = 0; i < nTabSize; ++i ) + { + if ( + (nPaperWidth == aDinTab[i].m_nWidth) && + (nPaperHeight == aDinTab[i].m_nHeight) + ) + { + m_eType = static_cast<Paper>(i); + break; + } + } +} + +rtl::OString PaperInfo::toPSName(Paper ePaper) +{ + return static_cast<size_t>(ePaper) < nTabSize ? + rtl::OString(aDinTab[ePaper].m_pPSName) : rtl::OString(); +} + +Paper PaperInfo::fromPSName(const rtl::OString &rName) +{ + if (!rName.getLength()) + return PAPER_USER; + + for ( size_t i = 0; i < nTabSize; ++i ) + { + if (aDinTab[i].m_pPSName && + !rtl_str_compareIgnoreAsciiCase(aDinTab[i].m_pPSName, rName.getStr())) + { + return static_cast<Paper>(i); + } + else if (aDinTab[i].m_pAltPSName && + !rtl_str_compareIgnoreAsciiCase(aDinTab[i].m_pAltPSName, rName.getStr())) + { + return static_cast<Paper>(i); + } + } + + return PAPER_USER; +} + +//http://wiki.services.openoffice.org/wiki/DefaultPaperSize +//http://sources.redhat.com/cgi-bin/cvsweb.cgi/libc/localedata/locales/?cvsroot=glibc +//http://www.unicode.org/cldr/data/charts/supplemental/territory_language_information.html +//http://en.wikipedia.org/wiki/Paper_size +//http://msdn.microsoft.com/en-us/library/cc195164.aspx +PaperInfo PaperInfo::getDefaultPaperForLocale( + const ::com::sun::star::lang::Locale & rLocale) +{ + Paper eType = PAPER_A4; + + if ( + //United States, Letter + !rLocale.Country.compareToAscii("US") || + //Puerto Rico, http://sources.redhat.com/ml/libc-hacker/2001-07/msg00046.html + !rLocale.Country.compareToAscii("PR") || + //Canada, http://sources.redhat.com/ml/libc-hacker/2001-07/msg00053.html + !rLocale.Country.compareToAscii("CA") || + //Venuzuela, https://www.redhat.com/archives/fedora-devel-list/2008-August/msg00019.html + !rLocale.Country.compareToAscii("VE") || + //Chile, https://www.redhat.com/archives/fedora-devel-list/2008-August/msg00240.html + !rLocale.Country.compareToAscii("CL") || + //Mexico, http://qa.openoffice.org/issues/show_bug.cgi?id=49739 + !rLocale.Country.compareToAscii("MX") || + //Colombia, http://qa.openoffice.org/issues/show_bug.cgi?id=69703 + !rLocale.Country.compareToAscii("CO") || + //Philippines, + // http://ubuntuliving.blogspot.com/2008/07/default-paper-size-in-evince.html + // http://www.gov.ph/faqs/driverslicense.asp + !rLocale.Country.compareToAscii("PH") + ) + { + eType = PAPER_LETTER; + } + + return eType; +} + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/o3tl/qa/makefile.mk b/o3tl/qa/makefile.mk index 563f4e2d3bf2..a6ebfbba4bb9 100644 --- a/o3tl/qa/makefile.mk +++ b/o3tl/qa/makefile.mk @@ -75,6 +75,6 @@ unittest : $(SHL1TARGETN) @echo ---------------------------------------------------------- @echo - start unit test on library $(SHL1TARGETN) @echo ---------------------------------------------------------- - $(AUGMENT_LIBRARY_PATH) testshl2 -sf $(mktmp ) $(SHL1TARGETN) + $(TESTSHL2) -sf $(mktmp ) $(SHL1TARGETN) ALLTAR : unittest diff --git a/rsc/source/prj/start.cxx b/rsc/source/prj/start.cxx index 5a623efeee51..c43879020a8e 100644 --- a/rsc/source/prj/start.cxx +++ b/rsc/source/prj/start.cxx @@ -306,8 +306,10 @@ int cdecl main ( int argc, char ** argv) BOOL bHelp = FALSE; BOOL bError = FALSE; BOOL bResponse = FALSE; - ByteString aPrePro( "rscpp" ); - ByteString aRsc2Name( "rsc2" ); + ByteString aSolarbin(getenv("SOLARBINDIR")); + ByteString aDelim("/"); + ByteString aPrePro; //( aSolarbin + aDelim + ByteString("rscpp")); + ByteString aRsc2Name; //( aSolarbin + aDelim + ByteString("rsc2")); ByteString aSrsName; ByteString aResName; RscStrList aInputList; @@ -318,6 +320,14 @@ int cdecl main ( int argc, char ** argv) sal_uInt32 i; ByteString* pString; + aPrePro = aSolarbin; + aPrePro += aDelim; + aPrePro += ByteString("rscpp"); + + aRsc2Name = aSolarbin; + aRsc2Name += aDelim; + aRsc2Name += ByteString("rsc2"); + printf( "VCL Resource Compiler 3.0\n" ); pStr = ::ResponseFile( &aCmdLine, argv, argc ); diff --git a/sot/inc/sot/exchange.hxx b/sot/inc/sot/exchange.hxx index 68862367e4f0..0c235fffcdbb 100644 --- a/sot/inc/sot/exchange.hxx +++ b/sot/inc/sot/exchange.hxx @@ -196,10 +196,7 @@ public: static ULONG RegisterFormatMimeType( const String& rMimeType ); static ULONG GetFormat( const ::com::sun::star::datatransfer::DataFlavor& rFlavor ); - static ULONG GetStaticNameFormat( const String& rName ); - static String GetFormatName( ULONG nFormat ); - static String GetFormatStaticName( ULONG nFormat ); static sal_Bool GetFormatDataFlavor( ULONG nFormat, ::com::sun::star::datatransfer::DataFlavor& rFlavor ); static String GetFormatMimeType( ULONG nFormat ); static BOOL IsInternal( const SvGlobalName& ); @@ -216,14 +213,6 @@ public: static ULONG RegisterSotFormatName( SotFormatStringId nId ) { return nId; } - // Anzahl der bereits registrierten Formate bzw. der hoechsten - // registrierten ID abfragen (fuer System-Registrierung) - // ACHTUNG: Die Algorithmen zur Registrierung beim System - // verlassen sich darauf, dass die hier gelieferte maximale - // Format-ID 'klein' ist, so dass eine Schleife ueber alle - // Formate laufen kann. - static ULONG GetMaxFormat( void ); - // same for XTransferable interface static USHORT GetExchangeAction( // XTransferable diff --git a/sot/source/base/exchange.cxx b/sot/source/base/exchange.cxx index 05de84bdfd46..6dedd84cdaeb 100644 --- a/sot/source/base/exchange.cxx +++ b/sot/source/base/exchange.cxx @@ -481,18 +481,6 @@ ULONG SotExchange::GetFormat( const DataFlavor& rFlavor ) /************************************************************************* |* -|* SotExchange::GetStaticNameFormat() -|* -|* Beschreibung CLIP.SDW -*************************************************************************/ -ULONG SotExchange::GetStaticNameFormat( const String& rName ) -{ - // has to be changed to return the format for the static name (KA 27.09.2001) - return SotExchange::RegisterFormatName( rName ); -} - -/************************************************************************* -|* |* SotExchange::GetFormatName() |* |* Beschreibung CLIP.SDW @@ -508,28 +496,6 @@ String SotExchange::GetFormatName( ULONG nFormat ) return aRet; } -/************************************************************************* -|* -|* SotExchange::GetFormatStaticName() -|* -|* Beschreibung CLIP.SDW -*************************************************************************/ -String SotExchange::GetFormatStaticName( ULONG nFormat ) -{ - // has to be changed to return the static format name (KA 27.09.2001) - return SotExchange::GetFormatName( nFormat ); -} - -/************************************************************************* -|* -|* SotExchange::GetMaxFormat() -|* -*************************************************************************/ -ULONG SotExchange::GetMaxFormat( void ) -{ - return( SOT_FORMATSTR_ID_USER_END + InitFormats_Impl().Count() ); -} - BOOL SotExchange::IsInternal( const SvGlobalName& rName ) { if ( rName == SvGlobalName(SO3_SW_CLASSID_60) || diff --git a/svtools/inc/docmspasswdrequest.hxx b/svtools/inc/docmspasswdrequest.hxx new file mode 100644 index 000000000000..684bffe71760 --- /dev/null +++ b/svtools/inc/docmspasswdrequest.hxx @@ -0,0 +1,72 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: docmspasswdrequest.hxx,v $ + * $Revision: 1.0 $ + * + * 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. + * + ************************************************************************/ + +#ifndef INCLUDED_SVTOOLS_DOCMSPASSWDREQUEST_HXX +#define INCLUDED_SVTOOLS_DOCMSPASSWDREQUEST_HXX + +#include "svtools/svldllapi.h" +#include <com/sun/star/task/DocumentMSPasswordRequest.hpp> +#include <com/sun/star/task/XInteractionRequest.hpp> +#include <rtl/ustring.hxx> +#include <cppuhelper/implbase1.hxx> + +class MSAbortContinuation; +class MSPasswordContinuation; + +class SVL_DLLPUBLIC RequestMSDocumentPassword : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionRequest > +{ + ::com::sun::star::uno::Any m_aRequest; + + ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > + > m_lContinuations; + + MSAbortContinuation* m_pAbort; + MSPasswordContinuation* m_pPassword; + +public: + RequestMSDocumentPassword( ::com::sun::star::task::PasswordRequestMode nMode, ::rtl::OUString aName ); + + sal_Bool isAbort(); + sal_Bool isPassword(); + + ::rtl::OUString getPassword(); + + virtual ::com::sun::star::uno::Any SAL_CALL getRequest() + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< + ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > + > SAL_CALL getContinuations() + throw( ::com::sun::star::uno::RuntimeException ); +}; + +#endif /* INCLUDED_SVTOOLS_DOCMSPASSWDREQUEST_HXX */ diff --git a/svtools/inc/pch/precompiled_svtools.hxx b/svtools/inc/pch/precompiled_svtools.hxx index 440bd04dce36..cab81cac04ec 100644 --- a/svtools/inc/pch/precompiled_svtools.hxx +++ b/svtools/inc/pch/precompiled_svtools.hxx @@ -227,6 +227,7 @@ #include <com/sun/star/system/XProxySettings.hpp> #include <com/sun/star/system/XSystemShellExecute.hpp> #include <com/sun/star/task/DocumentPasswordRequest.hpp> +#include <com/sun/star/task/DocumentMSPasswordRequest.hpp> #include <com/sun/star/task/MasterPasswordRequest.hpp> #include <com/sun/star/task/NoMasterException.hpp> #include <com/sun/star/task/PasswordRequestMode.hpp> diff --git a/svtools/inc/sfxecode.hxx b/svtools/inc/sfxecode.hxx index 100336796ea4..01292f1c87fa 100644 --- a/svtools/inc/sfxecode.hxx +++ b/svtools/inc/sfxecode.hxx @@ -84,6 +84,7 @@ #define ERRCODE_SFX_MACROS_SUPPORT_DISABLED (ERRCODE_WARNING_MASK | ERRCODE_AREA_SFX | ERRCODE_CLASS_NONE | 51) #define ERRCODE_SFX_DOCUMENT_MACRO_DISABLED (ERRCODE_WARNING_MASK | ERRCODE_AREA_SFX | ERRCODE_CLASS_NONE | 52) #define ERRCODE_SFX_BROKENSIGNATURE (ERRCODE_WARNING_MASK | ERRCODE_AREA_SFX | ERRCODE_CLASS_NONE | 53) +#define ERRCODE_SFX_SHARED_NOPASSWORDCHANGE (ERRCODE_WARNING_MASK | ERRCODE_AREA_SFX | ERRCODE_CLASS_NONE | 54) diff --git a/svtools/inc/svtools/parhtml.hxx b/svtools/inc/svtools/parhtml.hxx index d129a8c14595..f5de6aea358d 100644 --- a/svtools/inc/svtools/parhtml.hxx +++ b/svtools/inc/svtools/parhtml.hxx @@ -37,9 +37,17 @@ #include <svtools/svarray.hxx> #include <svtools/svparser.hxx> + +namespace com { namespace sun { namespace star { + namespace document { + class XDocumentProperties; + } +} } } + class Color; class SvNumberFormatter; class SvULongs; +class SvKeyValueIterator; #define HTMLFONTSZ1_DFLT 7 #define HTMLFONTSZ2_DFLT 10 @@ -224,6 +232,28 @@ public: // virtual void RestoreState(); virtual void Continue( int nToken ); + +protected: + + static rtl_TextEncoding GetEncodingByMIME( const String& rMime ); + + /// template method: called when ParseMetaOptions adds a user-defined meta + virtual void AddMetaUserDefined( ::rtl::OUString const & i_rMetaName ); + +private: + /// parse meta options into XDocumentProperties and encoding + bool ParseMetaOptionsImpl( const ::com::sun::star::uno::Reference< + ::com::sun::star::document::XDocumentProperties>&, + SvKeyValueIterator*, + const HTMLOptions*, + rtl_TextEncoding& rEnc ); + +public: + /// overriding method must call this implementation! + virtual bool ParseMetaOptions( const ::com::sun::star::uno::Reference< + ::com::sun::star::document::XDocumentProperties>&, + SvKeyValueIterator* ); + // Ist der uebergebene 0-terminierte String (vermutlich) der Anfang // eines HTML-Files? Er sollte mind. 80 Zeichen lang sein. // Mit Ausnahme des Falls, dass SwitchToUCS2==FALSE und diff --git a/svtools/inc/svtools/svlbox.hxx b/svtools/inc/svtools/svlbox.hxx index ba119263eff8..7371c2feee05 100644 --- a/svtools/inc/svtools/svlbox.hxx +++ b/svtools/inc/svtools/svlbox.hxx @@ -328,6 +328,9 @@ protected: // wird an der Target-View aufgerufen (im Drop-Handler) virtual void ReadDragServerInfo( const Point&,SvLBoxDDInfo* ); + // invalidate children on enable/disable + virtual void StateChanged( StateChangedType ); + virtual ULONG Insert( SvLBoxEntry* pEnt,SvLBoxEntry* pPar,ULONG nPos=LIST_APPEND); virtual ULONG Insert( SvLBoxEntry* pEntry,ULONG nRootPos = LIST_APPEND ); void InsertTree( SvLBoxEntry* pTree, SvLBoxEntry* pTarget) {pModel->InsertTree( pTree, pTarget ); } diff --git a/svtools/inc/svtools/svparser.hxx b/svtools/inc/svtools/svparser.hxx index d63777d05b1b..96c1aadc6319 100644 --- a/svtools/inc/svtools/svparser.hxx +++ b/svtools/inc/svtools/svparser.hxx @@ -37,6 +37,7 @@ #include <tools/string.hxx> #include <tools/ref.hxx> #include <rtl/textenc.h> +#include <boost/utility.hpp> struct SvParser_Impl; @@ -204,6 +205,84 @@ inline USHORT SvParser::GetCharSize() const { return (RTL_TEXTENCODING_UCS2 == eSrcEnc) ? 2 : 1; } + + +/*======================================================================== + * + * SvKeyValue. + * + *======================================================================*/ + +SV_DECL_REF(SvKeyValueIterator) + +class SvKeyValue +{ + /** Representation. + */ + String m_aKey; + String m_aValue; + +public: + /** Construction. + */ + SvKeyValue (void) + {} + + SvKeyValue (const String &rKey, const String &rValue) + : m_aKey (rKey), m_aValue (rValue) + {} + + SvKeyValue (const SvKeyValue &rOther) + : m_aKey (rOther.m_aKey), m_aValue (rOther.m_aValue) + {} + + /** Assignment. + */ + SvKeyValue& operator= (SvKeyValue &rOther) + { + m_aKey = rOther.m_aKey; + m_aValue = rOther.m_aValue; + return *this; + } + + /** Operation. + */ + const String& GetKey (void) const { return m_aKey; } + const String& GetValue (void) const { return m_aValue; } + + void SetKey (const String &rKey ) { m_aKey = rKey; } + void SetValue (const String &rValue) { m_aValue = rValue; } +}; + +/*======================================================================== + * + * SvKeyValueIterator. + * + *======================================================================*/ +class SvKeyValueList_Impl; +class SVT_DLLPUBLIC SvKeyValueIterator : public SvRefBase, + private boost::noncopyable +{ + /** Representation. + */ + SvKeyValueList_Impl* m_pList; + USHORT m_nPos; + +public: + /** Construction/Destruction. + */ + SvKeyValueIterator (void); + virtual ~SvKeyValueIterator (void); + + /** Operation. + */ + virtual BOOL GetFirst (SvKeyValue &rKeyVal); + virtual BOOL GetNext (SvKeyValue &rKeyVal); + virtual void Append (const SvKeyValue &rKeyVal); +}; + +SV_IMPL_REF(SvKeyValueIterator); + #endif //_SVPARSER_HXX /* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/svtools/prj/build.lst b/svtools/prj/build.lst index ee2414e0da59..a6a409055faa 100644 --- a/svtools/prj/build.lst +++ b/svtools/prj/build.lst @@ -1,4 +1,4 @@ -st svtools : offuh toolkit ucbhelper unotools JPEG:jpeg cppu cppuhelper comphelper sal sot jvmfwk NULL +st svtools : l10n offuh toolkit ucbhelper unotools JPEG:jpeg cppu cppuhelper comphelper sal sot jvmfwk NULL st svtools usr1 - all st_mkout NULL st svtools\inc nmake - all st_inc NULL st svtools\inc\sane get - all st_incsa NULL diff --git a/svtools/prj/d.lst b/svtools/prj/d.lst index 6b85194db6c1..4ff74419b9d4 100644 --- a/svtools/prj/d.lst +++ b/svtools/prj/d.lst @@ -312,6 +312,7 @@ mkdir: %_DEST%\inc%_EXT%\svtools ..\inc\textwindowaccessibility.hxx %_DEST%\inc%_EXT%\svtools\textwindowaccessibility.hxx ..\inc\docpasswdrequest.hxx %_DEST%\inc%_EXT%\svtools\docpasswdrequest.hxx +..\inc\docmspasswdrequest.hxx %_DEST%\inc%_EXT%\svtools\docmspasswdrequest.hxx ..\inc\fontsubstconfig.hxx %_DEST%\inc%_EXT%\svtools\fontsubstconfig.hxx ..\inc\apearcfg.hxx %_DEST%\inc%_EXT%\svtools\apearcfg.hxx ..\inc\fltrcfg.hxx %_DEST%\inc%_EXT%\svtools\fltrcfg.hxx diff --git a/svtools/source/config/useroptions.cxx b/svtools/source/config/useroptions.cxx index aad000a235f1..4eafbefe54a3 100644 --- a/svtools/source/config/useroptions.cxx +++ b/svtools/source/config/useroptions.cxx @@ -49,51 +49,45 @@ #include <rtl/logfile.hxx> #include "itemholder2.hxx" -#ifndef _COM_SUN_STAR_BEANS_PROPERTY_HPP_ #include <com/sun/star/beans/Property.hpp> -#endif - -#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ #include <com/sun/star/beans/XPropertySet.hpp> -#endif - -#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ #include <com/sun/star/beans/PropertyAttribute.hpp> -#endif - -#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ #include <com/sun/star/container/XNameAccess.hpp> -#endif - -#ifndef _COM_SUN_STAR_CONTAINER_XNAMECONTAINER_HPP_ #include <com/sun/star/container/XNameContainer.hpp> -#endif - -#ifndef _COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_ #include <com/sun/star/lang/XSingleServiceFactory.hpp> -#endif - -#ifndef _COMPHELPER_CONFIGURATIONHELPER_HXX_ +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/util/ChangesEvent.hpp> #include <comphelper/configurationhelper.hxx> -#endif - -#ifndef _UNOTOOLS_PROCESSFACTORY_HXX_ #include <unotools/processfactory.hxx> -#endif - -#ifndef _SVT_LOGHELPER_HXX -#include "loghelper.hxx" -#endif +#include <loghelper.hxx> using namespace utl; using namespace rtl; +using namespace com::sun::star; using namespace com::sun::star::uno; namespace css = ::com::sun::star; // class SvtUserOptions_Impl --------------------------------------------- +class SvtUserOptions_Impl; +class SvtUserConfigChangeListener_Impl : public cppu::WeakImplHelper1 +< + com::sun::star::util::XChangesListener +> +{ + SvtUserOptions_Impl& m_rParent; + public: + SvtUserConfigChangeListener_Impl(SvtUserOptions_Impl& rParent); + ~SvtUserConfigChangeListener_Impl(); + + //XChangesListener + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& Event ) throw(RuntimeException); + //XEventListener + virtual void SAL_CALL disposing( const lang::EventObject& Source ) throw(RuntimeException); +}; -class SvtUserOptions_Impl +class SvtUserOptions_Impl : public SfxBroadcaster { public: SvtUserOptions_Impl(); @@ -144,8 +138,10 @@ public: sal_Bool IsTokenReadonly( USHORT nToken ) const; ::rtl::OUString GetToken(USHORT nToken) const; + void Notify(); private: + uno::Reference< util::XChangesListener > m_xChangeListener; css::uno::Reference< css::container::XNameAccess > m_xCfg; css::uno::Reference< css::beans::XPropertySet > m_xData; ::rtl::OUString m_aLocale; @@ -158,18 +154,47 @@ static sal_Int32 nRefCount = 0; #define READONLY_DEFAULT sal_False -// functions ------------------------------------------------------------- +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtUserConfigChangeListener_Impl::SvtUserConfigChangeListener_Impl(SvtUserOptions_Impl& rParent) : + m_rParent( rParent ) +{ +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SvtUserConfigChangeListener_Impl::~SvtUserConfigChangeListener_Impl() +{ +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SvtUserConfigChangeListener_Impl::changesOccurred( const util::ChangesEvent& rEvent ) throw(RuntimeException) +{ + if(rEvent.Changes.getLength()) + m_rParent.Notify(); +} +/*-- 16.06.2009 14:22:56--------------------------------------------------- -namespace + -----------------------------------------------------------------------*/ +void SvtUserConfigChangeListener_Impl::disposing( const lang::EventObject& rSource ) throw(RuntimeException) { - struct PropertyNames - : public rtl::Static< Sequence< rtl::OUString >, PropertyNames> {}; + try + { + uno::Reference< util::XChangesNotifier > xChgNot( rSource.Source, UNO_QUERY_THROW); + xChgNot->removeChangesListener(this); + } + catch(Exception& ) + { + } } // class SvtUserOptions_Impl --------------------------------------------- // ----------------------------------------------------------------------- -SvtUserOptions_Impl::SvtUserOptions_Impl() +SvtUserOptions_Impl::SvtUserOptions_Impl() : + m_xChangeListener( new SvtUserConfigChangeListener_Impl(*this) ) { try { @@ -181,6 +206,14 @@ SvtUserOptions_Impl::SvtUserOptions_Impl() css::uno::UNO_QUERY ); m_xData = css::uno::Reference< css::beans::XPropertySet >(m_xCfg, css::uno::UNO_QUERY); + uno::Reference< util::XChangesNotifier > xChgNot( m_xCfg, UNO_QUERY); + try + { + xChgNot->addChangesListener( m_xChangeListener ); + } + catch(RuntimeException& ) + { + } } catch(const css::uno::Exception& ex) { @@ -743,6 +776,12 @@ void SvtUserOptions_Impl::SetApartment( const ::rtl::OUString& sApartment ) // ----------------------------------------------------------------------- +void SvtUserOptions_Impl::Notify() +{ + Broadcast( SfxSimpleHint( SFX_HINT_USER_OPTIONS_CHANGED ) ); +} +// ----------------------------------------------------------------------- + sal_Bool SvtUserOptions_Impl::IsTokenReadonly( USHORT nToken ) const { css::uno::Reference< css::beans::XPropertySet > xData(m_xCfg, css::uno::UNO_QUERY); @@ -906,7 +945,7 @@ SvtUserOptions::SvtUserOptions() } ++nRefCount; pImp = pOptions; - //StartListening( *pImp); + StartListening( *pImp); } // ----------------------------------------------------------------------- diff --git a/svtools/source/contnr/fileview.cxx b/svtools/source/contnr/fileview.cxx index d56c270fd5a8..274557051c27 100644 --- a/svtools/source/contnr/fileview.cxx +++ b/svtools/source/contnr/fileview.cxx @@ -1065,7 +1065,10 @@ BOOL ViewTabListBox_Impl::DoubleClickHdl() ::rtl::OUString sRet = SvHeaderTabListBox::GetAccessibleObjectDescription( _eType, _nPos ); if ( ::svt::BBTYPE_TABLECELL == _eType ) { - sal_Int32 nRow = _nPos / GetColumnCount(); + sal_Int32 nRow = -1; + const sal_uInt16 nColumnCount = GetColumnCount(); + if (nColumnCount > 0) + nRow = _nPos / nColumnCount; SvLBoxEntry* pEntry = GetEntry( nRow ); if ( pEntry ) { diff --git a/svtools/source/contnr/svlbox.cxx b/svtools/source/contnr/svlbox.cxx index 1c81343cd84f..e56db398b8fb 100644 --- a/svtools/source/contnr/svlbox.cxx +++ b/svtools/source/contnr/svlbox.cxx @@ -1203,6 +1203,12 @@ void SvLBox::ViewDataInitialized( SvLBoxEntry* ) DBG_CHKTHIS(SvLBox,0); } +void SvLBox::StateChanged( StateChangedType eType ) +{ + if( eType == STATE_CHANGE_ENABLE ) + Invalidate( INVALIDATE_CHILDREN ); + Control::StateChanged( eType ); +} void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry* pEntry, BOOL bShow) { diff --git a/svtools/source/contnr/svtabbx.cxx b/svtools/source/contnr/svtabbx.cxx index 32e8e68facb1..fc02c85dfd25 100644 --- a/svtools/source/contnr/svtabbx.cxx +++ b/svtools/source/contnr/svtabbx.cxx @@ -980,10 +980,12 @@ Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleCell( sal_Int32 _nR if ( !AreChildrenTransient() ) { + const sal_uInt16 nColumnCount = GetColumnCount(); + // first call? -> initial list if ( m_aAccessibleChildren.empty() ) { - sal_Int32 nCount = ( GetRowCount() + 1 ) * GetColumnCount(); + sal_Int32 nCount = ( GetRowCount() + 1 ) * nColumnCount; m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() ); } @@ -1021,8 +1023,9 @@ Reference< XAccessible > SvHeaderTabListBox::CreateAccessibleColumnHeader( sal_u // first call? -> initial list if ( m_aAccessibleChildren.empty() ) { - sal_Int32 nCount = AreChildrenTransient() ? GetColumnCount() - : ( GetRowCount() + 1 ) * GetColumnCount(); + const sal_uInt16 nColumnCount = GetColumnCount(); + sal_Int32 nCount = AreChildrenTransient() ? + nColumnCount : ( GetRowCount() + 1 ) * nColumnCount; m_aAccessibleChildren.assign( nCount, Reference< XAccessible >() ); } @@ -1098,9 +1101,12 @@ sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Poin if ( _nPos >= 0 ) { sal_uInt16 nColumnCount = GetColumnCount(); - sal_Int32 nRow = _nPos / nColumnCount; - sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); - aRetText = GetCellText( nRow, nColumn ); + if (nColumnCount > 0) + { + sal_Int32 nRow = _nPos / nColumnCount; + sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); + aRetText = GetCellText( nRow, nColumn ); + } } break; } @@ -1135,16 +1141,19 @@ sal_Bool SvHeaderTabListBox::ConvertPointToColumnHeader( sal_uInt16&, const Poin static const String sVar2( RTL_CONSTASCII_USTRINGPARAM( "%2" ) ); sal_uInt16 nColumnCount = GetColumnCount(); - sal_Int32 nRow = _nPos / nColumnCount; - sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); - - String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) ); - aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) ); - String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) ); - if ( sColHeader.Len() == 0 ) - sColHeader = String::CreateFromInt32( nColumn ); - aText.SearchAndReplace( sVar2, sColHeader ); - aRetText = aText; + if (nColumnCount > 0) + { + sal_Int32 nRow = _nPos / nColumnCount; + sal_uInt16 nColumn = static_cast< sal_uInt16 >( _nPos % nColumnCount ); + + String aText( SvtResId( STR_SVT_ACC_DESC_TABLISTBOX ) ); + aText.SearchAndReplace( sVar1, String::CreateFromInt32( nRow ) ); + String sColHeader = m_pImpl->m_pHeaderBar->GetItemText( m_pImpl->m_pHeaderBar->GetItemId( nColumn ) ); + if ( sColHeader.Len() == 0 ) + sColHeader = String::CreateFromInt32( nColumn ); + aText.SearchAndReplace( sVar2, sColHeader ); + aRetText = aText; + } } return aRetText; diff --git a/svtools/source/control/ctrltool.cxx b/svtools/source/control/ctrltool.cxx index 35e86189c352..77bb996584bd 100644 --- a/svtools/source/control/ctrltool.cxx +++ b/svtools/source/control/ctrltool.cxx @@ -161,7 +161,11 @@ static void ImplMakeSearchString( XubString& rStr ) static void ImplMakeSearchStringFromName( XubString& rStr ) { - rStr = rStr.GetToken( 0, ';' ); + // check for features before alternate font separator + if (rStr.Search(':') < rStr.Search(';')) + rStr = rStr.GetToken( 0, ':' ); + else + rStr = rStr.GetToken( 0, ';' ); ImplMakeSearchString( rStr ); } diff --git a/svtools/source/control/scrwin.cxx b/svtools/source/control/scrwin.cxx index 9805110c9254..162f23948385 100644 --- a/svtools/source/control/scrwin.cxx +++ b/svtools/source/control/scrwin.cxx @@ -273,8 +273,8 @@ void __EXPORT ScrollableWindow::Resize() // disable painting in the corner between the scrollbars if ( bVVisible && bHVisible ) { - aCornerWin.SetPosSizePixel( - *((Point*) &aOutPixSz), Size(nScrSize, nScrSize) ); + aCornerWin.SetPosSizePixel(Point(aOutPixSz.Width(), aOutPixSz.Height()), + Size(nScrSize, nScrSize) ); aCornerWin.Show(); } else diff --git a/svtools/source/items1/itemset.cxx b/svtools/source/items1/itemset.cxx index 48fe2877b892..6edeffe6d250 100644 --- a/svtools/source/items1/itemset.cxx +++ b/svtools/source/items1/itemset.cxx @@ -541,7 +541,7 @@ SfxItemState SfxItemSet::GetItemState( USHORT nWhich, // Unterschiedlich vorhanden return SFX_ITEM_DONTCARE; - if ( (*ppFnd)->IsA(TYPE(SfxVoidItem)) ) + if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) )
return SFX_ITEM_DISABLED; if (ppItem) diff --git a/svtools/source/misc/acceleratorexecute.cxx b/svtools/source/misc/acceleratorexecute.cxx index 3e2d63e0b622..16bc8339a0d9 100644 --- a/svtools/source/misc/acceleratorexecute.cxx +++ b/svtools/source/misc/acceleratorexecute.cxx @@ -476,8 +476,14 @@ css::uno::Reference< css::ui::XAcceleratorConfiguration > AcceleratorExecute::st xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.ui.ModuleUIConfigurationManagerSupplier")), css::uno::UNO_QUERY_THROW); - css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule); - css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg (xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); + css::uno::Reference< css::ui::XAcceleratorConfiguration > xAccCfg; + try + { + css::uno::Reference< css::ui::XUIConfigurationManager > xUIManager = xUISupplier->getUIConfigurationManager(sModule); + xAccCfg = css::uno::Reference< css::ui::XAcceleratorConfiguration >(xUIManager->getShortCutManager(), css::uno::UNO_QUERY_THROW); + } + catch(const css::container::NoSuchElementException&) + {} return xAccCfg; } diff --git a/svtools/source/misc/documentlockfile.cxx b/svtools/source/misc/documentlockfile.cxx index 71b541cfe894..990f1ba58d73 100644 --- a/svtools/source/misc/documentlockfile.cxx +++ b/svtools/source/misc/documentlockfile.cxx @@ -202,7 +202,7 @@ sal_Bool DocumentLockFile::OverwriteOwnLockFile() WriteEntryToStream( aNewEntry, xOutput ); xOutput->closeOutput(); } - catch( ucb::NameClashException& ) + catch( uno::Exception& ) { return sal_False; } diff --git a/svtools/source/misc/errtxt.src b/svtools/source/misc/errtxt.src index 72b575f96f43..033ecefc10e7 100644 --- a/svtools/source/misc/errtxt.src +++ b/svtools/source/misc/errtxt.src @@ -503,6 +503,10 @@ Resource RID_ERRHDL { Text [ en-US ] = "Function not possible: write protected." ; }; + String ERRCODE_SFX_SHARED_NOPASSWORDCHANGE + { + Text [ en-US ] = "The password of a shared spreadsheet cannot be set or changed.\nDeactivate sharing mode first."; + }; }; // eof ------------------------------------------------------------------------ diff --git a/svtools/source/misc1/adrparse.cxx b/svtools/source/misc1/adrparse.cxx index d9b389513f80..37c25d6c669f 100644 --- a/svtools/source/misc1/adrparse.cxx +++ b/svtools/source/misc1/adrparse.cxx @@ -172,8 +172,8 @@ inline void SvAddressParser_Impl::addTokenToRealName() if (!m_pRealNameBegin) m_pRealNameBegin = m_pRealNameContentBegin = m_pCurTokenBegin; else if (m_pRealNameEnd < m_pCurTokenBegin - 1 - || m_pRealNameEnd == m_pCurTokenBegin - 1 - && *m_pRealNameEnd != ' ') + || (m_pRealNameEnd == m_pCurTokenBegin - 1 + && *m_pRealNameEnd != ' ')) m_bRealNameReparse = true; m_pRealNameEnd = m_pRealNameContentEnd = m_pCurTokenEnd; } @@ -634,8 +634,8 @@ SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, else { m_pAddrSpec = m_aInnerAddrSpec.isValid() - || !m_aOuterAddrSpec.isValid() - && m_aInnerAddrSpec.isPoorlyValid() ? + || (!m_aOuterAddrSpec.isValid() + && m_aInnerAddrSpec.isPoorlyValid()) ? &m_aInnerAddrSpec : m_aOuterAddrSpec.isPoorlyValid() ? &m_aOuterAddrSpec : 0; @@ -663,11 +663,11 @@ SvAddressParser_Impl::SvAddressParser_Impl(SvAddressParser * pParser, } UniString aTheRealName; if (!m_pRealNameBegin - || m_pAddrSpec == &m_aOuterAddrSpec + || (m_pAddrSpec == &m_aOuterAddrSpec && m_pRealNameBegin == m_aOuterAddrSpec.m_pBegin && m_pRealNameEnd == m_aOuterAddrSpec.m_pEnd - && m_pFirstCommentBegin) + && m_pFirstCommentBegin)) if (!m_pFirstCommentBegin) aTheRealName = aTheAddrSpec; else if (m_bFirstCommentReparse) @@ -820,7 +820,7 @@ bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, return false; if (*p == '"') break; - if (*p == '\x0D' || *p == '\\' && ++p == pEnd + if (*p == '\x0D' || (*p == '\\' && ++p == pEnd) || !INetMIME::isUSASCII(*p)) return false; if (INetMIME::needsQuotedStringEscape(*p)) @@ -868,7 +868,7 @@ bool SvAddressParser::createRFC822Mailbox(String const & rPhrase, return false; if (*p == ']') break; - if (*p == '\x0D' || *p == '[' || *p == '\\' && ++p == pEnd + if (*p == '\x0D' || *p == '[' || (*p == '\\' && ++p == pEnd) || !INetMIME::isUSASCII(*p)) return false; if (*p >= '[' && *p <= ']') diff --git a/svtools/source/misc1/docmspasswdrequest.cxx b/svtools/source/misc1/docmspasswdrequest.cxx new file mode 100644 index 000000000000..e892d3a57d1a --- /dev/null +++ b/svtools/source/misc1/docmspasswdrequest.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright IBM Corporation 2009. + * Copyright 2009 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: docmspasswdrequest.cxx,v $ + * $Revision: 1.0 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "docmspasswdrequest.hxx" +#include <com/sun/star/task/XInteractionAbort.hpp> +#include <com/sun/star/task/XInteractionPassword.hpp> + +//========================================================================== + +class MSAbortContinuation : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionAbort > +{ + sal_Bool mbSelected; + +public: + MSAbortContinuation() : mbSelected( sal_False ) {} + + sal_Bool isSelected() { return mbSelected; } + + void reset() { mbSelected = sal_False; } + + virtual void SAL_CALL select() throw(::com::sun::star::uno::RuntimeException) { mbSelected = sal_True; } +}; + +//========================================================================== + +class MSPasswordContinuation : public ::cppu::WeakImplHelper1< ::com::sun::star::task::XInteractionPassword > +{ + sal_Bool mbSelected; + ::rtl::OUString maPassword; + +public: + MSPasswordContinuation() : mbSelected( sal_False ) {} + + sal_Bool isSelected() { return mbSelected; } + + void reset() { mbSelected = sal_False; } + + virtual void SAL_CALL select() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setPassword( const ::rtl::OUString& aPass ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getPassword( ) throw (::com::sun::star::uno::RuntimeException); +}; + +void SAL_CALL MSPasswordContinuation::select() + throw(::com::sun::star::uno::RuntimeException) +{ + mbSelected = sal_True; +} + +void SAL_CALL MSPasswordContinuation::setPassword( const ::rtl::OUString& aPass ) + throw (::com::sun::star::uno::RuntimeException) +{ + maPassword = aPass; +} + +::rtl::OUString SAL_CALL MSPasswordContinuation::getPassword() + throw (::com::sun::star::uno::RuntimeException) +{ + return maPassword; +} + +//========================================================================== + +RequestMSDocumentPassword::RequestMSDocumentPassword( ::com::sun::star::task::PasswordRequestMode nMode, ::rtl::OUString aName ) +{ + ::rtl::OUString temp; + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > temp2; + ::com::sun::star::task::DocumentMSPasswordRequest + aDocumentMSPasswordRequest( temp, + temp2, + ::com::sun::star::task::InteractionClassification_QUERY, + nMode, + aName ); + + m_aRequest <<= aDocumentMSPasswordRequest; + + m_pAbort = new MSAbortContinuation; + m_pPassword = new MSPasswordContinuation; + + m_lContinuations.realloc( 2 ); + m_lContinuations[0] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pAbort ); + m_lContinuations[1] = ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation >( m_pPassword ); +} + +sal_Bool RequestMSDocumentPassword::isAbort() +{ + return m_pAbort->isSelected(); +} + +sal_Bool RequestMSDocumentPassword::isPassword() +{ + return m_pPassword->isSelected(); +} + +::rtl::OUString RequestMSDocumentPassword::getPassword() +{ + return m_pPassword->getPassword(); +} + +::com::sun::star::uno::Any SAL_CALL RequestMSDocumentPassword::getRequest() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_aRequest; +} + +::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > + SAL_CALL RequestMSDocumentPassword::getContinuations() + throw( ::com::sun::star::uno::RuntimeException ) +{ + return m_lContinuations; +} + + diff --git a/svtools/source/misc1/makefile.mk b/svtools/source/misc1/makefile.mk index 0d1e67fd9021..3ca57ff36f92 100644 --- a/svtools/source/misc1/makefile.mk +++ b/svtools/source/misc1/makefile.mk @@ -50,6 +50,7 @@ SLOFILES=\ $(EXCEPTIONSFILES) \ $(SLO)$/adrparse.obj \ $(SLO)$/docpasswdrequest.obj \ + $(SLO)$/docmspasswdrequest.obj \ $(SLO)$/filenotation.obj \ $(SLO)$/inethist.obj \ $(SLO)$/inettype.obj \ diff --git a/svtools/source/svhtml/makefile.mk b/svtools/source/svhtml/makefile.mk index 577cc83e65c7..b597763ac390 100644 --- a/svtools/source/svhtml/makefile.mk +++ b/svtools/source/svhtml/makefile.mk @@ -34,6 +34,8 @@ PRJ=..$/.. PRJNAME=svtools TARGET=svhtml +ENABLE_EXCEPTIONS=TRUE + # --- Settings ----------------------------------------------------- .INCLUDE : settings.mk diff --git a/svtools/source/svhtml/parhtml.cxx b/svtools/source/svhtml/parhtml.cxx index 3413cd3e7fb8..215133c8efb4 100644 --- a/svtools/source/svhtml/parhtml.cxx +++ b/svtools/source/svhtml/parhtml.cxx @@ -43,10 +43,21 @@ #include <svtools/svstdarr.hxx> #endif +#include <tools/tenccvt.hxx> +#include <tools/datetime.hxx> +#include <svtools/inettype.hxx> +#include <comphelper/string.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> + #include <svtools/parhtml.hxx> #include "htmltokn.h" #include "htmlkywd.hxx" + +using namespace ::com::sun::star; + + const sal_Int32 MAX_LEN( 1024L ); //static sal_Unicode sTmpBuffer[ MAX_LEN+1 ]; const sal_Int32 MAX_MACRO_LEN( 1024 ); @@ -2080,7 +2091,6 @@ BOOL HTMLParser::InternalImgToPrivateURL( String& rURL ) return bFound; } - #ifdef USED void HTMLParser::SaveState( int nToken ) { @@ -2093,3 +2103,241 @@ void HTMLParser::RestoreState() } #endif + +enum eHtmlMetas { + HTML_META_NONE = 0, + HTML_META_AUTHOR, + HTML_META_DESCRIPTION, + HTML_META_KEYWORDS, + HTML_META_REFRESH, + HTML_META_CLASSIFICATION, + HTML_META_CREATED, + HTML_META_CHANGEDBY, + HTML_META_CHANGED, + HTML_META_GENERATOR, + HTML_META_SDFOOTNOTE, + HTML_META_SDENDNOTE, + HTML_META_CONTENT_TYPE +}; + +// <META NAME=xxx> +#ifdef __MINGW32__ // for runtime pseudo reloc +static HTMLOptionEnum aHTMLMetaNameTable[] = +#else +static HTMLOptionEnum __READONLY_DATA aHTMLMetaNameTable[] = +#endif +{ + { OOO_STRING_SVTOOLS_HTML_META_author, HTML_META_AUTHOR }, + { OOO_STRING_SVTOOLS_HTML_META_changed, HTML_META_CHANGED }, + { OOO_STRING_SVTOOLS_HTML_META_changedby, HTML_META_CHANGEDBY }, + { OOO_STRING_SVTOOLS_HTML_META_classification,HTML_META_CLASSIFICATION}, + { OOO_STRING_SVTOOLS_HTML_META_content_type, HTML_META_CONTENT_TYPE }, + { OOO_STRING_SVTOOLS_HTML_META_created, HTML_META_CREATED }, + { OOO_STRING_SVTOOLS_HTML_META_description, HTML_META_DESCRIPTION }, + { OOO_STRING_SVTOOLS_HTML_META_keywords, HTML_META_KEYWORDS }, + { OOO_STRING_SVTOOLS_HTML_META_generator, HTML_META_GENERATOR }, + { OOO_STRING_SVTOOLS_HTML_META_refresh, HTML_META_REFRESH }, + { OOO_STRING_SVTOOLS_HTML_META_sdendnote, HTML_META_SDENDNOTE }, + { OOO_STRING_SVTOOLS_HTML_META_sdfootnote, HTML_META_SDFOOTNOTE }, + { 0, 0 } +}; + + +void HTMLParser::AddMetaUserDefined( ::rtl::OUString const & ) +{ +} + +bool HTMLParser::ParseMetaOptionsImpl( + const uno::Reference<document::XDocumentProperties> & i_xDocProps, + SvKeyValueIterator *i_pHTTPHeader, + const HTMLOptions *i_pOptions, + rtl_TextEncoding& o_rEnc ) +{ + String aName, aContent; + USHORT nAction = HTML_META_NONE; + bool bHTTPEquiv = false, bChanged = false; + + for ( USHORT i = i_pOptions->Count(); i; ) + { + const HTMLOption *pOption = (*i_pOptions)[ --i ]; + switch ( pOption->GetToken() ) + { + case HTML_O_NAME: + aName = pOption->GetString(); + if ( HTML_META_NONE==nAction ) + { + pOption->GetEnum( nAction, aHTMLMetaNameTable ); + } + break; + case HTML_O_HTTPEQUIV: + aName = pOption->GetString(); + pOption->GetEnum( nAction, aHTMLMetaNameTable ); + bHTTPEquiv = true; + break; + case HTML_O_CONTENT: + aContent = pOption->GetString(); + break; + } + } + + if ( bHTTPEquiv || HTML_META_DESCRIPTION != nAction ) + { + // if it is not a Description, remove CRs and LFs from CONTENT + aContent.EraseAllChars( _CR ); + aContent.EraseAllChars( _LF ); + } + else + { + // convert line endings for Description + aContent.ConvertLineEnd(); + } + + + if ( bHTTPEquiv && i_pHTTPHeader ) + { + // #57232#: Netscape seems to just ignore a closing ", so we do too + if ( aContent.Len() && '"' == aContent.GetChar( aContent.Len()-1 ) ) + { + aContent.Erase( aContent.Len() - 1 ); + } + SvKeyValue aKeyValue( aName, aContent ); + i_pHTTPHeader->Append( aKeyValue ); + } + + switch ( nAction ) + { + case HTML_META_AUTHOR: + if (i_xDocProps.is()) { + i_xDocProps->setAuthor( aContent ); + bChanged = true; + } + break; + case HTML_META_DESCRIPTION: + if (i_xDocProps.is()) { + i_xDocProps->setDescription( aContent ); + bChanged = true; + } + break; + case HTML_META_KEYWORDS: + if (i_xDocProps.is()) { + i_xDocProps->setKeywords( + ::comphelper::string::convertCommaSeparated(aContent)); + bChanged = true; + } + break; + case HTML_META_CLASSIFICATION: + if (i_xDocProps.is()) { + i_xDocProps->setSubject( aContent ); + bChanged = true; + } + break; + + case HTML_META_CHANGEDBY: + if (i_xDocProps.is()) { + i_xDocProps->setModifiedBy( aContent ); + } + break; + + case HTML_META_CREATED: + case HTML_META_CHANGED: + if ( i_xDocProps.is() && aContent.Len() && + aContent.GetTokenCount() == 2 ) + { + Date aDate( (ULONG)aContent.GetToken(0).ToInt32() ); + Time aTime( (ULONG)aContent.GetToken(1).ToInt32() ); + DateTime aDateTime( aDate, aTime ); + ::util::DateTime uDT(aDateTime.Get100Sec(), + aDateTime.GetSec(), aDateTime.GetMin(), + aDateTime.GetHour(), aDateTime.GetDay(), + aDateTime.GetMonth(), aDateTime.GetYear()); + if ( HTML_META_CREATED==nAction ) + i_xDocProps->setCreationDate( uDT ); + else + i_xDocProps->setModificationDate( uDT ); + bChanged = true; + } + break; + + case HTML_META_REFRESH: + DBG_ASSERT( !bHTTPEquiv || i_pHTTPHeader, + "Reload-URL aufgrund unterlassener MUSS-Aenderung verlorengegangen" ); + break; + + case HTML_META_CONTENT_TYPE: + if ( aContent.Len() ) + { + o_rEnc = GetEncodingByMIME( aContent ); + } + break; + + case HTML_META_NONE: + if ( !bHTTPEquiv ) + { + if (i_xDocProps.is()) + { + uno::Reference<beans::XPropertyContainer> xUDProps + = i_xDocProps->getUserDefinedProperties(); + try { + xUDProps->addProperty(aName, + beans::PropertyAttribute::REMOVEABLE, + uno::makeAny(::rtl::OUString(aContent))); + AddMetaUserDefined(aName); + bChanged = true; + } catch (uno::Exception &) { + // ignore + } + } + } + break; + default: + break; + } + + return bChanged; +} + +bool HTMLParser::ParseMetaOptions( + const uno::Reference<document::XDocumentProperties> & i_xDocProps, + SvKeyValueIterator *i_pHeader ) +{ + USHORT nContentOption = HTML_O_CONTENT; + rtl_TextEncoding eEnc = RTL_TEXTENCODING_DONTKNOW; + + bool bRet = ParseMetaOptionsImpl( i_xDocProps, i_pHeader, + GetOptions(&nContentOption), + eEnc ); + + // If the encoding is set by a META tag, it may only overwrite the + // current encoding if both, the current and the new encoding, are 1-BYTE + // encodings. Everything else cannot lead to reasonable results. + if (RTL_TEXTENCODING_DONTKNOW != eEnc && + rtl_isOctetTextEncoding( eEnc ) && + rtl_isOctetTextEncoding( GetSrcEncoding() ) ) + { + eEnc = GetExtendedCompatibilityTextEncoding( eEnc ); // #89973# + SetSrcEncoding( eEnc ); + } + + return bRet; +} + +rtl_TextEncoding HTMLParser::GetEncodingByMIME( const String& rMime ) +{ + ByteString sType; + ByteString sSubType; + INetContentTypeParameterList aParameters; + ByteString sMime( rMime, RTL_TEXTENCODING_ASCII_US ); + if (INetContentTypes::parse(sMime, sType, sSubType, &aParameters)) + { + const INetContentTypeParameter * pCharset + = aParameters.find("charset"); + if (pCharset != 0) + { + ByteString sValue( pCharset->m_sValue, RTL_TEXTENCODING_ASCII_US ); + return GetExtendedCompatibilityTextEncoding( + rtl_getTextEncodingFromMimeCharset( sValue.GetBuffer() ) ); + } + } + return RTL_TEXTENCODING_DONTKNOW; +} + diff --git a/svtools/source/svrtf/rtfkey2.cxx b/svtools/source/svrtf/rtfkey2.cxx new file mode 100644 index 000000000000..5c4e1039d92c --- /dev/null +++ b/svtools/source/svrtf/rtfkey2.cxx @@ -0,0 +1,1162 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: rtfkey2.cxx,v $ + * $Revision: 1.14.134.1 $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ + +#include "rtfkeywd.hxx" + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEXCHAR, "\\'" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_IGNORE, "\\*" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OPTHYPH, "\\-" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBENTRY, "\\:" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSH, "\\absh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSW, "\\absw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ALT, "\\alt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANNOTATION, "\\annotation" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANSI, "\\ansi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNID, "\\atnid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AUTHOR, "\\author" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_B, "\\b" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGBDIAG, "\\bgbdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGCROSS, "\\bgcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDCROSS, "\\bgdcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKBDIAG, "\\bgdkbdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKCROSS, "\\bgdkcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKDCROSS, "\\bgdkdcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKFDIAG, "\\bgdkfdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKHORIZ, "\\bgdkhoriz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGDKVERT, "\\bgdkvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGFDIAG, "\\bgfdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGHORIZ, "\\bghoriz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BGVERT, "\\bgvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BIN, "\\bin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BINFSXN, "\\binfsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BINSXN, "\\binsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKCOLF, "\\bkmkcolf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKCOLL, "\\bkmkcoll" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKEND, "\\bkmkend" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKSTART, "\\bkmkstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLUE, "\\blue" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BOX, "\\box" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRB, "\\brdrb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRBAR, "\\brdrbar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRBTW, "\\brdrbtw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRCF, "\\brdrcf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDB, "\\brdrdb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDOT, "\\brdrdot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRHAIR, "\\brdrhair" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRL, "\\brdrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRR, "\\brdrr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRS, "\\brdrs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRSH, "\\brdrsh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRT, "\\brdrt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTH, "\\brdrth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRW, "\\brdrw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRSP, "\\brsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BULLET, "\\bullet" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BUPTIM, "\\buptim" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BXE, "\\bxe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CAPS, "\\caps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CB, "\\cb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CBPAT, "\\cbpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CELL, "\\cell" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CELLX, "\\cellx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CF, "\\cf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CFPAT, "\\cfpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHATN, "\\chatn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHDATE, "\\chdate" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHDPA, "\\chdpa" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHDPL, "\\chdpl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHFTN, "\\chftn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHFTNSEP, "\\chftnsep" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHFTNSEPC, "\\chftnsepc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHPGN, "\\chpgn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHTIME, "\\chtime" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGBDIAG, "\\clbgbdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGCROSS, "\\clbgcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDCROSS, "\\clbgdcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKBDIAG, "\\clbgdkbdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKCROSS, "\\clbgdkcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKDCROSS, "\\clbgdkdcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKFDIAG, "\\clbgdkfdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKHOR, "\\clbgdkhor" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGDKVERT, "\\clbgdkvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGFDIAG, "\\clbgfdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGHORIZ, "\\clbghoriz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBGVERT, "\\clbgvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRB, "\\clbrdrb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRL, "\\clbrdrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRR, "\\clbrdrr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLBRDRT, "\\clbrdrt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLCBPAT, "\\clcbpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLCFPAT, "\\clcfpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLMGF, "\\clmgf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLMRG, "\\clmrg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLSHDNG, "\\clshdng" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLNO, "\\colno" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLORTBL, "\\colortbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLS, "\\cols" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLSR, "\\colsr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLSX, "\\colsx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLUMN, "\\column" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COLW, "\\colw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COMMENT, "\\comment" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CREATIM, "\\creatim" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CTRL, "\\ctrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFF, "\\deff" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFFORMAT, "\\defformat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFLANG, "\\deflang" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFTAB, "\\deftab" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DELETED, "\\deleted" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTX, "\\dfrmtxtx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTY, "\\dfrmtxty" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DIBITMAP, "\\dibitmap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DN, "\\dn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCCOMM, "\\doccomm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCTEMP, "\\doctemp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DROPCAPLI, "\\dropcapli" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DROPCAPT, "\\dropcapt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSNOOVRLP, "\\absnoovrlp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DXFRTEXT, "\\dxfrtext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DY, "\\dy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EDMINS, "\\edmins" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMDASH, "\\emdash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDASH, "\\endash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDDOC, "\\enddoc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDNHERE, "\\endnhere" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENDNOTES, "\\endnotes" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EXPND, "\\expnd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EXPNDTW, "\\expndtw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_F, "\\f" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FACINGP, "\\facingp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FACPGSXN, "\\facpgsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FALT, "\\falt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FCHARSET, "\\fcharset" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FDECOR, "\\fdecor" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FI, "\\fi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FIELD, "\\field" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDDIRTY, "\\flddirty" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDEDIT, "\\fldedit" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDINST, "\\fldinst" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDLOCK, "\\fldlock" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDPRIV, "\\fldpriv" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDRSLT, "\\fldrslt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FMODERN, "\\fmodern" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FN, "\\fn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FNIL, "\\fnil" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FONTTBL, "\\fonttbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTER, "\\footer" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERF, "\\footerf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERL, "\\footerl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERR, "\\footerr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERY, "\\footery" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTNOTE, "\\footnote" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FPRQ, "\\fprq" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRACWIDTH, "\\fracwidth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FROMAN, "\\froman" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FS, "\\fs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FSCRIPT, "\\fscript" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FSWISS, "\\fswiss" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTECH, "\\ftech" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNBJ, "\\ftnbj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNCN, "\\ftncn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNRESTART, "\\ftnrestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNSEP, "\\ftnsep" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNSEPC, "\\ftnsepc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNSTART, "\\ftnstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNTJ, "\\ftntj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GREEN, "\\green" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GUTTER, "\\gutter" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GUTTERSXN, "\\guttersxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADER, "\\header" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERF, "\\headerf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERL, "\\headerl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERR, "\\headerr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERY, "\\headery" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HR, "\\hr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHHOTZ, "\\hyphhotz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_I, "\\i" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ID, "\\id" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_INFO, "\\info" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_INTBL, "\\intbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_IXE, "\\ixe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEEP, "\\keep" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEEPN, "\\keepn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KERNING, "\\kerning" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEYCODE, "\\keycode" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_KEYWORDS, "\\keywords" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LANDSCAPE, "\\landscape" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LANG, "\\lang" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LDBLQUOTE, "\\ldblquote" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVEL, "\\level" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LI, "\\li" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LIN, "\\lin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINE, "\\line" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEBETCOL, "\\linebetcol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINECONT, "\\linecont" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEMOD, "\\linemod" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEPPAGE, "\\lineppage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINERESTART, "\\linerestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINESTART, "\\linestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINESTARTS, "\\linestarts" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINEX, "\\linex" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LNDSCPSXN, "\\lndscpsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LQUOTE, "\\lquote" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MAC, "\\mac" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MACPICT, "\\macpict" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MAKEBACKUP, "\\makebackup" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGB, "\\margb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGBSXN, "\\margbsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGL, "\\margl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGLSXN, "\\marglsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGMIRROR, "\\margmirror" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGR, "\\margr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGRSXN, "\\margrsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGT, "\\margt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MARGTSXN, "\\margtsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MIN, "\\min" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MO, "\\mo" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NEXTCSET, "\\nextcset" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NEXTFILE, "\\nextfile" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFCHARS, "\\nofchars" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFPAGES, "\\nofpages" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFWORDS, "\\nofwords" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOLINE, "\\noline" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSUPERSUB, "\\nosupersub" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOWRAP, "\\nowrap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OPERATOR, "\\operator" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OUTL, "\\outl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAGE, "\\page" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAGEBB, "\\pagebb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAPERH, "\\paperh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAPERW, "\\paperw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PAR, "\\par" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PARD, "\\pard" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PC, "\\pc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PCA, "\\pca" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGHSXN, "\\pghsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNCONT, "\\pgncont" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNDEC, "\\pgndec" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNLCLTR, "\\pgnlcltr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNLCRM, "\\pgnlcrm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNRESTART, "\\pgnrestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNSTART, "\\pgnstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNSTARTS, "\\pgnstarts" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNUCLTR, "\\pgnucltr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNUCRM, "\\pgnucrm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNX, "\\pgnx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNY, "\\pgny" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGWSXN, "\\pgwsxn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PHCOL, "\\phcol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PHMRG, "\\phmrg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PHPG, "\\phpg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPB, "\\piccropb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPL, "\\piccropl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPR, "\\piccropr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICCROPT, "\\piccropt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICH, "\\pich" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICHGOAL, "\\pichgoal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICSCALED, "\\picscaled" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICSCALEX, "\\picscalex" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICSCALEY, "\\picscaley" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICT, "\\pict" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICW, "\\picw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICWGOAL, "\\picwgoal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PLAIN, "\\plain" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PMMETAFILE, "\\pmmetafile" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSNEGX, "\\posnegx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSNEGY, "\\posnegy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSX, "\\posx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXC, "\\posxc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXI, "\\posxi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXL, "\\posxl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXO, "\\posxo" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSXR, "\\posxr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSY, "\\posy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYB, "\\posyb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYC, "\\posyc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYIL, "\\posyil" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYT, "\\posyt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRINTIM, "\\printim" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PSOVER, "\\psover" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PVMRG, "\\pvmrg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PVPARA, "\\pvpara" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PVPG, "\\pvpg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QC, "\\qc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QJ, "\\qj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QL, "\\ql" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_QR, "\\qr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RDBLQUOTE, "\\rdblquote" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RED, "\\red" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVBAR, "\\revbar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVISED, "\\revised" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVISIONS, "\\revisions" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVPROP, "\\revprop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVTIM, "\\revtim" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RI, "\\ri" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RIN, "\\rin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ROW, "\\row" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RQUOTE, "\\rquote" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTF, "\\rtf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RXE, "\\rxe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_S, "\\s" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SA, "\\sa" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SB, "\\sb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBASEDON, "\\sbasedon" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKCOL, "\\sbkcol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKEVEN, "\\sbkeven" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKNONE, "\\sbknone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKODD, "\\sbkodd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBKPAGE, "\\sbkpage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SBYS, "\\sbys" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SCAPS, "\\scaps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECT, "\\sect" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTD, "\\sectd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHAD, "\\shad" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHADING, "\\shading" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHIFT, "\\shift" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SL, "\\sl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SNEXT, "\\snext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STRIKE, "\\strike" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STYLESHEET, "\\stylesheet" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUB, "\\sub" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBJECT, "\\subject" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUPER, "\\super" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TAB, "\\tab" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TB, "\\tb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TC, "\\tc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCF, "\\tcf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCL, "\\tcl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TEMPLATE, "\\template" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TITLE, "\\title" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TITLEPG, "\\titlepg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLDOT, "\\tldot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLEQ, "\\tleq" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLHYPH, "\\tlhyph" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLTH, "\\tlth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLUL, "\\tlul" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQC, "\\tqc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQDEC, "\\tqdec" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQR, "\\tqr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TQL, "\\tql" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRGAPH, "\\trgaph" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRLEFT, "\\trleft" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TROWD, "\\trowd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRQC, "\\trqc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRQL, "\\trql" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRQR, "\\trqr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRRH, "\\trrh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TX, "\\tx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TXE, "\\txe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UL, "\\ul" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULD, "\\uld" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDB, "\\uldb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULNONE, "\\ulnone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULW, "\\ulw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UP, "\\up" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_V, "\\v" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERN, "\\vern" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERSION, "\\version" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALB, "\\vertalb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALC, "\\vertalc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALJ, "\\vertalj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VERTALT, "\\vertalt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBITMAP, "\\wbitmap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBMBITSPIXEL, "\\wbmbitspixel" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBMPLANES, "\\wbmplanes" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WBMWIDTHBYTES, "\\wbmwidthbytes" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WIDOWCTRL, "\\widowctrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WMETAFILE, "\\wmetafile" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_XE, "\\xe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_YR, "\\yr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOBRKHYPH, "\\_" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMULA, "\\|" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOBREAK, "\\~" ); + + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AB, "\\ab" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACAPS, "\\acaps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACF, "\\acf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADDITIVE, "\\additive" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADN, "\\adn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AENDDOC, "\\aenddoc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AENDNOTES, "\\aendnotes" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AEXPND, "\\aexpnd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AF, "\\af" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFS, "\\afs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNBJ, "\\aftnbj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNCN, "\\aftncn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNALC, "\\aftnnalc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNAR, "\\aftnnar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNAUC, "\\aftnnauc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNCHI, "\\aftnnchi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNRLC, "\\aftnnrlc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNRUC, "\\aftnnruc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNRESTART, "\\aftnrestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNRSTCONT, "\\aftnrstcont" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNSEP, "\\aftnsep" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNSEPC, "\\aftnsepc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNSTART, "\\aftnstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNTJ, "\\aftntj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AI, "\\ai" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ALANG, "\\alang" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ALLPROT, "\\allprot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANNOTPROT, "\\annotprot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AOUTL, "\\aoutl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASCAPS, "\\ascaps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASHAD, "\\ashad" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASTRIKE, "\\astrike" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNAUTHOR, "\\atnauthor" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNICN, "\\atnicn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNREF, "\\atnref" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATNTIME, "\\atntime" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATRFEND, "\\atrfend" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ATRFSTART, "\\atrfstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AUL, "\\aul" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULD, "\\auld" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULDB, "\\auldb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULNONE, "\\aulnone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AULW, "\\aulw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AUP, "\\aup" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKPUB, "\\bkmkpub" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASH, "\\brdrdash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRKFRM, "\\brkfrm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CCHS, "\\cchs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CPG, "\\cpg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CS, "\\cs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CVMME, "\\cvmme" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DATAFIELD, "\\datafield" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DO, "\\do" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBXCOLUMN, "\\dobxcolumn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBXMARGIN, "\\dobxmargin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBXPAGE, "\\dobxpage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBYMARGIN, "\\dobymargin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBYPAGE, "\\dobypage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOBYPARA, "\\dobypara" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DODHGT, "\\dodhgt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOLOCK, "\\dolock" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDHOL, "\\dpaendhol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDL, "\\dpaendl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDSOL, "\\dpaendsol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPAENDW, "\\dpaendw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPARC, "\\dparc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPARCFLIPX, "\\dparcflipx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPARCFLIPY, "\\dparcflipy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTHOL, "\\dpastarthol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTL, "\\dpastartl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTSOL, "\\dpastartsol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPASTARTW, "\\dpastartw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCALLOUT, "\\dpcallout" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOA, "\\dpcoa" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOACCENT, "\\dpcoaccent" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOBESTFIT, "\\dpcobestfit" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOBORDER, "\\dpcoborder" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODABS, "\\dpcodabs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODBOTTOM, "\\dpcodbottom" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODCENTER, "\\dpcodcenter" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODTOP, "\\dpcodtop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOLENGTH, "\\dpcolength" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOMINUSX, "\\dpcominusx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOMINUSY, "\\dpcominusy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOOFFSET, "\\dpcooffset" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOSMARTA, "\\dpcosmarta" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTDOUBLE, "\\dpcotdouble" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTRIGHT, "\\dpcotright" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTSINGLE, "\\dpcotsingle" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOTTRIPLE, "\\dpcottriple" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCOUNT, "\\dpcount" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPELLIPSE, "\\dpellipse" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPENDGROUP, "\\dpendgroup" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGCB, "\\dpfillbgcb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGCG, "\\dpfillbgcg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGCR, "\\dpfillbgcr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGGRAY, "\\dpfillbggray" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLBGPAL, "\\dpfillbgpal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGCB, "\\dpfillfgcb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGCG, "\\dpfillfgcg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGCR, "\\dpfillfgcr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGGRAY, "\\dpfillfggray" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLFGPAL, "\\dpfillfgpal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPFILLPAT, "\\dpfillpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPGROUP, "\\dpgroup" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINE, "\\dpline" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINECOB, "\\dplinecob" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINECOG, "\\dplinecog" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINECOR, "\\dplinecor" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDADO, "\\dplinedado" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDADODO, "\\dplinedadodo" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDASH, "\\dplinedash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEDOT, "\\dplinedot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEGRAY, "\\dplinegray" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEHOLLOW, "\\dplinehollow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEPAL, "\\dplinepal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINESOLID, "\\dplinesolid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPLINEW, "\\dplinew" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPOLYCOUNT, "\\dppolycount" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPOLYGON, "\\dppolygon" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPOLYLINE, "\\dppolyline" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPTX, "\\dpptx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPPTY, "\\dppty" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPRECT, "\\dprect" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPROUNDR, "\\dproundr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPSHADOW, "\\dpshadow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPSHADX, "\\dpshadx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPSHADY, "\\dpshady" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPTXBX, "\\dptxbx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPTXBXMAR, "\\dptxbxmar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPTXBXTEXT, "\\dptxbxtext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPX, "\\dpx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPXSIZE, "\\dpxsize" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPY, "\\dpy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPYSIZE, "\\dpysize" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DS, "\\ds" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMSPACE, "\\emspace" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ENSPACE, "\\enspace" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FBIDI, "\\fbidi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FET, "\\fet" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FID, "\\fid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FILE, "\\file" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FILETBL, "\\filetbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDALT, "\\fldalt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FNETWORK, "\\fnetwork" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FONTEMB, "\\fontemb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FONTFILE, "\\fontfile" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMDISP, "\\formdisp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMPROT, "\\formprot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMSHADE, "\\formshade" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOSNUM, "\\fosnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRELATIVE, "\\frelative" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNALT, "\\ftnalt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNIL, "\\ftnil" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNALC, "\\ftnnalc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNAR, "\\ftnnar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNAUC, "\\ftnnauc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNCHI, "\\ftnnchi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNRLC, "\\ftnnrlc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNRUC, "\\ftnnruc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNRSTCONT, "\\ftnrstcont" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNRSTPG, "\\ftnrstpg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTTRUETYPE, "\\fttruetype" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDDOS, "\\fvaliddos" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDHPFS, "\\fvalidhpfs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDMAC, "\\fvalidmac" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FVALIDNTFS, "\\fvalidntfs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHAUTO, "\\hyphauto" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHCAPS, "\\hyphcaps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHCONSEC, "\\hyphconsec" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHPAR, "\\hyphpar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINKSELF, "\\linkself" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINKSTYLES, "\\linkstyles" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRCH, "\\ltrch" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRDOC, "\\ltrdoc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRMARK, "\\ltrmark" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRPAR, "\\ltrpar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRROW, "\\ltrrow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LTRSECT, "\\ltrsect" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOCOLBAL, "\\nocolbal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOEXTRASPRL, "\\noextrasprl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOTABIND, "\\notabind" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOWIDCTLPAR, "\\nowidctlpar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJALIAS, "\\objalias" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJALIGN, "\\objalign" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJAUTLINK, "\\objautlink" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCLASS, "\\objclass" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPB, "\\objcropb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPL, "\\objcropl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPR, "\\objcropr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJCROPT, "\\objcropt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJDATA, "\\objdata" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJECT, "\\object" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJEMB, "\\objemb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJH, "\\objh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJICEMB, "\\objicemb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJLINK, "\\objlink" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJLOCK, "\\objlock" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJNAME, "\\objname" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJPUB, "\\objpub" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSCALEX, "\\objscalex" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSCALEY, "\\objscaley" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSECT, "\\objsect" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSETSIZE, "\\objsetsize" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJSUB, "\\objsub" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJTIME, "\\objtime" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJTRANSY, "\\objtransy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJUPDATE, "\\objupdate" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJW, "\\objw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OTBLRUL, "\\otblrul" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHN, "\\pgnhn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSC, "\\pgnhnsc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSH, "\\pgnhnsh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSM, "\\pgnhnsm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSN, "\\pgnhnsn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNHNSP, "\\pgnhnsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICBMP, "\\picbmp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICBPP, "\\picbpp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PN, "\\pn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNACROSS, "\\pnacross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNB, "\\pnb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCAPS, "\\pncaps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCARD, "\\pncard" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCF, "\\pncf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDEC, "\\pndec" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNF, "\\pnf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNFS, "\\pnfs" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNHANG, "\\pnhang" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNI, "\\pni" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNINDENT, "\\pnindent" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLCLTR, "\\pnlcltr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLCRM, "\\pnlcrm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVL, "\\pnlvl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVLBLT, "\\pnlvlblt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVLBODY, "\\pnlvlbody" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNLVLCONT, "\\pnlvlcont" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNNUMONCE, "\\pnnumonce" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNORD, "\\pnord" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNORDT, "\\pnordt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNPREV, "\\pnprev" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNQC, "\\pnqc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNQL, "\\pnql" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNQR, "\\pnqr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRESTART, "\\pnrestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSCAPS, "\\pnscaps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSECLVL, "\\pnseclvl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSP, "\\pnsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSTART, "\\pnstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNSTRIKE, "\\pnstrike" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNTEXT, "\\pntext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNTXTA, "\\pntxta" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNTXTB, "\\pntxtb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNUCLTR, "\\pnucltr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNUCRM, "\\pnucrm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNUL, "\\pnul" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULD, "\\pnuld" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULDB, "\\pnuldb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULNONE, "\\pnulnone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNULW, "\\pnulw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRCOLBL, "\\prcolbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRINTDATA, "\\printdata" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PSZ, "\\psz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PUBAUTO, "\\pubauto" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RESULT, "\\result" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVAUTH, "\\revauth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVDTTM, "\\revdttm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVPROT, "\\revprot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVTBL, "\\revtbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTBMP, "\\rsltbmp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTMERGE, "\\rsltmerge" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTPICT, "\\rsltpict" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTRTF, "\\rsltrtf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RSLTTXT, "\\rslttxt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLCH, "\\rtlch" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLDOC, "\\rtldoc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLMARK, "\\rtlmark" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLPAR, "\\rtlpar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLROW, "\\rtlrow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_RTLSECT, "\\rtlsect" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SEC, "\\sec" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTNUM, "\\sectnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTUNLOCKED, "\\sectunlocked" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SLMULT, "\\slmult" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTCOL, "\\softcol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTLHEIGHT, "\\softlheight" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTLINE, "\\softline" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOFTPAGE, "\\softpage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSSPBF, "\\sprsspbf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSTSP, "\\sprstsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBDOCUMENT, "\\subdocument" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SWPBDR, "\\swpbdr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCN, "\\tcn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRANSMF, "\\transmf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRB, "\\trbrdrb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRH, "\\trbrdrh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRL, "\\trbrdrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRR, "\\trbrdrr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRT, "\\trbrdrt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRBRDRV, "\\trbrdrv" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRHDR, "\\trhdr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRKEEP, "\\trkeep" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDB, "\\trpaddb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDL, "\\trpaddl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDR, "\\trpaddr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDT, "\\trpaddt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFB, "\\trpaddfb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFL, "\\trpaddfl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFR, "\\trpaddfr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRPADDFT, "\\trpaddft" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WRAPTRSP, "\\wraptrsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_XEF, "\\xef" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ZWJ, "\\zwj" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ZWNJ, "\\zwnj" ); + +// neue Tokens zur 1.5 +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ABSLOCK, "\\abslock" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADJUSTRIGHT, "\\adjustright" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNCHOSUNG, "\\aftnnchosung" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNCNUM, "\\aftnncnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBAR, "\\aftnndbar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUM, "\\aftnndbnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUMD, "\\aftnndbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUMK, "\\aftnndbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNDBNUMT, "\\aftnndbnumt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGANADA, "\\aftnnganada" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUM, "\\aftnngbnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUMD, "\\aftnngbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUMK, "\\aftnngbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNGBNUML, "\\aftnngbnuml" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNZODIAC, "\\aftnnzodiac" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNZODIACD, "\\aftnnzodiacd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_AFTNNZODIACL, "\\aftnnzodiacl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANIMTEXT, "\\animtext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ANSICPG, "\\ansicpg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BACKGROUND, "\\background" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BDBFHDR, "\\bdbfhdr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLIPTAG, "\\bliptag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLIPUID, "\\blipuid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BLIPUPI, "\\blipupi" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRART, "\\brdrart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHD, "\\brdrdashd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHDD, "\\brdrdashdd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHDOTSTR, "\\brdrdashdotstr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRDASHSM, "\\brdrdashsm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDREMBOSS, "\\brdremboss" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRENGRAVE, "\\brdrengrave" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRFRAME, "\\brdrframe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTHTNLG, "\\brdrthtnlg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTHTNMG, "\\brdrthtnmg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTHTNSG, "\\brdrthtnsg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHLG, "\\brdrtnthlg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHMG, "\\brdrtnthmg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHSG, "\\brdrtnthsg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHTNLG, "\\brdrtnthtnlg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHTNMG, "\\brdrtnthtnmg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTNTHTNSG, "\\brdrtnthtnsg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRTRIPLE, "\\brdrtriple" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRWAVY, "\\brdrwavy" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDRWAVYDB, "\\brdrwavydb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CATEGORY, "\\category" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CGRID, "\\cgrid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHARSCALEX, "\\charscalex" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGBDIAG, "\\chbgbdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGCROSS, "\\chbgcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDCROSS, "\\chbgdcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKBDIAG, "\\chbgdkbdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKCROSS, "\\chbgdkcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKDCROSS, "\\chbgdkdcross" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKFDIAG, "\\chbgdkfdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKHORIZ, "\\chbgdkhoriz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGDKVERT, "\\chbgdkvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGFDIAG, "\\chbgfdiag" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGHORIZ, "\\chbghoriz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBGVERT, "\\chbgvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHBRDR, "\\chbrdr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHCBPAT, "\\chcbpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHCFPAT, "\\chcfpat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CHSHDNG, "\\chshdng" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADL, "\\clpadl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADT, "\\clpadt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADB, "\\clpadb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADR, "\\clpadr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFL, "\\clpadfl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFT, "\\clpadft" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFB, "\\clpadfb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLPADFR, "\\clpadfr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXLRTB, "\\cltxlrtb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXTBRL, "\\cltxtbrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVERTALB, "\\clvertalb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVERTALC, "\\clvertalc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVERTALT, "\\clvertalt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVMGF, "\\clvmgf" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLVMRG, "\\clvmrg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXTBRLV, "\\cltxtbrlv" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXBTLR, "\\cltxbtlr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CLTXLRTBV, "\\cltxlrtbv" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_COMPANY, "\\company" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CRAUTH, "\\crauth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_CRDATE, "\\crdate" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DATE, "\\date" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DEFLANGFE, "\\deflangfe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRAUTH, "\\dfrauth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRDATE, "\\dfrdate" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRSTART, "\\dfrstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRSTOP, "\\dfrstop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRXST, "\\dfrxst" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DGMARGIN, "\\dgmargin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DNTBLNSBDB, "\\dntblnsbdb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCTYPE, "\\doctype" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DOCVAR, "\\docvar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DPCODESCENT, "\\dpcodescent" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMBO, "\\embo" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EMFBLIP, "\\emfblip" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_EXPSHRTN, "\\expshrtn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAAUTO, "\\faauto" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FBIAS, "\\fbias" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFDEFRES, "\\ffdefres" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFDEFTEXT, "\\ffdeftext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFENTRYMCR, "\\ffentrymcr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFEXITMCR, "\\ffexitmcr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFFORMAT, "\\ffformat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFHASLISTBOX, "\\ffhaslistbox" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFHELPTEXT, "\\ffhelptext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFHPS, "\\ffhps" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFL, "\\ffl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFMAXLEN, "\\ffmaxlen" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFNAME, "\\ffname" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFOWNHELP, "\\ffownhelp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFOWNSTAT, "\\ffownstat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFPROT, "\\ffprot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFRECALC, "\\ffrecalc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFRES, "\\ffres" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFSIZE, "\\ffsize" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFSTATTEXT, "\\ffstattext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFTYPE, "\\fftype" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FFTYPETXT, "\\fftypetxt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLDTYPE, "\\fldtype" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FNAME, "\\fname" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FORMFIELD, "\\formfield" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FROMTEXT, "\\fromtext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNCHOSUNG, "\\ftnnchosung" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNCNUM, "\\ftnncnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBAR, "\\ftnndbar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUM, "\\ftnndbnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUMD, "\\ftnndbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUMK, "\\ftnndbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNDBNUMT, "\\ftnndbnumt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGANADA, "\\ftnnganada" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUM, "\\ftnngbnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUMD, "\\ftnngbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUMK, "\\ftnngbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNGBNUML, "\\ftnngbnuml" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNZODIAC, "\\ftnnzodiac" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNZODIACD, "\\ftnnzodiacd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FTNNZODIACL, "\\ftnnzodiacl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_G, "\\g" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GCW, "\\gcw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRIDTBL, "\\gridtbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HIGHLIGHT, "\\highlight" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLFR, "\\hlfr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLINKBASE, "\\hlinkbase" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLLOC, "\\hlloc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HLSRC, "\\hlsrc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ILVL, "\\ilvl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_IMPR, "\\impr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_JPEGBLIP, "\\jpegblip" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELFOLLOW, "\\levelfollow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELINDENT, "\\levelindent" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELJC, "\\leveljc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELLEGAL, "\\levellegal" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELNFC, "\\levelnfc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELNORESTART, "\\levelnorestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELNUMBERS, "\\levelnumbers" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELOLD, "\\levelold" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELPREV, "\\levelprev" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELPREVSPACE, "\\levelprevspace" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELSPACE, "\\levelspace" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELSTARTAT, "\\levelstartat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LEVELTEXT, "\\leveltext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LINKVAL, "\\linkval" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LIST, "\\list" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTID, "\\listid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTLEVEL, "\\listlevel" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTNAME, "\\listname" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDE, "\\listoverride" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDECOUNT, "\\listoverridecount" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDEFORMAT, "\\listoverrideformat" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDESTART, "\\listoverridestart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTOVERRIDETABLE, "\\listoverridetable" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTRESTARTHDN, "\\listrestarthdn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTSIMPLE, "\\listsimple" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTTABLE, "\\listtable" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTTEMPLATEID, "\\listtemplateid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LISTTEXT, "\\listtext" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LS, "\\ls" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LYTEXCTTP, "\\lytexcttp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LYTPRTMET, "\\lytprtmet" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MANAGER, "\\manager" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_MSMCAP, "\\msmcap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOFCHARSWS, "\\nofcharsws" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOLEAD, "\\nolead" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NONSHPPICT, "\\nonshppict" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSECTEXPAND, "\\nosectexpand" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSNAPLINEGRID, "\\nosnaplinegrid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOSPACEFORUL, "\\nospaceforul" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOULTRLSPC, "\\noultrlspc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOXLATTOYEN, "\\noxlattoyen" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJATTPH, "\\objattph" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJHTML, "\\objhtml" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OBJOCX, "\\objocx" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDLINEWRAP, "\\oldlinewrap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OUTLINELEVEL, "\\outlinelevel" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OVERLAY, "\\overlay" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PANOSE, "\\panose" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRB, "\\pgbrdrb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRFOOT, "\\pgbrdrfoot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRHEAD, "\\pgbrdrhead" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRL, "\\pgbrdrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDROPT, "\\pgbrdropt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRR, "\\pgbrdrr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRSNAP, "\\pgbrdrsnap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRDRT, "\\pgbrdrt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNCHOSUNG, "\\pgnchosung" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNCNUM, "\\pgncnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNDBNUMK, "\\pgndbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNDBNUMT, "\\pgndbnumt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGANADA, "\\pgnganada" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUM, "\\pgngbnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUMD, "\\pgngbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUMK, "\\pgngbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNGBNUML, "\\pgngbnuml" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNZODIAC, "\\pgnzodiac" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNZODIACD, "\\pgnzodiacd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGNZODIACL, "\\pgnzodiacl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PICPROP, "\\picprop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNAIUEO, "\\pnaiueo" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNAIUEOD, "\\pnaiueod" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNCHOSUNG, "\\pnchosung" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUMD, "\\pndbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUMK, "\\pndbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUML, "\\pndbnuml" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNDBNUMT, "\\pndbnumt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGANADA, "\\pnganada" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBLIP, "\\pngblip" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUM, "\\pngbnum" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUMD, "\\pngbnumd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUMK, "\\pngbnumk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNGBNUML, "\\pngbnuml" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRAUTH, "\\pnrauth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRDATE, "\\pnrdate" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRNFC, "\\pnrnfc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRNOT, "\\pnrnot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRPNBR, "\\pnrpnbr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRRGB, "\\pnrrgb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRSTART, "\\pnrstart" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRSTOP, "\\pnrstop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNRXST, "\\pnrxst" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNZODIAC, "\\pnzodiac" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNZODIACD, "\\pnzodiacd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PNZODIACL, "\\pnzodiacl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LFOLEVEL, "\\lfolevel" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYIN, "\\posyin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_POSYOUT, "\\posyout" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRIVATE, "\\private" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PROPNAME, "\\propname" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PROPTYPE, "\\proptype" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVAUTHDEL, "\\revauthdel" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_REVDTTMDEL, "\\revdttmdel" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SAUTOUPD, "\\sautoupd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTDEFAULTCL, "\\sectdefaultcl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTEXPAND, "\\sectexpand" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTLINEGRID, "\\sectlinegrid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTSPECIFYCL, "\\sectspecifycl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SECTSPECIFYL, "\\sectspecifyl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHIDDEN, "\\shidden" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBOTTOM, "\\shpbottom" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBXCOLUMN, "\\shpbxcolumn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBXMARGIN, "\\shpbxmargin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBXPAGE, "\\shpbxpage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBYMARGIN, "\\shpbymargin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBYPAGE, "\\shpbypage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBYPARA, "\\shpbypara" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPFBLWTXT, "\\shpfblwtxt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPFHDR, "\\shpfhdr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPGRP, "\\shpgrp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLEFT, "\\shpleft" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLID, "\\shplid" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLOCKANCHOR, "\\shplockanchor" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPPICT, "\\shppict" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPRIGHT, "\\shpright" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPRSLT, "\\shprslt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPTOP, "\\shptop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPTXT, "\\shptxt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPWRK, "\\shpwrk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPWR, "\\shpwr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPZ, "\\shpz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSBSP, "\\sprsbsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSLNSP, "\\sprslnsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SPRSTSM, "\\sprstsm" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STATICVAL, "\\staticval" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STEXTFLOW, "\\stextflow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_STRIKED, "\\striked" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SUBFONTBYSIZE, "\\subfontbysize" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TCELLD, "\\tcelld" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TIME, "\\time" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TRUNCATEFONTHEIGHT, "\\truncatefontheight" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UC, "\\uc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UD, "\\ud" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDASH, "\\uldash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDASHD, "\\uldashd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULDASHDD, "\\uldashdd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTH, "\\ulth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULWAVE, "\\ulwave" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULC, "\\ulc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_U, "\\u" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UPR, "\\upr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_USERPROPS, "\\userprops" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VIEWKIND, "\\viewkind" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VIEWSCALE, "\\viewscale" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_VIEWZK, "\\viewzk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WIDCTLPAR, "\\widctlpar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WINDOWCAPTION, "\\windowcaption" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WPEQN, "\\wpeqn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WPJST, "\\wpjst" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_WPSP, "\\wpsp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_YXE, "\\yxe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXLRTB, "\\frmtxlrtb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXTBRL, "\\frmtxtbrl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXBTLR, "\\frmtxbtlr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXLRTBV, "\\frmtxlrtbv" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FRMTXTBRLV, "\\frmtxtbrlv" ); + +// MS-2000 Tokens +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHD, "\\ulthd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHDASH, "\\ulthdash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULLDASH, "\\ulldash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHLDASH, "\\ulthldash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHDASHD, "\\ulthdashd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULTHDASHDD, "\\ulthdashdd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULHWAVE, "\\ulhwave" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ULULDBWAVE, "\\ululdbwave" ); + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LOCH, "\\loch" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HICH, "\\hich" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DBCH, "\\dbch" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_LANGFE, "\\langfe" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADEFLANG, "\\adeflang" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ADEFF, "\\adeff" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACCNONE, "\\accnone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACCDOT, "\\accdot" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ACCCOMMA, "\\acccomma" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TWOINONE, "\\twoinone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HORZVERT, "\\horzvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAHANG, "\\fahang" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAVAR, "\\favar" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FACENTER, "\\facenter" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAROMAN, "\\faroman" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FAFIXED, "\\fafixed" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOCWRAP, "\\nocwrap" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_NOOVERFLOW,"\\nooverflow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_ASPALPHA, "\\aspalpha" ); + +// SWG spezifische Attribute +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRFALIGNV, "\\grfalignv" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRFALIGNH, "\\grfalignh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_GRFMIRROR, "\\grfmirror" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERYB, "\\headeryb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERXL, "\\headerxl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERXR, "\\headerxr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERYT, "\\footeryt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERXL, "\\footerxl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERXR, "\\footerxr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HEADERYH, "\\headeryh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FOOTERYH, "\\footeryh" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BALANCEDCOLUMN, "\\swcolmnblnc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_UPDNPROP, "\\updnprop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PRTDATA, "\\prtdata" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BKMKKEY, "\\bkmkkey" ); + +// Attribute fuer die freifliegenden Rahmen +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYPRINT, "\\flyprint" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYOPAQUE, "\\flyopaque" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYPRTCTD, "\\flyprtctd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYMAINCNT, "\\flymaincnt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYVERT, "\\flyvert" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYHORZ, "\\flyhorz" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTL, "\\dfrmtxtl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTR, "\\dfrmtxtr" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTU, "\\dfrmtxtu" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_DFRMTXTW, "\\dfrmtxtw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYANCHOR, "\\flyanchor" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYCNTNT, "\\flycntnt" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYCOLUMN, "\\flycolumn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYPAGE, "\\flypage" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_FLYINPARA, "\\flyinpara" ); + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDBOX, "\\brdbox" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNCOL, "\\brdlncol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNIN, "\\brdlnin" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNOUT, "\\brdlnout" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_BRDLNDIST, "\\brdlndist" ); + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHADOW, "\\shadow" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWDIST, "\\shdwdist" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWSTYLE, "\\shdwstyle" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWCOL, "\\shdwcol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHDWFCOL, "\\shdwfcol" ); + + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCTBL, "\\pgdsctbl" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSC, "\\pgdsc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCUSE, "\\pgdscuse" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCNXT, "\\pgdscnxt" ); + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHEN, "\\hyphen" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHLEAD, "\\hyphlead" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHTRAIL, "\\hyphtrail" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_HYPHMAX, "\\hyphmax" ); + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_TLSWG, "\\tlswg" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGBRK, "\\pgbrk" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_PGDSCNO, "\\pgdscno" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SOUTLVL, "\\soutlvl" ); + +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHP, "\\shp" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SN, "\\sn" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SV, "\\sv" ); +/* +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPLEFT, "\\shpleft" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPTOP, "\\shptop" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPBOTTOM, "\\shpbottom" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_SHPRIGHT, "\\shpright" ); +*/ + +// Support for overline attributes +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OL, "\\ol" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLD, "\\old" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDB, "\\oldb" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLNONE, "\\olnone" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLW, "\\olw" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDASH, "\\oldash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDASHD, "\\oldashd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLDASHDD, "\\oldashdd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTH, "\\olth" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLWAVE, "\\olwave" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLC, "\\olc" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHD, "\\olthd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHDASH, "\\olthdash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLLDASH, "\\olldash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHLDASH, "\\olthldash" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHDASHD, "\\olthdashd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLTHDASHDD, "\\olthdashdd" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLHWAVE, "\\olhwave" ); +sal_Char const SVTOOLS_CONSTASCII_DEF( sRTF_OLOLDBWAVE, "\\ololdbwave" ); + +/* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/svtools/source/svrtf/svparser.cxx b/svtools/source/svrtf/svparser.cxx index f58a5d11a3c6..c7444dd5cbcb 100644 --- a/svtools/source/svrtf/svparser.cxx +++ b/svtools/source/svrtf/svparser.cxx @@ -666,4 +666,64 @@ IMPL_STATIC_LINK( SvParser, NewDataRead, void*, EMPTYARG ) return 0; } +/*======================================================================== + * + * SvKeyValueIterator. + * + *======================================================================*/ +SV_DECL_PTRARR_DEL(SvKeyValueList_Impl, SvKeyValue*, 0, 4) +SV_IMPL_PTRARR(SvKeyValueList_Impl, SvKeyValue*); + +/* + * SvKeyValueIterator. + */ +SvKeyValueIterator::SvKeyValueIterator (void) + : m_pList (new SvKeyValueList_Impl), + m_nPos (0) +{ +} + +/* + * ~SvKeyValueIterator. + */ +SvKeyValueIterator::~SvKeyValueIterator (void) +{ + delete m_pList; +} + +/* + * GetFirst. + */ +BOOL SvKeyValueIterator::GetFirst (SvKeyValue &rKeyVal) +{ + m_nPos = m_pList->Count(); + return GetNext (rKeyVal); +} + +/* + * GetNext. + */ +BOOL SvKeyValueIterator::GetNext (SvKeyValue &rKeyVal) +{ + if (m_nPos > 0) + { + rKeyVal = *m_pList->GetObject(--m_nPos); + return TRUE; + } + else + { + // Nothing to do. + return FALSE; + } +} + +/* + * Append. + */ +void SvKeyValueIterator::Append (const SvKeyValue &rKeyVal) +{ + SvKeyValue *pKeyVal = new SvKeyValue (rKeyVal); + m_pList->C40_INSERT(SvKeyValue, pKeyVal, m_pList->Count()); +} + /* vi:set tabstop=4 shiftwidth=4 expandtab: */ diff --git a/svtools/source/uno/unoevent.cxx b/svtools/source/uno/unoevent.cxx index 14321ecdd84c..19d40c17ce5c 100644 --- a/svtools/source/uno/unoevent.cxx +++ b/svtools/source/uno/unoevent.cxx @@ -492,7 +492,7 @@ SvDetachedEventDescriptor::~SvDetachedEventDescriptor() delete aMacros[i]; } - delete aMacros; + delete [] aMacros; } sal_Int16 SvDetachedEventDescriptor::getIndex(const sal_uInt16 nID) const diff --git a/toolkit/inc/toolkit/helper/property.hxx b/toolkit/inc/toolkit/helper/property.hxx index da2de08c9544..f5e1b4ea3770 100644 --- a/toolkit/inc/toolkit/helper/property.hxx +++ b/toolkit/inc/toolkit/helper/property.hxx @@ -165,7 +165,7 @@ namespace rtl { #define BASEPROPERTY_IMAGEPOSITION 113 // sal_Int16 #define BASEPROPERTY_NATIVE_WIDGET_LOOK 114 // sal_Bool #define BASEPROPERTY_VERTICALALIGN 115 // VerticalAlignment -#define BASEPROPERTY_WHEELWITHOUTFOCUS 116 // sal_Bool +#define BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR 116 // sal_Int16 #define BASEPROPERTY_GRAPHIC 117 // css.graphic.XGraphic #define BASEPROPERTY_STEP_TIME 118 // sal_Int32 #define BASEPROPERTY_DECORATION 119 // sal_Bool @@ -191,6 +191,7 @@ namespace rtl { #define BASEPROPERTY_IMAGE_SCALE_MODE 137 #define BASEPROPERTY_WRITING_MODE 138 #define BASEPROPERTY_CONTEXT_WRITING_MODE 139 +#define BASEPROPERTY_ENABLEVISIBLE 140 // sal_Bool // Keine gebundenen Properties, werden immer aus der Property BASEPROPERTY_FONTDESCRIPTOR entnommen. #define BASEPROPERTY_FONTDESCRIPTORPART_START 1000 diff --git a/toolkit/inc/toolkit/helper/vclunohelper.hxx b/toolkit/inc/toolkit/helper/vclunohelper.hxx index 68583f99b447..1c5d89a3cc64 100644 --- a/toolkit/inc/toolkit/helper/vclunohelper.hxx +++ b/toolkit/inc/toolkit/helper/vclunohelper.hxx @@ -135,11 +135,15 @@ public: static MapUnit /* MapModeUnit */ ConvertToMapModeUnit(sal_Int16 /* com.sun.star.util.MeasureUnit.* */ _nMeasureUnit) throw (::com::sun::star::lang::IllegalArgumentException); static sal_Int16 /* com.sun.star.util.MeasureUnit.* */ ConvertToMeasurementUnit(MapUnit /* MapModeUnit */ _nMapModeUnit) throw (::com::sun::star::lang::IllegalArgumentException); + static ::Size /* VCLSize */ ConvertToVCLSize(::com::sun::star::awt::Size const& _aSize); static ::com::sun::star::awt::Size ConvertToAWTSize(::Size /* VCLSize */ const& _aSize); + static ::Point /* VCLPoint */ ConvertToVCLPoint(::com::sun::star::awt::Point const& _aPoint); static ::com::sun::star::awt::Point ConvertToAWTPoint(::Point /* VCLPoint */ const& _aPoint); + static ::Rectangle ConvertToVCLRect( ::com::sun::star::awt::Rectangle const & _rRect ); + static ::com::sun::star::awt::Rectangle ConvertToAWTRect( ::Rectangle const & _rRect ); }; diff --git a/toolkit/source/awt/vclxwindow.cxx b/toolkit/source/awt/vclxwindow.cxx index 09e318800184..337400c08713 100644 --- a/toolkit/source/awt/vclxwindow.cxx +++ b/toolkit/source/awt/vclxwindow.cxx @@ -35,6 +35,7 @@ #include <com/sun/star/awt/KeyModifier.hpp> #include <com/sun/star/awt/MouseEvent.hpp> #include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/awt/MouseWheelBehavior.hpp> #include <com/sun/star/awt/XTopWindow.hpp> #include <com/sun/star/awt/Style.hpp> #include <com/sun/star/accessibility/AccessibleRole.hpp> @@ -82,6 +83,7 @@ using ::com::sun::star::style::VerticalAlignment_BOTTOM; using ::com::sun::star::style::VerticalAlignment_MAKE_FIXED_SIZE; namespace WritingMode2 = ::com::sun::star::text::WritingMode2; +namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior; //==================================================================== @@ -226,6 +228,8 @@ private: ::toolkit::AccessibilityClient maAccFactory; bool mbDisposed; bool mbDrawingOntoParent; // no bit mask, is passed around by reference + sal_Bool mbEnableVisible; + sal_Bool mbDirectVisible; ::osl::Mutex maListenerContainerMutex; ::cppu::OInterfaceContainerHelper maWindow2Listeners; @@ -273,6 +277,15 @@ public: */ VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex, bool _bWithDefaultProps ); + /** synchronously mbEnableVisible + */ + void setEnableVisible( sal_Bool bEnableVisible ) { mbEnableVisible = bEnableVisible; } + sal_Bool isEnableVisible() { return mbEnableVisible; } + /** synchronously mbDirectVisible; + */ + void setDirectVisible( sal_Bool bDirectVisible ) { mbDirectVisible = bDirectVisible; } + sal_Bool isDirectVisible() { return mbDirectVisible; } + /** asynchronously notifies a mouse event to the VCLXWindow's XMouseListeners */ void notifyMouseEvent( const awt::MouseEvent& _rMouseEvent, MouseEventType _nType ); @@ -347,6 +360,8 @@ VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex, ,mrMutex( _rMutex ) ,mbDisposed( false ) ,mbDrawingOntoParent( false ) + ,mbEnableVisible(sal_True) + ,mbDirectVisible(sal_True) ,maListenerContainerMutex( ) ,maWindow2Listeners( maListenerContainerMutex ) ,maDockableWindowListeners( maListenerContainerMutex ) @@ -625,7 +640,12 @@ void VCLXWindow::SetWindow( Window* pWindow ) SetOutputDevice( pWindow ); if ( GetWindow() ) + { GetWindow()->AddEventListener( LINK( this, VCLXWindow, WindowEventListener ) ); + sal_Bool bDirectVisible = pWindow ? pWindow->IsVisible() : false; + mpImpl->setDirectVisible( bDirectVisible ); + } + } void VCLXWindow::suspendVclEventListening( ) @@ -1226,7 +1246,8 @@ void VCLXWindow::setVisible( sal_Bool bVisible ) throw(::com::sun::star::uno::Ru } } */ - pWindow->Show( bVisible ); + mpImpl->setDirectVisible( bVisible ); + pWindow->Show( bVisible && mpImpl->isEnableVisible() ); } } @@ -1529,6 +1550,7 @@ void VCLXWindow::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds, bool bWithDe BASEPROPERTY_HELPURL, BASEPROPERTY_TEXT, BASEPROPERTY_PRINTABLE, + BASEPROPERTY_ENABLEVISIBLE, // for visibility BASEPROPERTY_TABSTOP, 0); @@ -1634,19 +1656,27 @@ void VCLXWindow::setProperty( const ::rtl::OUString& PropertyName, const ::com:: } break; - case BASEPROPERTY_WHEELWITHOUTFOCUS: + case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR: { - sal_Bool bWheelOnHover( sal_True ); - if ( Value >>= bWheelOnHover ) - { - AllSettings aSettings = pWindow->GetSettings(); - MouseSettings aMouseSettings = aSettings.GetMouseSettings(); + sal_uInt16 nWheelBehavior( MouseWheelBehavior::SCROLL_FOCUS_ONLY ); + OSL_VERIFY( Value >>= nWheelBehavior ); - aMouseSettings.SetNoWheelActionWithoutFocus( !bWheelOnHover ); - aSettings.SetMouseSettings( aMouseSettings ); + AllSettings aSettings = pWindow->GetSettings(); + MouseSettings aMouseSettings = aSettings.GetMouseSettings(); - pWindow->SetSettings( aSettings, TRUE ); + USHORT nVclBehavior( MOUSE_WHEEL_FOCUS_ONLY ); + switch ( nWheelBehavior ) + { + case MouseWheelBehavior::SCROLL_DISABLED: nVclBehavior = MOUSE_WHEEL_DISABLE; break; + case MouseWheelBehavior::SCROLL_FOCUS_ONLY: nVclBehavior = MOUSE_WHEEL_FOCUS_ONLY; break; + case MouseWheelBehavior::SCROLL_ALWAYS: nVclBehavior = MOUSE_WHEEL_ALWAYS; break; + default: + OSL_ENSURE( false, "VCLXWindow::setProperty( 'MouseWheelBehavior' ): illegal property value!" ); } + + aMouseSettings.SetWheelBehavior( nWheelBehavior ); + aSettings.SetMouseSettings( aMouseSettings ); + pWindow->SetSettings( aSettings, TRUE ); } break; @@ -1672,6 +1702,19 @@ void VCLXWindow::setProperty( const ::rtl::OUString& PropertyName, const ::com:: setEnable( b ); } break; + case BASEPROPERTY_ENABLEVISIBLE: + { + sal_Bool b = sal_False; + if ( Value >>= b ) + { + if( b != mpImpl->isEnableVisible() ) + { + mpImpl->setEnableVisible( b ); + pWindow->Show( b && mpImpl->isDirectVisible() ); + } + } + } + break; case BASEPROPERTY_TEXT: case BASEPROPERTY_LABEL: case BASEPROPERTY_TITLE: @@ -2122,10 +2165,19 @@ void VCLXWindow::setProperty( const ::rtl::OUString& PropertyName, const ::com:: aProp <<= mpImpl->mnWritingMode; break; - case BASEPROPERTY_WHEELWITHOUTFOCUS: + case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR: { - sal_Bool bWheelOnHover = !GetWindow()->GetSettings().GetMouseSettings().GetNoWheelActionWithoutFocus(); - aProp <<= bWheelOnHover; + USHORT nVclBehavior = GetWindow()->GetSettings().GetMouseSettings().GetWheelBehavior(); + sal_Int16 nBehavior = MouseWheelBehavior::SCROLL_FOCUS_ONLY; + switch ( nVclBehavior ) + { + case MOUSE_WHEEL_DISABLE: nBehavior = MouseWheelBehavior::SCROLL_DISABLED; break; + case MOUSE_WHEEL_FOCUS_ONLY: nBehavior = MouseWheelBehavior::SCROLL_FOCUS_ONLY; break; + case MOUSE_WHEEL_ALWAYS: nBehavior = MouseWheelBehavior::SCROLL_ALWAYS; break; + default: + OSL_ENSURE( false, "VCLXWindow::getProperty( 'MouseWheelBehavior' ): illegal VCL value!" ); + } + aProp <<= nBehavior; } break; @@ -2137,6 +2189,10 @@ void VCLXWindow::setProperty( const ::rtl::OUString& PropertyName, const ::com:: aProp <<= (sal_Bool) GetWindow()->IsEnabled(); break; + case BASEPROPERTY_ENABLEVISIBLE: + aProp <<= (sal_Bool) mpImpl->isEnableVisible(); + break; + case BASEPROPERTY_TEXT: case BASEPROPERTY_LABEL: case BASEPROPERTY_TITLE: @@ -2411,7 +2467,7 @@ void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno: if ( !pWindow ) return; - if ( pWindow ) + if ( isDesignMode() || mpImpl->isEnableVisible() ) { TabPage* pTabPage = dynamic_cast< TabPage* >( pWindow ); if ( pTabPage ) @@ -2481,7 +2537,7 @@ void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno: vcl::PDFExtOutDevData* pPDFExport = dynamic_cast<vcl::PDFExtOutDevData*>(pDev->GetExtOutDevData()); bool bDrawSimple = ( pDev->GetOutDevType() == OUTDEV_PRINTER ) || ( pDev->GetOutDevViewType() == OUTDEV_VIEWTYPE_PRINTPREVIEW ) - || ( pPDFExport && ! pPDFExport->GetIsExportFormFields() ); + || ( pPDFExport != NULL ); if ( bDrawSimple ) { pWindow->Draw( pDev, aP, aSz, WINDOW_DRAW_NOCONTROLS ); diff --git a/toolkit/source/awt/vclxwindows.cxx b/toolkit/source/awt/vclxwindows.cxx index 59cb9632b7e1..b49fa1a621d6 100644 --- a/toolkit/source/awt/vclxwindows.cxx +++ b/toolkit/source/awt/vclxwindows.cxx @@ -386,6 +386,7 @@ void VCLXButton::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DEFAULTBUTTON, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_GRAPHIC, BASEPROPERTY_HELPTEXT, @@ -668,6 +669,7 @@ void VCLXImageControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_BORDERCOLOR, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_GRAPHIC, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -796,6 +798,7 @@ void VCLXCheckBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) PushPropertyIds( rIds, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_GRAPHIC, BASEPROPERTY_HELPTEXT, @@ -1095,6 +1098,7 @@ void VCLXRadioButton::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) PushPropertyIds( rIds, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_GRAPHIC, BASEPROPERTY_HELPTEXT, @@ -1380,6 +1384,9 @@ void VCLXRadioButton::ImplClickedOrToggled( BOOL bToggled ) // ---------------------------------------------------- void VCLXSpinField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) { + PushPropertyIds( rIds, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, + 0 ); VCLXEdit::ImplGetPropertyIds( rIds ); } @@ -1519,6 +1526,7 @@ void VCLXListBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_DROPDOWN, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -1532,6 +1540,7 @@ void VCLXListBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_ALIGN, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXWindow::ImplGetPropertyIds( rIds ); } @@ -2709,6 +2718,7 @@ void VCLXFixedHyperlink::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_BORDERCOLOR, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -2737,6 +2747,7 @@ void VCLXFixedText::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_BORDERCOLOR, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -2879,6 +2890,7 @@ void VCLXScrollBar::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_BORDERCOLOR, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, BASEPROPERTY_LINEINCREMENT, @@ -3358,6 +3370,7 @@ void VCLXEdit::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ECHOCHAR, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HARDLINEBREAKS, BASEPROPERTY_HELPTEXT, @@ -3734,6 +3747,7 @@ void VCLXComboBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_DROPDOWN, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -3748,6 +3762,7 @@ void VCLXComboBox::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_ALIGN, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); // no, don't call VCLXEdit here - it has properties which we do *not* want to have at at combo box // #i92690# / 2008-08-12 / frank.schoenheit@sun.com @@ -4250,6 +4265,7 @@ void VCLXDateField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_DROPDOWN, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_EXTDATEFORMAT, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, @@ -4266,6 +4282,7 @@ void VCLXDateField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_HIDEINACTIVESELECTION, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); } @@ -4586,6 +4603,7 @@ void VCLXTimeField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_BORDERCOLOR, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_EXTTIMEFORMAT, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, @@ -4605,6 +4623,7 @@ void VCLXTimeField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_HIDEINACTIVESELECTION, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); } @@ -4887,6 +4906,7 @@ void VCLXNumericField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DECIMALACCURACY, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -4906,6 +4926,7 @@ void VCLXNumericField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_HIDEINACTIVESELECTION, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); } @@ -5227,6 +5248,7 @@ void VCLXMetricField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DECIMALACCURACY, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -5244,6 +5266,7 @@ void VCLXMetricField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_CUSTOMUNITTEXT, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); } @@ -5477,6 +5500,7 @@ void VCLXCurrencyField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DECIMALACCURACY, BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -5496,6 +5520,7 @@ void VCLXCurrencyField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_HIDEINACTIVESELECTION, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); } @@ -5828,6 +5853,7 @@ void VCLXPatternField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_DEFAULTCONTROL, BASEPROPERTY_EDITMASK, BASEPROPERTY_ENABLED, + BASEPROPERTY_ENABLEVISIBLE, BASEPROPERTY_FONTDESCRIPTOR, BASEPROPERTY_HELPTEXT, BASEPROPERTY_HELPURL, @@ -5841,6 +5867,7 @@ void VCLXPatternField::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) BASEPROPERTY_HIDEINACTIVESELECTION, BASEPROPERTY_WRITING_MODE, BASEPROPERTY_CONTEXT_WRITING_MODE, + BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR, 0); VCLXFormattedSpinField::ImplGetPropertyIds( rIds ); } diff --git a/toolkit/source/controls/formattedcontrol.cxx b/toolkit/source/controls/formattedcontrol.cxx index 19fb4c3609d0..6171067f1185 100644 --- a/toolkit/source/controls/formattedcontrol.cxx +++ b/toolkit/source/controls/formattedcontrol.cxx @@ -142,6 +142,7 @@ namespace toolkit ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MAX ); ImplRegisterProperty( BASEPROPERTY_EFFECTIVE_MIN ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); ImplRegisterProperty( BASEPROPERTY_FORMATKEY ); ImplRegisterProperty( BASEPROPERTY_FORMATSSUPPLIER ); @@ -161,6 +162,7 @@ namespace toolkit ImplRegisterProperty( BASEPROPERTY_ENFORCE_FORMAT ); ImplRegisterProperty( BASEPROPERTY_WRITING_MODE ); ImplRegisterProperty( BASEPROPERTY_CONTEXT_WRITING_MODE ); + ImplRegisterProperty( BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR ); Any aTreatAsNumber; aTreatAsNumber <<= (sal_Bool) sal_True; diff --git a/toolkit/source/controls/tkspinbutton.cxx b/toolkit/source/controls/tkspinbutton.cxx index 5c4e47e240dc..138b849a190c 100644 --- a/toolkit/source/controls/tkspinbutton.cxx +++ b/toolkit/source/controls/tkspinbutton.cxx @@ -60,6 +60,7 @@ namespace toolkit ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); ImplRegisterProperty( BASEPROPERTY_ORIENTATION ); diff --git a/toolkit/source/controls/tree/treecontrol.cxx b/toolkit/source/controls/tree/treecontrol.cxx index 68c3212f5692..2949954bb13c 100644 --- a/toolkit/source/controls/tree/treecontrol.cxx +++ b/toolkit/source/controls/tree/treecontrol.cxx @@ -65,6 +65,7 @@ UnoTreeModel::UnoTreeModel() ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); diff --git a/toolkit/source/controls/unocontrol.cxx b/toolkit/source/controls/unocontrol.cxx index 92c27e33ead0..0775b6ee74f3 100644 --- a/toolkit/source/controls/unocontrol.cxx +++ b/toolkit/source/controls/unocontrol.cxx @@ -1049,7 +1049,13 @@ void UnoControl::draw( sal_Int32 x, sal_Int32 y ) throw(RuntimeException) } if ( xDrawPeerView.is() ) + { + Reference< XVclWindowPeer > xWindowPeer; + xWindowPeer.set( xDrawPeer, UNO_QUERY ); + if ( xWindowPeer.is() ) + xWindowPeer->setDesignMode( mbDesignMode ); xDrawPeerView->draw( x, y ); + } if ( bDisposeDrawPeer ) xDrawPeer->dispose(); @@ -1420,7 +1426,6 @@ void UnoControl::setDesignMode( sal_Bool bOn ) throw(RuntimeException) // remember this mbDesignMode = bOn; xWindow = xWindow.query( getPeer() ); - // dispose our current AccessibleContext, if we have one // (changing the design mode implies having a new implementation for this context, // so the old one must be declared DEFUNC) diff --git a/toolkit/source/controls/unocontrolmodel.cxx b/toolkit/source/controls/unocontrolmodel.cxx index 0f54a204a010..cc5faa27eec8 100644 --- a/toolkit/source/controls/unocontrolmodel.cxx +++ b/toolkit/source/controls/unocontrolmodel.cxx @@ -36,6 +36,7 @@ #include <com/sun/star/awt/FontWidth.hpp> #include <com/sun/star/awt/FontWeight.hpp> #include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/awt/MouseWheelBehavior.hpp> #include <com/sun/star/graphic/XGraphicProvider.hpp> #include <com/sun/star/text/WritingMode2.hpp> #include <com/sun/star/io/XMarkableStream.hpp> @@ -294,6 +295,7 @@ void UnoControlModel::ImplPropertyChanged( sal_uInt16 ) case BASEPROPERTY_IMAGEALIGN: aDefault <<= (sal_Int16) 1 /*ImageAlign::TOP*/; break; case BASEPROPERTY_IMAGEPOSITION: aDefault <<= (sal_Int16) 12 /*ImagePosition::Centered*/; break; case BASEPROPERTY_PUSHBUTTONTYPE: aDefault <<= (sal_Int16) 0 /*PushButtonType::STANDARD*/; break; + case BASEPROPERTY_MOUSE_WHEEL_BEHAVIOUR:aDefault <<= (sal_Int16) awt::MouseWheelBehavior::SCROLL_FOCUS_ONLY; break; case BASEPROPERTY_DATEMAX: aDefault <<= (sal_Int32) Date( 31, 12, 2200 ).GetDate(); break; case BASEPROPERTY_DATEMIN: aDefault <<= (sal_Int32) Date( 1, 1, 1900 ).GetDate(); break; @@ -338,13 +340,13 @@ void UnoControlModel::ImplPropertyChanged( sal_uInt16 ) case BASEPROPERTY_HARDLINEBREAKS: case BASEPROPERTY_NOLABEL: aDefault <<= (sal_Bool) sal_False; break; - case BASEPROPERTY_WHEELWITHOUTFOCUS: case BASEPROPERTY_HIDEINACTIVESELECTION: case BASEPROPERTY_ENFORCE_FORMAT: case BASEPROPERTY_AUTOCOMPLETE: case BASEPROPERTY_SCALEIMAGE: case BASEPROPERTY_ENABLED: case BASEPROPERTY_PRINTABLE: + case BASEPROPERTY_ENABLEVISIBLE: case BASEPROPERTY_DECORATION: aDefault <<= (sal_Bool) sal_True; break; case BASEPROPERTY_HELPTEXT: diff --git a/toolkit/source/controls/unocontrols.cxx b/toolkit/source/controls/unocontrols.cxx index 771a69c532b9..3abacef7b67f 100644 --- a/toolkit/source/controls/unocontrols.cxx +++ b/toolkit/source/controls/unocontrols.cxx @@ -481,6 +481,7 @@ UnoControlFileControlModel::UnoControlFileControlModel() ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); @@ -1778,6 +1779,7 @@ UnoControlGroupBoxModel::UnoControlGroupBoxModel() { ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); @@ -3594,6 +3596,7 @@ UnoControlProgressBarModel::UnoControlProgressBarModel() ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); @@ -3723,6 +3726,7 @@ UnoControlFixedLineModel::UnoControlFixedLineModel() ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); ImplRegisterProperty( BASEPROPERTY_ENABLED ); + ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); ImplRegisterProperty( BASEPROPERTY_HELPURL ); diff --git a/toolkit/source/helper/property.cxx b/toolkit/source/helper/property.cxx index bace3ff94771..0560afbd835f 100644 --- a/toolkit/source/helper/property.cxx +++ b/toolkit/source/helper/property.cxx @@ -257,7 +257,7 @@ ImplPropertyInfo* ImplGetPropertyInfos( sal_uInt16& rElementCount ) DECL_PROP_2 ( "Complete", COMPLETE, sal_Bool, BOUND, MAYBEDEFAULT ), DECL_PROP_2 ( "CurrentItemID", CURRENTITEMID, sal_Int16, BOUND, MAYBEDEFAULT ), - DECL_PROP_2 ( "WheelWithoutFocus", WHEELWITHOUTFOCUS, sal_Bool, BOUND, MAYBEDEFAULT ), + DECL_PROP_2 ( "MouseWheelBehavior", MOUSE_WHEEL_BEHAVIOUR, sal_Int16, BOUND, MAYBEDEFAULT ), DECL_PROP_2 ( "StepTime", STEP_TIME, sal_Int32, BOUND, MAYBEDEFAULT ), DECL_PROP_2 ( "Decoration", DECORATION, sal_Bool, BOUND, MAYBEDEFAULT ), @@ -272,7 +272,8 @@ ImplPropertyInfo* ImplGetPropertyInfos( sal_uInt16& rElementCount ) DECL_PROP_2 ( "DialogSourceURL", DIALOGSOURCEURL, ::rtl::OUString, BOUND, MAYBEDEFAULT ), DECL_PROP_2 ( "URL", URL, ::rtl::OUString, BOUND, MAYBEDEFAULT ), DECL_PROP_2 ( "WritingMode", WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT ), - DECL_PROP_3 ( "ContextWritingMode", CONTEXT_WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT, TRANSIENT ) + DECL_PROP_3 ( "ContextWritingMode", CONTEXT_WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT, TRANSIENT ), + DECL_PROP_2 ( "EnableVisible", ENABLEVISIBLE, sal_Bool, BOUND, MAYBEDEFAULT ) }; pPropertyInfos = aImplPropertyInfos; nElements = sizeof( aImplPropertyInfos ) / sizeof( ImplPropertyInfo ); diff --git a/toolkit/source/helper/vclunohelper.cxx b/toolkit/source/helper/vclunohelper.cxx index d76b56a6a37d..029e520baca6 100644 --- a/toolkit/source/helper/vclunohelper.cxx +++ b/toolkit/source/helper/vclunohelper.cxx @@ -736,4 +736,12 @@ com::sun::star::awt::Point VCLUnoHelper::ConvertToAWTPoint(::Point /* VCLPoint * return aAWTPoint; } +::Rectangle VCLUnoHelper::ConvertToVCLRect( ::com::sun::star::awt::Rectangle const & _rRect ) +{ + return ::Rectangle( _rRect.X, _rRect.Y, _rRect.X + _rRect.Width - 1, _rRect.Y + _rRect.Height - 1 ); +} +::com::sun::star::awt::Rectangle VCLUnoHelper::ConvertToAWTRect( ::Rectangle const & _rRect ) +{ + return ::com::sun::star::awt::Rectangle( _rRect.Left(), _rRect.Top(), _rRect.GetWidth(), _rRect.GetHeight() ); +} diff --git a/tools/bootstrp/makefile.mk b/tools/bootstrp/makefile.mk index d0adff1278e4..60bfc57bf96b 100644 --- a/tools/bootstrp/makefile.mk +++ b/tools/bootstrp/makefile.mk @@ -81,18 +81,20 @@ LIB2OBJFILES=\ APP1TARGET= sspretty APP1OBJS= $(OBJ)$/sspretty.obj APP1LIBS= $(LB)$/$(TARGET).lib $(LB)$/$(TARGET1).lib -APP1STDLIBS=$(SALLIB) $(VOSLIB) $(TOOLSLIB) +APP1STDLIBS=$(SALLIB) $(VOSLIB) $(TOOLSLIB) $(BASEGFXLIB) $(UCBHELPERLIB) $(CPPULIB) $(COMPHELPERLIB) $(CPPUHELPERLIB) $(SALHELPERLIB) $(I18NISOLANGLIB) APP2TARGET= rscdep APP2OBJS= $(OBJ)$/rscdep.obj APP2LIBS= $(LB)$/$(TARGET).lib $(LB)$/$(TARGET1).lib -APP2STDLIBS= $(SALLIB) $(VOSLIB) $(TOOLSLIB) +APP2STDLIBS= $(SALLIB) $(VOSLIB) $(TOOLSLIB) $(BASEGFXLIB) $(UCBHELPERLIB) $(CPPULIB) $(COMPHELPERLIB) $(I18NISOLANGLIB) $(CPPUHELPERLIB) $(SALHELPERLIB) +APP2RPATH= NONE +APP2RPATH= NONE APP2RPATH= NONE APP3TARGET= so_checksum APP3OBJS= $(OBJ)$/md5.obj \ $(OBJ)$/so_checksum.obj -APP3STDLIBS= $(TOOLSLIB) $(SALLIB) +APP3STDLIBS= $(TOOLSLIB) $(SALLIB) $(VOSLIB) $(BASEGFXLIB) $(UCBHELPERLIB) $(CPPULIB) $(COMPHELPERLIB) $(I18NISOLANGLIB) $(CPPUHELPERLIB) $(SALHELPERLIB) DEPOBJFILES = $(APP1OBJS) $(APP2OBJS) $(APP3OBJS) diff --git a/tools/bootstrp/md5.cxx b/tools/bootstrp/md5.cxx index bca89725fac2..a234f278cc9d 100644 --- a/tools/bootstrp/md5.cxx +++ b/tools/bootstrp/md5.cxx @@ -44,8 +44,62 @@ #define FILE_OPEN_READ "r" #endif +// Extended calc_md5_checksum to recognize Windows executables and libraries. To +// create the same md5 checksum for a (code/data) identical file it ignores a different +// date and header checksum. Please see crashrep/source/win32/soreport.cpp +// where the same method is also used. The crash reporter uses the MD5 +// checksums to transfer them to the crash database. You have to make sure that both +// methods use the same algorithm otherwise there could be problems with stack reports. + +void normalize_pe_image(sal_uInt8* buffer, size_t nBufferSize) +{ + const int OFFSET_PE_OFFSET = 0x3c; + const int OFFSET_COFF_TIMEDATESTAMP = 4; + const int PE_SIGNATURE_SIZE = 4; + const int COFFHEADER_SIZE = 20; + const int OFFSET_PE_OPTIONALHEADER_CHECKSUM = 64; + + // Check the header part of the file buffer + if (buffer[0] == sal_uInt8('M') && buffer[1] == sal_uInt8('Z')) + { + unsigned long PEHeaderOffset = (long)buffer[OFFSET_PE_OFFSET]; + if (PEHeaderOffset < nBufferSize-4) + { + if ( buffer[PEHeaderOffset+0] == sal_uInt8('P') && + buffer[PEHeaderOffset+1] == sal_uInt8('E') && + buffer[PEHeaderOffset+2] == 0 && + buffer[PEHeaderOffset+3] == 0 ) + { + PEHeaderOffset += PE_SIGNATURE_SIZE; + if (PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP < nBufferSize-4) + { + // Set timedatestamp and checksum fields to a normalized + // value to enforce the same MD5 checksum for identical + // Windows executables/libraries. + buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+0] = 0; + buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+1] = 0; + buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+2] = 0; + buffer[PEHeaderOffset+OFFSET_COFF_TIMEDATESTAMP+3] = 0; + } + + if (PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM < nBufferSize-4) + { + // Set checksum to a normalized value + buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM] = 0; + buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+1] = 0; + buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+2] = 0; + buffer[PEHeaderOffset+COFFHEADER_SIZE+OFFSET_PE_OPTIONALHEADER_CHECKSUM+3] = 0; + } + } + } + } +} + rtlDigestError calc_md5_checksum( const char *filename, ByteString &aChecksum ) { + const size_t BUFFER_SIZE = 0x1000; + const size_t MINIMAL_SIZE = 512; + sal_uInt8 checksum[RTL_DIGEST_LENGTH_MD5]; rtlDigestError error = rtl_Digest_E_None; @@ -58,11 +112,19 @@ rtlDigestError calc_md5_checksum( const char *filename, ByteString &aChecksum ) if ( digest ) { size_t nBytesRead; - sal_uInt8 buffer[0x1000]; + sal_uInt8 buffer[BUFFER_SIZE]; + bool bHeader(true); while ( rtl_Digest_E_None == error && 0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) ) { + if (bHeader) + { + bHeader = false; + if (nBytesRead >= MINIMAL_SIZE && buffer[0] == sal_uInt8('M') && buffer[1] == sal_uInt8('Z') ) + normalize_pe_image(buffer, nBytesRead); + } + error = rtl_digest_updateMD5( digest, buffer, nBytesRead ); } diff --git a/tools/source/fsys/urlobj.cxx b/tools/source/fsys/urlobj.cxx index e3484aee4e2d..2aff0d734bf6 100644 --- a/tools/source/fsys/urlobj.cxx +++ b/tools/source/fsys/urlobj.cxx @@ -1523,8 +1523,15 @@ bool INetURLObject::convertRelToAbs(rtl::OUString const & rTheRelURIRef, else if (pEnd - q >= 2 && q[0] == '\\' && q[1] == '\\') { q += 2; - if (scanDomain(q, pEnd) > 0 && (q == pEnd || *q == '\\')) + sal_Int32 n = rtl_ustr_indexOfChar_WithLength( + q, pEnd - q, '\\'); + sal_Unicode const * qe = n == -1 ? pEnd : q + n; + if (parseHostOrNetBiosName( + q, qe, bOctets, ENCODE_ALL, RTL_TEXTENCODING_DONTKNOW, + true, NULL)) + { bFSys = true; // 1st + } } if (bFSys) { diff --git a/tools/workben/urltest.cxx b/tools/workben/urltest.cxx index 542297eb4bd6..a232f8ebdd93 100644 --- a/tools/workben/urltest.cxx +++ b/tools/workben/urltest.cxx @@ -799,6 +799,25 @@ main() bSuccess = false; } } + { + bool bWasAbsolute; + if (!rtl::OUString(INetURLObject(rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "file:///"))). + smartRel2Abs( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( + "\\\\unc_host\\path")), + bWasAbsolute). + GetMainURL(INetURLObject::NO_DECODE)). + equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("file://unc_host/path")) + || !bWasAbsolute) + { + printf("BAD smartRel2Abs(\"\\\\unc_host\\path\")\n"); + bSuccess = false; + } + } } if (true) diff --git a/transex3/inc/export.hxx b/transex3/inc/export.hxx index 89c1cf548947..3d7eee8e1eaf 100644 --- a/transex3/inc/export.hxx +++ b/transex3/inc/export.hxx @@ -510,7 +510,9 @@ private: SvFileStream aErrLog; ByteStringSet aLanguageSet; MergeDataHashMap aMap; - std::vector<ByteString> aLanguages; + ByteStringHashMap aLanguageMap; + std::vector<ByteString> aLanguageList; + ByteStringHashMap aFilenames; public: diff --git a/transex3/prj/d.lst b/transex3/prj/d.lst index 7bd8e7d3e72d..54d1ab156205 100644 --- a/transex3/prj/d.lst +++ b/transex3/prj/d.lst @@ -28,6 +28,7 @@ mkdir: %_DEST%\inc%_EXT%\transex3 ..\scripts\localize.pl %_DEST%\bin%_EXT%\localize.pl ..\scripts\localize %_DEST%\bin%_EXT%\localize +..\scripts\fast_merge.pl %_DEST%\bin%_EXT%\fast_merge.pl ..\inc\export.hxx %_DEST%\inc%_EXT%\transex3\export.hxx ..\inc\transex3\directory.hxx %_DEST%\inc%_EXT%\transex3\directory.hxx diff --git a/transex3/scripts/fast_merge.pl b/transex3/scripts/fast_merge.pl new file mode 100644 index 000000000000..266c1c0801e8 --- /dev/null +++ b/transex3/scripts/fast_merge.pl @@ -0,0 +1,348 @@ +: +eval 'exec perl -wS $0 ${1+"$@"}' + if 0; +#************************************************************************* +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: fast_merge.pl,v $ +# +# $Revision: 1.1.2.2 $ +# +# last change: $Author: ihi $ $Date: 2007/07/20 10:37:53 $ +# +# The Contents of this file are made available subject to +# the terms of GNU Lesser General Public License Version 2.1. +# +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2005 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library 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 for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +#************************************************************************* + +use strict; +use Class::Struct; +use Getopt::Long; +use File::Temp; +use File::Path; + +my @files; +my @file_names; +my $module_name = ''; +my @current; +my @buffer; +my $last_file; +my $last_path; +my $last_localize_file; +my $first_run = "1"; +my $sdf_filename; +my $merge_dir; +my $WIN; +my $state = "none"; + +if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) { $WIN = 'TRUE'; } +else { $WIN = ''; } + +$SIG{INT} = 'inthandler'; +$SIG{QUIT} = 'quithandler'; + +struct ( sdf_obj => +{ + module => '$', + file => '$', + dir => '$', + FILEHANDLE => '$', + line => '$', + endoffile => '$' +} +); + +parse_options(); +my $lock_file = $merge_dir."/lock.mk"; +$lock_file =~ s/\//\\/g , if ( $WIN ) ; +acquire_lock(); +read_sdf_file_names(); +init(); +my $reference; +my $path ; +my $localize_file; +while( hasLines() ) +{ + @current = (); + foreach ( @files ) + { + push @current , $_; + } + + $reference = getNextIdentifier( ); + + @current = (); + foreach ( @files ) + { + if( $_->module eq $reference->module && $_->dir eq $reference->dir ) + { + push @current , $_ ; + } + } + write_lines(); +} +if( $#current+1 ne 0 ) +{ + ( $path , $localize_file ) = make_paths(); + add_to_buffer(); + write_buffer( $path , $localize_file ); +} +release_lock(); +exit( 0 ); + +########################################################################################## +sub acquire_lock +{ + if( -e $lock_file ){ + $state = "blocked"; + print "WARNING: Lock file '$lock_file' 'found, waiting ....\n"; + my $cnt = 0; + sleep 10 , while( -e $lock_file && $cnt++ < 180 ); + exit( 0 ); + }else + { + $state = "locked"; + print "Writing lock file '$lock_file'\n"; + open FILE, ">$lock_file" or die "Can't create lock file '$lock_file'"; + print FILE "L10N_LOCK=YES" ; + close ( FILE ); + } +} +sub release_lock +{ + print "Deleting lock file '$lock_file'\n"; + unlink $lock_file, if( -e $lock_file ); + $state = "none"; +} +sub inthandler +{ + release_lock() , if( $state eq "locked" ); + exit( -1 ); +} +sub quithandler +{ + release_lock() , if( $state eq "locked" ); + exit( 0 ); +} + +sub init +{ + foreach my $file ( @file_names ) + { + my $obj = new sdf_obj; + open my $FILEHANDLE , "<$file" or die "Can't open file '$file'"; + $obj->FILEHANDLE ( $FILEHANDLE ) ; + getNextSdfObj( $obj ); + push @files, $obj ; + print "Open file '$file'\n"; + } +} + +# get the next module/file +sub getNextIdentifier +{ + my @sorted = sort { + return $a->module.$a->dir cmp $b->module.$b->dir; + } @current ; + return shift @sorted; +} + +# update the obj with the next line +sub getNextSdfObj +{ + my $obj = shift; + my $line = readline ( $obj->FILEHANDLE ); + if ( $line eq undef ) + { + $obj->endoffile( "true" ); + } + else + { + $line =~ /^(([^\t]*)\t([^\t]*).*)/o ; + if( defined $1 && defined $2 && defined $3 ) + { + $obj->line ( $1 ); + $obj->module( $2 ); + $obj->file ( $3 ); + $obj->dir ( getDir( $3 ) ); + } + else + { + $obj->line ( "" ); + $obj->module( "" ); + $obj->file ( "" ); + $obj->dir ( "" ); + } + } + return $obj; +} +sub getNextSdfObjModule +{ + my $obj = shift; + while( !$obj->endoffile ) + { + my $line = readline ( $obj->FILEHANDLE ); + if ( $line eq undef ) + { + $obj->endoffile( "true" ); + } + else + { + $line =~ /^(([^\t]*)\t([^\t]*).*)/o ; + if( defined $1 && defined $2 && defined $3 ) + { + $obj->line ( $1 ); + $obj->module( $2 ); + $obj->file ( $3 ); + $obj->dir ( getDir( $3 ) ); + } + else + { + $obj->line ( "" ); + $obj->module( "" ); + $obj->file ( "" ); + $obj->dir ( "" ); + } + return $obj , if( $obj->module eq $module_name ) + } + } + #return $obj; +} +sub getDir +{ + my $path = shift ; + $path =~ s/\//\\/g; + my @tmp_path = split /\\/ , $path; + pop @tmp_path; + $path = join '\\' , @tmp_path; + return $path; +} + +sub hasLines +{ + my $hasLines = ""; + my @tmpfiles; + foreach ( @files ) + { + push @tmpfiles , $_, if( !$_->endoffile ); + } + @files = @tmpfiles; + return $#files+1; +} + +sub make_paths +{ + my $localizeFile = $merge_dir."\\".$current[ 0 ]->module."\\".$current[ 0 ]->file; + my $path = getDir( $localizeFile ); + if ( !$WIN ) { $path =~ s/\\/\//g; } + + $localizeFile = $path."\\localize.sdf"; + if ( !$WIN ) { $localizeFile =~ s/\\/\//g; } + + return ( $path , $localizeFile ); +} +sub write_lines +{ + if( $first_run ){ + add_to_buffer(); + my( $path , $localize_file ) = make_paths(); + $last_path = $path; + $last_localize_file = $localize_file; + mkpath $path; + write_buffer( $path , $localize_file ); + $first_run = ''; + } + else + { + return , if ( $#current+1 eq 0 ); + my( $path , $localize_file ) = make_paths(); + if( $path eq $last_path ) + { + add_to_buffer(); + } + else + { + mkpath $path; + write_buffer( $last_path , $last_localize_file ); + add_to_buffer(); + $last_path = $path; + $last_localize_file = $localize_file; + } + } +} +sub add_to_buffer +{ + my $plainline; + my $afile; + my $amodule; + foreach my $elem ( @current ) + { + do { + $amodule=$elem->module; + $afile=$elem->file; + $plainline=$elem->line; + push @buffer, $plainline; + getNextSdfObj( $elem ); + } while ( !$elem->endoffile && $amodule eq $elem->module && $afile eq $elem->file ); + } +} +sub write_buffer +{ + my $path = shift; + my $localize_file = shift; + my $cnt = $#buffer+1; + print "Write to $path $cnt lines\n"; + open FILE , ">>$localize_file" or die "Can't open file '$localize_file'\n"; + foreach ( @buffer ) + { + print FILE $_."\n"; + } + @buffer = (); +} +sub parse_options +{ + my $success = GetOptions( 'sdf_files=s' => \$sdf_filename , 'merge_dir=s' => \$merge_dir ); #, 'module=s' => \$module_name ); + if( ! ( $sdf_filename && $merge_dir && $success ) ) + { + usage(); + exit( -1 ); + } +} + +sub usage +{ + print "Usage: fast_merge -sdf_files <file containing sdf file names> -merge_dir <directory>\n" ; +} + +sub read_sdf_file_names +{ + open FILE , "<$sdf_filename" or die "Can't open file '$sdf_filename'\n"; + while ( <FILE> ) + { + push @file_names , split " " , $_ ; + } + close ( FILE ); +} + + diff --git a/transex3/scripts/localize b/transex3/scripts/localize deleted file mode 100755 index 74a75ecc3aee..000000000000 --- a/transex3/scripts/localize +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -if [ x${SOLARENV}x = xx ]; then - echo No environment found, please use 'setsolar' -exit 1 -fi - -# localize.pl calls localize_sl in solver bin directory which depends on dynamic -# libraries in solver lib directory but has no correct RPATH (or equivalent): -if [ "${OS?}" = MACOSX ]; then - export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH+${DYLD_LIBRARY_PATH}:}${SOLARVERSION?}/${INPATH?}/lib${UPDMINOREXT} -else - export LD_LIBRARY_PATH=${LD_LIBRARY_PATH+${LD_LIBRARY_PATH}:}${SOLARVERSION?}/${INPATH?}/lib${UPDMINOREXT} -fi - -if [ x${SOLARVER}x = xx -o x${UPDMINOR}x = xx ]; then - exec perl -w $SOLARVERSION/$INPATH/bin/localize.pl "$@" -else - exec perl -w $SOLARVERSION/$INPATH/bin.$UPDMINOR/localize.pl "$@" -fi - diff --git a/transex3/scripts/localize.pl b/transex3/scripts/localize.pl index b9e478ba66bd..10e8124027b1 100755 --- a/transex3/scripts/localize.pl +++ b/transex3/scripts/localize.pl @@ -13,7 +13,7 @@ eval 'exec perl -wS $0 ${1+"$@"}' # # $RCSfile: localize.pl,v $ # -# $Revision: 1.18 $ +# $Revision: 1.18.6.2 $ # # This file is part of OpenOffice.org. # @@ -39,10 +39,12 @@ use Getopt::Long; use IO::Handle; use File::Find; use File::Temp; +use File::Path; use File::Copy; use File::Glob qw(:glob csh_glob); use Cwd; +my $CVS_BINARY = "/usr/bin/cvs"; # ver 1.1 # #### module lookup @@ -61,16 +63,24 @@ BEGIN { use lib (@lib_dirs); #### globals #### -my $sdffile = ''; -my $no_sort = ''; -my $outputfile = ''; -my $mode = ''; -my $bVerbose="0"; -my $srcpath = ''; +my $sdffile = ''; +my $no_sort = ''; +my $create_dirs = ''; +my $multi_localize_files = ''; +my $module_to_merge = ''; +my $sort_sdf_before = ''; +my $outputfile = ''; +my $no_gsicheck = ''; +my $mode = ''; +my $bVerbose = "0"; +my $srcpath = ''; my $WIN; my $languages; #my %sl_modules; # Contains all modules where en-US and de is source language my $use_default_date = '0'; +my %is_ooo_module; +my %is_so_module; +my $DELIMITER; # ( leftpart ) ( rightpart ) # prj file dummy type gid lid helpid pform width lang text helptext qhelptext title timestamp @@ -82,21 +92,38 @@ my @sdfparticles; #### main #### parse_options(); +check_modules_scm(); if ( defined $ENV{USE_SHELL} && $ENV{USE_SHELL} eq '4nt' ) { $WIN = 'TRUE'; + $DELIMITER = "\\"; } else { $WIN = ''; + $DELIMITER = "/"; +} + +my $binpath = ''; +if( defined $ENV{UPDMINOREXT} ) +{ + $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$ENV{UPDMINOREXT}.$DELIMITER ; +} +else +{ + $binpath = $ENV{SOLARVER}.$DELIMITER.$ENV{INPATH}.$DELIMITER."bin".$DELIMITER ; } #%sl_modules = fetch_sourcelanguage_dirlist(); if ( $mode eq "merge" ) { - merge_gsicheck(); + if ( ! $no_gsicheck ){ + merge_gsicheck(); + } splitfile( $sdffile ); - unlink $sdffile; # remove temp file! + if ( ! $no_gsicheck ){ + unlink $sdffile; # remove temp file! + } } elsif( $mode eq "extract" ) { collectfiles( $outputfile ); @@ -126,6 +153,12 @@ sub splitfile{ open MYFILE , "< $sdffile" or die "Can't open '$sdffile'\n"; +# my %lang_hash; + my %string_hash_ooo; + my %string_hash_so; + my %so_modules; + $so_modules{ "extras_full" } = "TRUE"; + while( <MYFILE>){ if( /$sdf_regex/ ){ my $line = defined $_ ? $_ : ''; @@ -137,183 +170,187 @@ sub splitfile{ my $lang = defined $12 ? $12 : ''; my $plattform = defined $10 ? $10 : ''; my $helpid = defined $9 ? $9 : ''; - next if( $prj eq "binfilter" ); # Don't merge strings into binfilter module chomp( $line ); - $currentFile = $srcpath . '\\' . $prj . '\\' . $file; - if ( $WIN ) { $currentFile =~ s/\//\\/g; } - else { $currentFile =~ s/\\/\//g; } - - $cur_sdffile = $currentFile; - #if( $cur_sdffile =~ /\.$file_types[\s]*$/ ){ - if( $WIN ) { $cur_sdffile =~ s/\\[^\\]*\.$file_types[\s]*$/\\localize.sdf/; } - else { $cur_sdffile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; } - #} - - # Set default date - if( $line =~ /(.*)\t[^\t\$]*$/ ){ - $line = $1."\t".$default_date; - } - if( $start ){ - $start=''; - $lastFile = $currentFile; # ? - $last_sdffile = $cur_sdffile; - } - - if( $lang eq "en-US" ){} - elsif( $cur_sdffile eq $last_sdffile ) + if( is_openoffice_module( $prj ) ) { - $block{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line ; + $string_hash_ooo { $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line; } else { - writesdf( $lastFile , \%block ); - $lastFile = $currentFile; #? - $last_sdffile = $cur_sdffile; - %block = (); - #if( ! $lang eq "en-US" ) { - $block{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line ; - #} - + $string_hash_so{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line; } - } #else { print STDOUT "splitfile REGEX kaputt\n";} - + } } - writesdf( $lastFile , \%block ); - %block = (); close( MYFILE ); + if( !defined $ENV{SRC_ROOT} ){ + print "Error, no SRC_ROOT in env found.\n"; + exit( -1 ); + } + my $src_root = $ENV{SRC_ROOT}; + #print $WIN eq "TRUE" ? $src_root."\\l10n_so\n" : $src_root."/l10n_so\n"; + my $so_l10n_path = $WIN eq "TRUE" ? $src_root."\\l10n_so\\source" : $src_root."/l10n_so/source"; + my $ooo_l10n_path = $WIN eq "TRUE" ? $src_root."\\l10n\\source" : $src_root."/l10n/source"; + + #print "$so_l10n_path\n"; + #print "$ooo_l10n_path\n"; + + write_sdf( \%string_hash_so , $so_l10n_path ); + write_sdf( \%string_hash_ooo , $ooo_l10n_path ); + } -######################################################### +sub check_modules_scm +{ + #my @ooo_modules; + #my @so_modules; + my $src_path = $ENV{ SRC_ROOT } ; + my $last_dir = getcwd(); + chdir $src_path ; + my @modules = <*/.svn/entries>; + + foreach my $module ( @modules ) + { + #print "$module \n"; + if( open ( FILE , "<$module" ) ) + { + while( <FILE> ) + { -#sub fetch_sourcelanguage_dirlist + my @path = split ( "/" , $module ) ; + + if( /svn.services.openoffice.org/ ) + { + my $mod = $path[ 0 ]; + #push @ooo_modules , $mod; + $is_ooo_module{ $mod } = "true"; + # print "$module -> ooo "; + } + elsif ( /jumbo2.germany.sun.com/ ) + { + my $mod = $path[ 0 ]; + #push @so_modules , $mod; + # print "$module -> so "; + #$so_lookup_hash{ $mod } = "true"; + } + #else + #{ + # print "ERROR: Is $module a SO or OOo module? Can not parese the $module/.svn/entries file ... please check mwsfinnish/merge/splitsdf.pl line 280\n"; + # exit -1; + #} + } + } + } + chdir $last_dir ; + #print "OOO\n"; + #print @ooo_modules; + #print "\nSO\n"; + #print @so_modules; +} + + +#sub parse #{ -# -# my $working_path = getcwd(); -# my %sl_dirlist; -# -# chdir $srcpath; -# my @all_dirs = csh_glob( "*" ); -# -# foreach my $file ( @all_dirs ) -# { -# if( -d $file ) -# { -# my $module = $file; -# $file .= "/prj/l10n"; -# $file =~ s/\//\\/ , if( $WIN ) ; -# -# if( -f $file ) # Test file <module>/prj/l10n -# { -# $sl_dirlist{ $module } = 1; -# if( $bVerbose eq "1" ) { print STDOUT "$module: de and en-US source language detected\n"; } -# } -# } +# my $command = "$CVS_BINARY -d:pserver:anoncvs\@anoncvs.services.openoffice.org:/cvs co -c"; +# my $output = `$command`; +# my $rc = $? << 8; +# if ( $output eq "" || $rc < 0 ){ +# print STDERR "ERROR: Can not fetch cvs alias list, please login to the cvs server and press at the password prompt just return\ncvs -d:pserver:anoncvs\@anoncvs.services.openoffice.org:/cvs login\n"; +# exit ( -1 ); # } +# my @list = split /\n/ , $output ; +# foreach my $string( @list ) +# { # -# chdir $working_path; +# # print "Found '$1'\n" , if( $string =~ /^(\w*)/ && $1 ne "" ); # -# return %sl_dirlist; +# $is_ooo_module{ $1 } = "TRUE", if( $string =~ /^(\w*)/ && $1 ne "" ); +# } +# # foreach my $key( keys( %is_ooo_module ) ) +# #{ +# # print "$key\n"; +# #} #} +sub is_openoffice_module +{ + my $module = shift; + return "TRUE", if defined $is_ooo_module{ $module }; + return ""; +} -#sub has_two_sourcelanguages -#{ -# my $module = shift; -# return defined $sl_modules{ $module } ; -#} -sub writesdf{ - - my $lastFile = shift; - my $blockhash_ref = shift; - my $localizeFile = $lastFile; - my %index=(); - - if( $localizeFile =~ /\.$file_types[\s]*$/ ){ - if( $WIN ) { $localizeFile =~ s/\\[^\\]*\.$file_types[\s]*$/\\localize.sdf/; } - else { $localizeFile =~ s/\/[^\/]*\.$file_types[\s]*$/\/localize.sdf/; } - }else { - print STDERR "Strange filetype found '$localizeFile'\n"; - return; - } - if( $bVerbose ){ print STDOUT "$localizeFile\n"; } - if( open DESTFILE , "< $localizeFile" ){ +sub write_sdf +{ + my $string_hash = shift; + my $l10n_file = shift; - #or die "Can't open/create '\$localizeFile'"; + foreach my $lang( keys( %{ $string_hash } ) ) + { + my @sdf_file; - #### Build hash - while(<DESTFILE>){ - if( /$sdf_regex/ ){ - my $line = defined $_ ? $_ : ''; - my $prj = defined $3 ? $3 : ''; - my $file = defined $4 ? $4 : ''; - my $type = defined $6 ? $6 : ''; - my $gid = defined $7 ? $7 : ''; - my $lid = defined $8 ? $8 : ''; - my $lang = defined $12 ? $12 : ''; - my $plattform = defined $10 ? $10 : ''; - my $helpid = defined $9 ? $9 : ''; + # mkdir!!!! + my $current_l10n_file = $WIN eq "TRUE" ? $l10n_file."\\$lang\\localize.sdf" : $l10n_file."/$lang/localize.sdf"; + print "Writing '$current_l10n_file'\n"; + if( open DESTFILE , "< $current_l10n_file" ){ - chomp( $line ); - $index{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = $line ; - - } #else { print STDOUT "writesdf REGEX kaputt $_\n";} + while(<DESTFILE>){ + if( /$sdf_regex/ ){ + my $line = defined $_ ? $_ : ''; + my $prj = defined $3 ? $3 : ''; + my $file = defined $4 ? $4 : ''; + my $type = defined $6 ? $6 : ''; + my $gid = defined $7 ? $7 : ''; + my $lid = defined $8 ? $8 : ''; + my $lang = defined $12 ? $12 : ''; + my $plattform = defined $10 ? $10 : ''; + my $helpid = defined $9 ? $9 : ''; + chomp( $line ); + if ( defined $string_hash->{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } ) + { + # Changed String! + push @sdf_file , $string_hash->{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } ; + $string_hash->{ $lang }{ "$prj\t$file\t$type\t$gid\t$lid\t$helpid\t$plattform\t$lang" } = undef; + } + else + { + # No new string + push @sdf_file , $line; + } + } + } } close( DESTFILE ); - } - #### Copy new strings - my @mykeys = keys( %{ $blockhash_ref } ); - my $isDirty = "FALSE"; - foreach my $key( @mykeys ){ - if( ! defined $index{ $key } ){ - # Add new entry - $index{ $key } = $blockhash_ref->{ $key} ; - $isDirty = "TRUE"; - }elsif( $index{ $key } ne $blockhash_ref->{ $key } ){ - # Overwrite old entry - $index{ $key } = $blockhash_ref->{ $key }; - $isDirty = "TRUE"; - }else { + #Now just append the enw strings + #FIXME!!! Implement insertion in the correct order + foreach my $key ( keys ( %{ $string_hash->{ $lang } } ) ) + { + push @sdf_file , $string_hash->{ $lang }{ $key } , if ( defined $string_hash->{ $lang }{ $key } ); + #print "WARNING: Not defined = ".$string_hash->{ $lang }{ $key }."\n", if( ! defined $string_hash->{ $lang }{ $key } ); } - } - #### Write file - - if( !$bVerbose ){ print STDOUT "."; } - if( $isDirty eq "TRUE" ){ - if( open DESTFILE , "+> $localizeFile" ){ + # Write the new file + my ( $TMPFILE , $tmpfile ) = File::Temp::tempfile(); + if( open DESTFILE , "+> $tmpfile " ){ print DESTFILE get_license_header(); - @mykeys = sort keys( %index ); - foreach my $key( @mykeys ){ - print DESTFILE ( $index{ $key } , "\n" ); + foreach my $string( @sdf_file ){ + print DESTFILE "$string\n"; } - close DESTFILE; - }else { - print STDOUT "WARNING: File $localizeFile is not writable , try to merge ...\n"; - my ( $TMPFILE , $tmpfile ) = File::Temp::tempfile(); - if( open DESTFILE , "+> $tmpfile " ){ - @mykeys = keys( %index ); - foreach my $key( @mykeys ){ - print DESTFILE ( $index{ $key } , "\n" ); - } - close DESTFILE; - if( move( $localizeFile , $localizeFile.".backup" ) ){ - if( copy( $tmpfile , $localizeFile ) ){ - unlink $localizeFile.".backup"; - } else { print STDERR "Can't open/create '$localizeFile', original file is renamed to $localizeFile.backup\n"; } - } else { print STDERR "Can't open/create '$localizeFile'\n"; } - }else{ - print STDERR "WARNING: Can't open/create '$localizeFile'\n"; - } - unlink $tmpfile; - } - } -# if( $no_sort eq '' ){ -# sort_outfile( $localizeFile ); -# } + close ( DESTFILE ); + if( move( $current_l10n_file , $current_l10n_file.".backup" ) ){ + if( copy( $tmpfile , $current_l10n_file ) ){ + unlink $l10n_file.".backup"; + } else { print STDERR "Can't open/create '$l10n_file', original file is renamed to $l10n_file.backup\n"; } + } else { print STDERR "Can't open/create '$l10n_file'\n"; } + }else{ + print STDERR "WARNING: Can't open/create '$l10n_file'\n"; + } + unlink $tmpfile; + } } +######################################################### + sub get_license_header{ return "#\n". @@ -398,6 +435,41 @@ sub wanted } } +sub add_paths +{ + my $langhash_ref = shift; + my $root_dir = $ENV{ SRC_ROOT }; + my $ooo_l10n_dir = "$root_dir"."$DELIMITER"."l10n"."$DELIMITER"."source"; + my $so_l10n_dir = "$root_dir"."$DELIMITER"."l10n_so"."$DELIMITER"."source"; + + if( -e $ooo_l10n_dir ) + { + foreach my $lang ( keys( %{ $langhash_ref } ) ) + { + my $loc_file = "$ooo_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + if( -e $loc_file ) + { + push @sdfparticles , "$ooo_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + } + else { print "WARNING: $loc_file not found ....\n"; } + } + } + else { die "ERROR: Can not find directory $ooo_l10n_dir!!!" } + if( -e $so_l10n_dir ) + { + foreach my $lang ( keys( %{ $langhash_ref } ) ) + { + my $loc_file = "$so_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + if( -e $loc_file ) + { + push @sdfparticles , "$ooo_l10n_dir"."$DELIMITER"."$lang"."$DELIMITER"."localize.sdf"; + } + else { #print "WARNING: $loc_file not found ....\n"; + } + } + + } +} sub collectfiles{ print STDOUT "### Localize\n"; my $localizehash_ref; @@ -408,14 +480,14 @@ sub collectfiles{ STDOUT->autoflush( 1 ); ### Search sdf particles - print STDOUT "### Searching sdf particles\n"; + #print STDOUT "### Searching sdf particles\n"; my $working_path = getcwd(); - chdir $srcpath; - find ( { wanted => \&wanted , follow => 1 }, getcwd() ); - chdir $working_path; - - my $nFound = $#sdfparticles +1; - print "\n $nFound files found !\n"; + #chdir $srcpath; + #find ( { wanted => \&wanted , follow => 1 }, getcwd() ); + #chdir $working_path; + add_paths( $langhash_ref ); + #my $nFound = $#sdfparticles +1; + #print "\n $nFound files found !\n"; my ( $LOCALIZEPARTICLE , $localizeSDF ) = File::Temp::tempfile(); close( $LOCALIZEPARTICLE ); @@ -425,18 +497,18 @@ sub collectfiles{ my ( $LOCALIZE_LOG , $my_localize_log ) = File::Temp::tempfile(); close( $LOCALIZE_LOG ); - ## Get the localize de,en-US extract + ## Get the localize en-US extract if( $bAll || $bUseLocalize ){ print "### Fetching source language strings\n"; my $command = ""; my $args = ""; if( $ENV{WRAPCMD} ){ - $command = "$ENV{WRAPCMD} localize_sl"; + $command = $ENV{WRAPCMD}.$binpath."localize_sl"; }else{ - $command = "localize_sl"; + $command = $binpath."localize_sl"; } - + print $command; # -e # if ( -x $command ){ if( $command ){ @@ -480,7 +552,8 @@ sub collectfiles{ } ## Get sdf particles - open ALLPARTICLES_MERGED , "+>> $particleSDF_merged" +#***************** + open ALLPARTICLES_MERGED , "+>> $particleSDF_merged" or die "Can't open $particleSDF_merged"; ## Fill fackback hash @@ -542,7 +615,7 @@ sub collectfiles{ } } close ALLPARTICLES_MERGED; - +#*************** # Hash of array my %output; @@ -1040,7 +1113,8 @@ sub parse_options{ my $merge; my $extract; my $success = GetOptions('f=s' => \$sdffile , 'l=s' => \$languages , 's=s' => \$srcpath , 'h' => \$help , 'v' => \$bVerbose , - 'm' => \$merge , 'e' => \$extract , 'x' => \$no_sort , 'd' => \$use_default_date ); + 'm' => \$merge , 'e' => \$extract , 'x' => \$no_sort , 'd' => \$use_default_date , 'c' => \$create_dirs , + 'n' => \$no_gsicheck ); $outputfile = $sdffile; #print STDOUT "DBG: lang = $languages\n"; @@ -1068,13 +1142,16 @@ sub parse_options{ if( $extract ){ $mode = "extract"; } else { $mode = "merge"; } } +#my $multi_localize_files = ''; h +#my $module_to_merge = ''; i +#my $sort_sdf_before = ''; g ######################################################### sub usage{ print STDERR "Usage: localize.pl\n"; print STDERR "Split or collect SDF files\n"; - print STDERR " merge: -m -f <sdffile> -l l1[=f1][,l2[=f2]][...] [ -s <sourceroot> ]\n"; + print STDERR " merge: -m -f <sdffile> -l l1[=f1][,l2[=f2]][...] [ -s <sourceroot> ] [ -c ]\n"; print STDERR " extract: -e -f <outputfile> -l <lang> [ -s <sourceroot> ] [-d]\n"; print STDERR "Options:\n"; print STDERR " -h help\n"; @@ -1085,6 +1162,11 @@ sub usage{ print STDERR " -s <sourceroot> Path to the modules, if no \$SRC_ROOT is set\n"; print STDERR " -l ( all | <isocode> | <isocode>=fallback ) comma seperated languages\n"; print STDERR " -d Use default date in extracted sdf file\n"; + print STDERR " -c Create needed directories\n"; + print STDERR " -g Sort sdf file before mergeing\n"; + print STDERR " -h File with localize.sdf's\n!"; + print STDERR " -n No gsicheck\n"; + print STDERR " -i Module to merge\n"; print STDERR " -v Verbose\n"; print STDERR "\nExample:\n"; print STDERR "\nlocalize -e -l en-US,pt-BR=en-US -f my.sdf\n( Extract en-US and pt-BR with en-US fallback )\n"; diff --git a/transex3/source/localize.cxx b/transex3/source/localize.cxx index 31420cc58eeb..bcd45d7027a4 100644 --- a/transex3/source/localize.cxx +++ b/transex3/source/localize.cxx @@ -283,6 +283,7 @@ void SourceTreeLocalizer::WorkOnFile( const ByteString &rParameter, const ByteString &rIso ) /*****************************************************************************/ { + (void) rIso; // Remove me ;) String sFull( rFileName, RTL_TEXTENCODING_ASCII_US ); DirEntry aEntry( sFull ); ByteString sFileName( aEntry.GetName(), RTL_TEXTENCODING_ASCII_US ); @@ -304,37 +305,43 @@ void SourceTreeLocalizer::WorkOnFile( DirEntry aTemp( Export::GetTempFile()); ByteString sTempFile( aTemp.GetFull(), RTL_TEXTENCODING_ASCII_US ); - ByteString sExecutable( rExecutable ); + ByteString sDel; #if defined(WNT) || defined(OS2) - sExecutable += ".exe"; - String sPath( Export::GetEnv( "PATH" ), RTL_TEXTENCODING_ASCII_US ); + sDel=ByteString("\\"); #else - String sPath( Export::GetEnv( "LD_LIBRARY_PATH" ), RTL_TEXTENCODING_ASCII_US ); + sDel=ByteString("/"); #endif + ByteString sPath1( Export::GetEnv("SOLARVER") ); + ByteString sPath2( Export::GetEnv("INPATH") ); + ByteString sPath3( "bin" ); + ByteString sPath4( Export::GetEnv("UPDMINOREXT") ); + ByteString sExecutable( sPath1 ); + sExecutable += sDel ; + sExecutable += sPath2 ; + sExecutable += sDel; + sExecutable += sPath3 ; + sExecutable += sPath4 ; + sExecutable += sDel ; + sExecutable += rExecutable ; + + + ByteString sCommand( sExecutable ); + sCommand += " "; + sCommand += rParameter; + sCommand += " -p "; + sCommand += sPrj; + sCommand += " -r "; + sCommand += sRoot; + sCommand += " -i "; + sCommand += sFileName; + sCommand += " -o "; + sCommand += sTempFile; + if ( sLanguageRestriction.Len()) { + sCommand += " -l "; + sCommand += getSourceLanguages( sLanguageRestriction , sCommand ); + } - DirEntry aExecutable( String( sExecutable, RTL_TEXTENCODING_ASCII_US )); - aExecutable.Find( sPath ); - - ByteString sCommand( aExecutable.GetFull(), RTL_TEXTENCODING_ASCII_US ); - sCommand += " "; - sCommand += rParameter; - sCommand += " -p "; - sCommand += sPrj; - sCommand += " -r "; - sCommand += sRoot; - sCommand += " -i "; - sCommand += sFileName; - sCommand += " -o "; - sCommand += sTempFile; - if ( sLanguageRestriction.Len()) { - sCommand += " -l "; - sCommand += getSourceLanguages( sLanguageRestriction , sCommand ); - } - if ( rIso.Equals("iso") && sIsoCode99.Len()) { - sCommand += " -ISO99 "; - sCommand += sIsoCode99; - } - if( bQuiet2 ){ + if( bQuiet2 ){ sCommand +=" -QQ "; } //printf("DBG: %s\n",sCommand.GetBuffer()); diff --git a/transex3/source/merge.cxx b/transex3/source/merge.cxx index 3546d7e3accd..ee0f6f459655 100644 --- a/transex3/source/merge.cxx +++ b/transex3/source/merge.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: merge.cxx,v $ - * $Revision: 1.29 $ + * $Revision: 1.27.36.3 $ * * This file is part of OpenOffice.org. * @@ -210,38 +210,39 @@ MergeDataFile::MergeDataFile( const ByteString &rFileName, const ByteString& sFi ByteString sTEXT; ByteString sQHTEXT; ByteString sTITLE; + ByteString sHACK("HACK"); const ByteString sEmpty(""); if( !aInputStream.IsOpen() ) { - printf("ERROR : Can't open %s\n", rFileName.GetBuffer()); - exit( -1 ); + printf("Warning : Can't open %s\n", rFileName.GetBuffer()); + //exit( -1 ); + return; } while ( !aInputStream.IsEof()) { + xub_StrLen nToks; aInputStream.ReadLine( sLine ); sLine = sLine.Convert( RTL_TEXTENCODING_MS_1252, aCharSet ); - if ( sLine.GetTokenCount( '\t' ) == 15 ) { + nToks = sLine.GetTokenCount( '\t' ); + if ( nToks == 15 ) { // Skip all wrong filenames ByteString filename = sLine.GetToken( 1 , '\t' ); filename = filename.Copy( filename.SearchCharBackward( "\\" )+1 , filename.Len() ); if( sFile.Equals( sEmpty ) || ( !sFile.Equals( sEmpty ) && filename.Equals( sFile ) ) ) { - sTYP = sLine.GetToken( 3, '\t' ); - sGID = sLine.GetToken( 4, '\t' ); - sLID = sLine.GetToken( 5, '\t' ); - sPFO = sLine.GetToken( 7, '\t' ); - sPFO = ByteString("HACK"); - nLANG = sLine.GetToken( 9, '\t' ); - - sTEXT = sLine.GetToken( 10, '\t' ); - // printf("%s\n",sTEXT.GetBuffer()); - // Quote( sTEXT ); - // printf("%s\n",sTEXT.GetBuffer()); - - sQHTEXT = sLine.GetToken( 12, '\t' ); - sTITLE = sLine.GetToken( 13, '\t' ); + xub_StrLen rIdx = 0; + sTYP = sLine.GetToken( 3, '\t', rIdx ); + sGID = sLine.GetToken( 0, '\t', rIdx ); // 4 + sLID = sLine.GetToken( 0, '\t', rIdx ); // 5 + sPFO = sLine.GetToken( 1, '\t', rIdx ); // 7 + sPFO = sHACK; + nLANG = sLine.GetToken( 1, '\t', rIdx ); // 9 + sTEXT = sLine.GetToken( 0, '\t', rIdx ); // 10 + + sQHTEXT = sLine.GetToken( 1, '\t', rIdx ); // 12 + sTITLE = sLine.GetToken( 0, '\t', rIdx ); // 13 nLANG.EraseLeadingAndTrailingChars(); @@ -250,20 +251,22 @@ MergeDataFile::MergeDataFile( const ByteString &rFileName, const ByteString& sFi #else if ( !nLANG.EqualsIgnoreCaseAscii("en-US") ){ #endif - InsertEntry( sTYP, sGID, sLID, sPFO, nLANG, sTEXT, sQHTEXT, sTITLE , filename , bCaseSensitive ); - if( nLANG.Len() > 0 ){ - bool bFound = false; - for( unsigned int x = 0; x < aLanguages.size(); x++ ){ - if( aLanguages[ x ].Equals( nLANG ) ) - bFound = true; - } + ByteStringHashMap::const_iterator lit; + lit = aLanguageMap.find (nLANG); + ByteString aLANG; + if (lit == aLanguageMap.end()) { + aLANG = nLANG; + aLanguageMap.insert( ByteStringHashMap::value_type( aLANG, aLANG ) ); // Remember read languages for -l all switch - if( !bFound ) aLanguages.push_back( nLANG ); - } + aLanguageList.push_back( nLANG ); + } else + aLANG = lit->first; + + InsertEntry( sTYP, sGID, sLID, sPFO, aLANG, sTEXT, sQHTEXT, sTITLE , filename , bCaseSensitive ); } } } - else if ( sLine.GetTokenCount( '\t' ) == 10 ){ + else if ( nToks == 10 ) { printf("ERROR: File format is obsolete and no longer supported!\n"); } } @@ -286,7 +289,7 @@ ByteString MergeDataFile::Dump(){ ByteString sRet( "MergeDataFile\n" ); //sRet.Append( Export::DumpMap( "aLanguageSet" , aLanguageSet ) ); - //sRet.Append( Export::DumpMap( "aLanguages" , aLanguages ) ); + //sRet.Append( Export::DumpMap( "aLanguageList" , aLanguageList ) ); printf("MergeDataFile\n"); MergeDataHashMap::const_iterator idbg; for( idbg = aMap.begin() ; idbg != aMap.end(); ++idbg ){ @@ -318,7 +321,7 @@ void MergeDataFile::WriteError( const ByteString &rLine ) fprintf( stderr, "%s\n", rLine.GetBuffer()); } std::vector<ByteString> MergeDataFile::GetLanguages(){ - return aLanguages; + return aLanguageList; } /*****************************************************************************/ @@ -379,23 +382,32 @@ void MergeDataFile::InsertEntry( const ByteString &rLID, const ByteString &rPFO, const ByteString &nLANG, const ByteString &rTEXT, const ByteString &rQHTEXT, const ByteString &rTITLE , - const ByteString &rFilename , bool bCaseSensitive + const ByteString &rInFilename , bool bCaseSensitive ) /*****************************************************************************/ { MergeData *pData; BOOL bFound = FALSE; - // search for MergeData + // uniquify the filename to save memory. + ByteStringHashMap::const_iterator fit = aFilenames.find (rInFilename); + ByteString aFilename; + if (fit == aFilenames.end()) { + aFilename = rInFilename; + aFilenames.insert (ByteStringHashMap::value_type (aFilename, aFilename)); + } else + aFilename = fit->first; - ByteString sKey = CreateKey( rTYP , rGID , rLID , rFilename , bCaseSensitive ); - ByteString sKey2; + // search for MergeData - if( aMap.find( sKey ) != aMap.end() ){ - pData = aMap[ sKey ]; + ByteString sKey = CreateKey( rTYP , rGID , rLID , aFilename , bCaseSensitive ); + MergeDataHashMap::const_iterator mit; + mit = aMap.find( sKey ); + if( mit != aMap.end() ){ + pData = mit->second; }else{ - pData = new MergeData( rTYP, rGID, rLID , rFilename ); - aMap.insert( MergeDataHashMap::value_type( CreateKey( rTYP , rGID , rLID , rFilename , bCaseSensitive ) , pData ) ); + pData = new MergeData( rTYP, rGID, rLID, aFilename ); + aMap.insert( MergeDataHashMap::value_type( sKey, pData ) ); } bFound = FALSE; diff --git a/ucbhelper/prj/build.lst b/ucbhelper/prj/build.lst index fb9e7d7ab45f..3f49d69c987f 100644 --- a/ucbhelper/prj/build.lst +++ b/ucbhelper/prj/build.lst @@ -1,4 +1,4 @@ -uh ucbhelper : offuh sal cppu cppuhelper salhelper NULL +uh ucbhelper : offuh sal cppu cppuhelper salhelper NULL uh ucbhelper usr1 - all uh_mkout NULL uh ucbhelper\inc nmake - all uh_inc NULL uh ucbhelper\source\client nmake - all uh_client uh_inc NULL diff --git a/unotools/inc/unotools/confignode.hxx b/unotools/inc/unotools/confignode.hxx index a50025a6ab50..580274004e1a 100644 --- a/unotools/inc/unotools/confignode.hxx +++ b/unotools/inc/unotools/confignode.hxx @@ -86,7 +86,7 @@ namespace utl const OConfigurationNode& operator=(const OConfigurationNode& _rSource); /// dtor - ~OConfigurationNode(); + ~OConfigurationNode() {} /** open a sub node @param _rPath access path of the to-be-opened sub node. May be a hierarchical path. diff --git a/unotools/source/config/confignode.cxx b/unotools/source/config/confignode.cxx index 56d0b1b06118..4b1b9fe272db 100644 --- a/unotools/source/config/confignode.cxx +++ b/unotools/source/config/confignode.cxx @@ -130,11 +130,6 @@ namespace utl } //------------------------------------------------------------------------ - OConfigurationNode::~OConfigurationNode() - { - } - - //------------------------------------------------------------------------ void OConfigurationNode::_disposing( const EventObject& _rSource ) { Reference< XComponent > xDisposingSource(_rSource.Source, UNO_QUERY); diff --git a/vcl/aqua/inc/salframeview.h b/vcl/aqua/inc/salframeview.h index e969cc8509a1..7fd4d96c4a45 100755 --- a/vcl/aqua/inc/salframeview.h +++ b/vcl/aqua/inc/salframeview.h @@ -108,6 +108,7 @@ -(void)sendMouseEventToFrame:(NSEvent*)pEvent button:(USHORT)nButton eventtype:(USHORT)nEvent; -(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar; -(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod; +-(MacOSBOOL)sendKeyToFrameDirect: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod; -(MacOSBOOL)sendSingleCharacter:(NSEvent*)pEvent; -(MacOSBOOL)handleKeyDownException:(NSEvent*)pEvent; /* diff --git a/vcl/aqua/inc/vclnsapp.h b/vcl/aqua/inc/vclnsapp.h index a5c339c238bd..fc637ff75a31 100755 --- a/vcl/aqua/inc/vclnsapp.h +++ b/vcl/aqua/inc/vclnsapp.h @@ -59,7 +59,6 @@ -(void)scrollbarSettingsChanged: (NSNotification*) pNotification; -(void)addFallbackMenuItem: (NSMenuItem*)pNewItem; -(void)removeFallbackMenuItem: (NSMenuItem*)pOldItem; --(void)getSystemVersionMajor:(unsigned *)major minor:(unsigned *)minor bugFix:(unsigned *)bugFix; -(void)addDockMenuItem: (NSMenuItem*)pNewItem; -(void)applicationWillBecomeActive: (NSNotification *)pNotification; -(void)applicationWillResignActive: (NSNotification *)pNotification; diff --git a/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm b/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm index 53472e6ae34d..e521e7362323 100644 --- a/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ytextattributeswrapper.mm @@ -249,6 +249,8 @@ using namespace ::rtl; // empty } catch ( IndexOutOfBoundsException & e ) { // empty + } catch ( RuntimeException& ) { + // at least don't crash } return string; } diff --git a/vcl/aqua/source/a11y/aqua11yutil.mm b/vcl/aqua/source/a11y/aqua11yutil.mm index 6d12fbee7a91..44f95169ca68 100644 --- a/vcl/aqua/source/a11y/aqua11yutil.mm +++ b/vcl/aqua/source/a11y/aqua11yutil.mm @@ -51,7 +51,7 @@ using namespace ::com::sun::star::awt; +(Point)nsPointToVclPoint:(NSValue *)nsPoint { // VCL coordinates are in upper-left-notation, Cocoa likes it the Cartesian way (lower-left) NSRect screenRect = [ [ NSScreen mainScreen ] frame ]; - return Point ( [ nsPoint pointValue ].x, screenRect.size.height - [ nsPoint pointValue ].y ); + return Point ( static_cast<long>([ nsPoint pointValue ].x), static_cast<long>(screenRect.size.height - [ nsPoint pointValue ].y) ); } @end diff --git a/vcl/aqua/source/a11y/aqua11ywrapper.mm b/vcl/aqua/source/a11y/aqua11ywrapper.mm index d6f99c7020d6..99bcbd20f698 100644 --- a/vcl/aqua/source/a11y/aqua11ywrapper.mm +++ b/vcl/aqua/source/a11y/aqua11ywrapper.mm @@ -728,9 +728,15 @@ static MacOSBOOL isPopupMenuOpen = NO; if ( nativeSubrole != nil && ! [ nativeSubrole isEqualToString: @"" ] ) { [ attributeNames addObject: NSAccessibilitySubroleAttribute ]; } + try + { if ( [ self accessibleContext ] -> getAccessibleChildCount() > 0 ) { [ attributeNames addObject: NSAccessibilityChildrenAttribute ]; } + } + catch( DisposedException& ) {} + catch( RuntimeException& ) {} + if ( title != nil && ! [ title isEqualToString: @"" ] ) { [ attributeNames addObject: NSAccessibilityTitleAttribute ]; } @@ -986,7 +992,7 @@ Reference < XAccessibleContext > hitTestRunner ( Point point, Reference < XAcces } Reference < XAccessibleContext > hitChild; NSRect screenRect = [ [ NSScreen mainScreen ] frame ]; - Point hitPoint ( point.x , screenRect.size.height - point.y ); + Point hitPoint ( static_cast<long>(point.x) , static_cast<long>(screenRect.size.height - point.y) ); // check child windows first NSWindow * window = (NSWindow *) [ self accessibilityAttributeValue: NSAccessibilityWindowAttribute ]; NSArray * childWindows = [ window childWindows ]; diff --git a/vcl/aqua/source/app/saldata.cxx b/vcl/aqua/source/app/saldata.cxx index a70854306122..180f6a106459 100644 --- a/vcl/aqua/source/app/saldata.cxx +++ b/vcl/aqua/source/app/saldata.cxx @@ -93,7 +93,7 @@ SalData::~SalData() } osl_destroyThreadKey( s_aAutoReleaseKey ); - s_aAutoReleaseKey = NULL; + s_aAutoReleaseKey = 0; } if ( mpMainController ) [mpMainController release]; diff --git a/vcl/aqua/source/app/salinst.cxx b/vcl/aqua/source/app/salinst.cxx index b9d66d1e02d3..71bfb7953187 100644 --- a/vcl/aqua/source/app/salinst.cxx +++ b/vcl/aqua/source/app/salinst.cxx @@ -140,10 +140,6 @@ bool AquaSalInstance::isOnCommandLine( const rtl::OUString& rArg ) // returns an NSAutoreleasePool that must be released when the event loop begins static void initNSApp() { - SInt32 major = NULL; - SInt32 minor = NULL; - SInt32 bugFix = NULL; - // create our cocoa NSApplication [VCL_NSApplication sharedApplication]; @@ -176,7 +172,17 @@ static void initNSApp() object: nil ]; // get System Version and store the value in GetSalData()->mnSystemVersion - [NSApp getSystemVersionMajor: (unsigned int *)major minor:(unsigned int *)minor bugFix:(unsigned int *)bugFix ]; + OSErr err = noErr; + SInt32 systemVersion = VER_TIGER; // Initialize with minimal requirement + if( (err = Gestalt(gestaltSystemVersion, &systemVersion)) == noErr ) + { + GetSalData()->mnSystemVersion = systemVersion; +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "System Version %x\n", (unsigned int)systemVersion); +#endif + } + else + NSLog(@"Unable to obtain system version: %ld", (long)err); // Initialize Apple Remote GetSalData()->mpMainController = [[MainController alloc] init]; diff --git a/vcl/aqua/source/app/salsys.cxx b/vcl/aqua/source/app/salsys.cxx index 28acb47ccade..78b5defe6dd9 100644 --- a/vcl/aqua/source/app/salsys.cxx +++ b/vcl/aqua/source/app/salsys.cxx @@ -75,8 +75,8 @@ Rectangle AquaSalSystem::GetDisplayScreenPosSizePixel( unsigned int nScreen ) if( pScreen ) { NSRect aFrame = [pScreen frame]; - aRet = Rectangle( Point( aFrame.origin.x, aFrame.origin.y ), - Size( aFrame.size.width, aFrame.size.height ) ); + aRet = Rectangle( Point( static_cast<long int>(aFrame.origin.x), static_cast<long int>(aFrame.origin.y) ), + Size( static_cast<long int>(aFrame.size.width), static_cast<long int>(aFrame.size.height) ) ); } return aRet; } @@ -94,8 +94,8 @@ Rectangle AquaSalSystem::GetDisplayWorkAreaPosSizePixel( unsigned int nScreen ) if( pScreen ) { NSRect aFrame = [pScreen visibleFrame]; - aRet = Rectangle( Point( aFrame.origin.x, aFrame.origin.y ), - Size( aFrame.size.width, aFrame.size.height ) ); + aRet = Rectangle( Point( static_cast<long int>(aFrame.origin.x), static_cast<long int>(aFrame.origin.y) ), + Size( static_cast<long int>(aFrame.size.width), static_cast<long int>(aFrame.size.height) ) ); } return aRet; } diff --git a/vcl/aqua/source/app/vclnsapp.mm b/vcl/aqua/source/app/vclnsapp.mm index 4ad5e7ff9271..43d44c709c12 100755 --- a/vcl/aqua/source/app/vclnsapp.mm +++ b/vcl/aqua/source/app/vclnsapp.mm @@ -105,44 +105,33 @@ } } - /* #i89611# - Cmd-Option-Space is for some reason not consumed by the menubar, - but also not by the input method (like e.g. Cmd-Space) and stays - without function. - - However MOD1 + MOD2 combinations are not used throughout OOo code - since they tend to clash with system shortcuts on all platforms so - we can skip this case here. - */ // get information whether the event was handled; keyDown returns nothing GetSalData()->maKeyEventAnswer[ pEvent ] = false; bool bHandled = false; - if( nModMask != (NSCommandKeyMask | NSAlternateKeyMask) ) + // dispatch to view directly to avoid the key event being consumed by the menubar + // popup windows do not get the focus, so they don't get these either + // simplest would be dispatch this to the key window always if it is without parent + // however e.g. in document we want the menu shortcut if e.g. the stylist has focus + if( pFrame->mpParent && (pFrame->mnStyle & SAL_FRAME_STYLE_FLOAT) == 0 ) { - // dispatch to view directly to avoid the key event being consumed by the menubar - // popup windows do not get the focus, so they don't get these either - // simplest would be dispatch this to the key window always if it is without parent - // however e.g. in document we want the menu shortcut if e.g. the stylist has focus - if( pFrame->mpParent && (pFrame->mnStyle & SAL_FRAME_STYLE_FLOAT) == 0 ) - { - [[pKeyWin contentView] keyDown: pEvent]; - bHandled = GetSalData()->maKeyEventAnswer[ pEvent ]; - } - - // see whether the main menu consumes this event - // if not, we want to dispatch it ourselves. Unless we do this "trick" - // the main menu just beeps for an unknown or disabled key equivalent - // and swallows the event wholesale - NSMenu* pMainMenu = [NSApp mainMenu]; - if( ! bHandled && (pMainMenu == 0 || ! [pMainMenu performKeyEquivalent: pEvent]) ) - { - [[pKeyWin contentView] keyDown: pEvent]; - bHandled = GetSalData()->maKeyEventAnswer[ pEvent ]; - } - else - bHandled = true; // event handled already or main menu just handled it + [[pKeyWin contentView] keyDown: pEvent]; + bHandled = GetSalData()->maKeyEventAnswer[ pEvent ]; + } + + // see whether the main menu consumes this event + // if not, we want to dispatch it ourselves. Unless we do this "trick" + // the main menu just beeps for an unknown or disabled key equivalent + // and swallows the event wholesale + NSMenu* pMainMenu = [NSApp mainMenu]; + if( ! bHandled && (pMainMenu == 0 || ! [pMainMenu performKeyEquivalent: pEvent]) ) + { + [[pKeyWin contentView] keyDown: pEvent]; + bHandled = GetSalData()->maKeyEventAnswer[ pEvent ]; } + else + bHandled = true; // event handled already or main menu just handled it + GetSalData()->maKeyEventAnswer.erase( pEvent ); if( bHandled ) return; @@ -374,26 +363,6 @@ AquaSalMenu::removeFallbackMenuItem( pItem ); } -- (void)getSystemVersionMajor:(unsigned *)major - minor:(unsigned *)minor - bugFix:(unsigned *)bugFix -{ - OSErr err; - SInt32 systemVersion = VER_TIGER; // Initialize with minimal requirement - if ((err = Gestalt(gestaltSystemVersion, &systemVersion)) == noErr) - { - GetSalData()->mnSystemVersion = systemVersion; -#if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "System Version %x\n", (unsigned int)systemVersion); - fprintf( stderr, "Stored System Version %x\n", (unsigned int)GetSalData()->mnSystemVersion); -#endif - } - else - NSLog(@"Unable to obtain system version: %ld", (long)err); - - return; -} - -(void)addDockMenuItem: (NSMenuItem*)pNewItem { NSMenu* pDock = AquaSalInstance::GetDynamicDockMenu(); diff --git a/vcl/aqua/source/gdi/aquaprintview.mm b/vcl/aqua/source/gdi/aquaprintview.mm index 6099fbaed741..ba139da5f5a4 100755 --- a/vcl/aqua/source/gdi/aquaprintview.mm +++ b/vcl/aqua/source/gdi/aquaprintview.mm @@ -58,6 +58,9 @@ { NSSize aPaperSize = [mpInfoPrinter->getPrintInfo() paperSize]; int nWidth = (int)aPaperSize.width; + // #i101108# sanity check + if( nWidth < 1 ) + nWidth = 1; NSRect aRect = { { page % nWidth, page / nWidth }, aPaperSize }; return aRect; } @@ -71,7 +74,7 @@ -(void)drawRect: (NSRect)rect { NSPoint aPoint = [self locationOfPrintRect: rect]; - mpInfoPrinter->setStartPageOffset( rect.origin.x, rect.origin.y ); + mpInfoPrinter->setStartPageOffset( static_cast<int>(rect.origin.x), static_cast<int>(rect.origin.y) ); NSSize aPaperSize = [mpInfoPrinter->getPrintInfo() paperSize]; int nPage = (int)(aPaperSize.width * rect.origin.y + rect.origin.x); diff --git a/vcl/aqua/source/gdi/salatslayout.cxx b/vcl/aqua/source/gdi/salatslayout.cxx index 98700feba39d..7ecef01cf0d5 100755 --- a/vcl/aqua/source/gdi/salatslayout.cxx +++ b/vcl/aqua/source/gdi/salatslayout.cxx @@ -6,9 +6,6 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: salatslayout.cxx,v $ - * $Revision: 1.12 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -431,8 +428,8 @@ void ATSLayout::DrawText( SalGraphics& rGraphics ) const if( rAquaGraphics.mnATSUIRotation != 0 ) { const double fRadians = rAquaGraphics.mnATSUIRotation * (M_PI/0xB40000); - nXOfsFixed = +rSubPortion.mnXOffset * cos( fRadians ); - nYOfsFixed = +rSubPortion.mnXOffset * sin( fRadians ); + nXOfsFixed = static_cast<Fixed>(static_cast<double>(+rSubPortion.mnXOffset) * cos( fRadians )); + nYOfsFixed = static_cast<Fixed>(static_cast<double>(+rSubPortion.mnXOffset) * sin( fRadians )); } // draw sub-portions @@ -745,6 +742,8 @@ int ATSLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) cons // get a quick overview on what could fit const long nPixelWidth = (nMaxWidth - (nCharExtra * mnCharCount)) / nFactor; + if( nPixelWidth <= 0 ) + return mnMinCharPos; // check assumptions DBG_ASSERT( !mnTrailingSpaceWidth, "ATSLayout::GetTextBreak() with nTSW!=0" ); diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index 3ee54afe2fba..f8410a47dfd6 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -974,6 +974,11 @@ bool AquaSalGraphics::drawPolyLine( const ::basegfx::B2DPolygon& rPolyLine, if( rLineWidths.getX() != rLineWidths.getY() ) return false; + // #i101491# Aqua does not support B2DLINEJOIN_NONE; return false to use + // the fallback (own geometry preparation) + if(basegfx::B2DLINEJOIN_NONE == eLineJoin) + return false; + // setup line attributes CGLineJoin aCGLineJoin = kCGLineJoinMiter; switch( eLineJoin ) { diff --git a/vcl/aqua/source/gdi/salgdiutils.cxx b/vcl/aqua/source/gdi/salgdiutils.cxx index 066268791b11..99a1629006d2 100755 --- a/vcl/aqua/source/gdi/salgdiutils.cxx +++ b/vcl/aqua/source/gdi/salgdiutils.cxx @@ -102,8 +102,8 @@ void AquaSalGraphics::SetVirDevGraphics( CGLayerRef xLayer, CGContextRef xContex else { const CGSize aSize = CGLayerGetSize( mxLayer ); - mnWidth = aSize.width; - mnHeight = aSize.height; + mnWidth = static_cast<int>(aSize.width); + mnHeight = static_cast<int>(aSize.height); } // prepare graphics for drawing @@ -219,7 +219,10 @@ void AquaSalGraphics::RefreshRect(float lX, float lY, float lWidth, float lHeigh { // update a little more around the designated rectangle // this helps with antialiased rendering - const Rectangle aVclRect( Point( lX-1, lY-1 ), Size( lWidth+2, lHeight+2) ); + const Rectangle aVclRect(Point(static_cast<long int>(lX-1), + static_cast<long int>(lY-1) ), + Size( static_cast<long int>(lWidth+2), + static_cast<long int>(lHeight+2) ) ); mpFrame->maInvalidRect.Union( aVclRect ); } } diff --git a/vcl/aqua/source/gdi/salnativewidgets.cxx b/vcl/aqua/source/gdi/salnativewidgets.cxx index 9f2c7c4fa3a7..6cd4e78a2d1a 100644 --- a/vcl/aqua/source/gdi/salnativewidgets.cxx +++ b/vcl/aqua/source/gdi/salnativewidgets.cxx @@ -612,7 +612,7 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, aPushInfo.animation.time.start = 0; aPushInfo.animation.time.current = 0; PushButtonValue* pPBVal = (PushButtonValue*)aValue.getOptionalVal(); - int nPaintHeight = rc.size.height; + int nPaintHeight = static_cast<int>(rc.size.height); if( pPBVal && pPBVal->mbBevelButton ) { @@ -1162,8 +1162,10 @@ BOOL AquaSalGraphics::drawNativeControl(ControlType nType, if( mxClipPath ) aRect = CGPathGetBoundingBox( mxClipPath ); if( aRect.size.width != 0 && aRect.size.height != 0 ) - buttonRect.Intersection( Rectangle( Point( aRect.origin.x, aRect.origin.y ), - Size( aRect.size.width, aRect.size.height ) ) ); + buttonRect.Intersection( Rectangle( Point( static_cast<long int>(aRect.origin.x), + static_cast<long int>(aRect.origin.y) ), + Size( static_cast<long int>(aRect.size.width), + static_cast<long int>(aRect.size.height) ) ) ); } RefreshRect( buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight() ); diff --git a/vcl/aqua/source/gdi/salprn.cxx b/vcl/aqua/source/gdi/salprn.cxx index ef6258829261..b9a1f4ef7748 100644 --- a/vcl/aqua/source/gdi/salprn.cxx +++ b/vcl/aqua/source/gdi/salprn.cxx @@ -127,20 +127,27 @@ void AquaSalInfoPrinter::SetupPrinterGraphics( CGContextRef i_rContext ) const NSRect aImageRect = [mpPrintInfo imageablePageBounds]; if( mePageOrientation == ORIENTATION_PORTRAIT ) { + // move mirrored CTM back into paper double dX = 0, dY = aPaperSize.height; + // move CTM to reflect imageable area dX += aImageRect.origin.x; dY -= aPaperSize.height - aImageRect.size.height - aImageRect.origin.y; CGContextTranslateCTM( i_rContext, dX + mnStartPageOffsetX, dY - mnStartPageOffsetY ); + // scale to be top/down and reflect our "virtual" DPI CGContextScaleCTM( i_rContext, 0.1, -0.1 ); } else { + // move CTM to reflect imageable area + double dX = aImageRect.origin.x, dY = aPaperSize.height - aImageRect.size.height - aImageRect.origin.y; + CGContextTranslateCTM( i_rContext, -dX, -dY ); + // turn by 90 degree CGContextRotateCTM( i_rContext, M_PI/2 ); - double dX = aPaperSize.height, dY = -aPaperSize.width; - dY += aPaperSize.height - aImageRect.size.height - aImageRect.origin.y; - dX -= aImageRect.origin.x; - + // move turned CTM back into paper + dX = aPaperSize.height; + dY = -aPaperSize.width; CGContextTranslateCTM( i_rContext, dX + mnStartPageOffsetY, dY - mnStartPageOffsetX ); + // scale to be top/down and reflect our "virtual" DPI CGContextScaleCTM( i_rContext, -0.1, 0.1 ); } mpGraphics->SetPrinterGraphics( i_rContext, nDPIX, nDPIY, 1.0 ); @@ -187,8 +194,8 @@ static struct PaperSizeEntry { 420, 595, PAPER_A5 }, { 612, 792, PAPER_LETTER }, { 612, 1008, PAPER_LEGAL }, - { 728, 1032, PAPER_B4 }, - { 516, 729, PAPER_B5 }, + { 728, 1032, PAPER_B4_JIS }, + { 516, 729, PAPER_B5_JIS }, { 792, 1224, PAPER_TABLOID } }; @@ -216,8 +223,8 @@ static Paper recognizePaper( double i_fWidth, double i_fHeight ) case 595000842: aPaper = PAPER_A4; break; case 420000595: aPaper = PAPER_A5; break; case 612000792: aPaper = PAPER_LETTER; break; - case 728001032: aPaper = PAPER_B4; break; - case 516000729: aPaper = PAPER_B5; break; + case 728001032: aPaper = PAPER_B4_JIS; break; + case 516000729: aPaper = PAPER_B5_JIS; break; case 612001008: aPaper = PAPER_LEGAL; break; case 792001224: aPaper = PAPER_TABLOID; break; default: @@ -303,8 +310,12 @@ BOOL AquaSalInfoPrinter::SetData( ULONG i_nFlags, ImplJobSetup* io_pSetupData ) double width = 0, height = 0; if( io_pSetupData->mePaperFormat == PAPER_USER ) { - width = TenMuToPt( io_pSetupData->mnPaperWidth ); - height = TenMuToPt( io_pSetupData->mnPaperHeight ); + // #i101108# sanity check + if( io_pSetupData->mnPaperWidth && io_pSetupData->mnPaperHeight ) + { + width = TenMuToPt( io_pSetupData->mnPaperWidth ); + height = TenMuToPt( io_pSetupData->mnPaperHeight ); + } } else getPaperSize( width, height, io_pSetupData->mePaperFormat ); diff --git a/vcl/aqua/source/gdi/salvd.cxx b/vcl/aqua/source/gdi/salvd.cxx index d7690e4e38bd..4d25d5d8b63b 100644 --- a/vcl/aqua/source/gdi/salvd.cxx +++ b/vcl/aqua/source/gdi/salvd.cxx @@ -228,8 +228,8 @@ void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) if( mxLayer ) { const CGSize aSize = CGLayerGetSize( mxLayer ); - rWidth = aSize.width; - rHeight = aSize.height; + rWidth = static_cast<long>(aSize.width); + rHeight = static_cast<long>(aSize.height); } else { diff --git a/vcl/aqua/source/window/salframe.cxx b/vcl/aqua/source/window/salframe.cxx index 560d80fd75d5..9c713ea26a52 100644 --- a/vcl/aqua/source/window/salframe.cxx +++ b/vcl/aqua/source/window/salframe.cxx @@ -520,8 +520,16 @@ void AquaSalFrame::SetClientSize( long nWidth, long nHeight ) void AquaSalFrame::GetClientSize( long& rWidth, long& rHeight ) { - rWidth = mbShown ? maGeometry.nWidth : 0; - rHeight = mbShown ? maGeometry.nHeight : 0; + if( mbShown || mbInitShow ) + { + rWidth = maGeometry.nWidth; + rHeight = maGeometry.nHeight; + } + else + { + rWidth = 0; + rHeight = 0; + } } // ----------------------------------------------------------------------- @@ -1174,7 +1182,7 @@ void AquaSalFrame::UpdateSettings( AllSettings& rSettings ) getAppleScrollBarVariant(); // set scrollbar size - aStyleSettings.SetScrollBarSize( [NSScroller scrollerWidth] ); + aStyleSettings.SetScrollBarSize( static_cast<long int>([NSScroller scrollerWidth]) ); // images in menus false for MacOSX aStyleSettings.SetUseImagesInMenus( false ); @@ -1195,7 +1203,15 @@ const SystemEnvData* AquaSalFrame::GetSystemData() const void AquaSalFrame::Beep( SoundType eSoundType ) { - NSBeep(); + switch( eSoundType ) + { + case SOUND_DISABLE: + // don't beep + break; + default: + NSBeep(); + break; + } } // ----------------------------------------------------------------------- @@ -1232,7 +1248,7 @@ void AquaSalFrame::SetPosSize(long nX, long nY, long nWidth, long nHeight, USHOR if( (nFlags & SAL_FRAME_POSSIZE_WIDTH) != 0 ) nX = mpParent->maGeometry.nWidth - nWidth-1 - nX; else - nX = mpParent->maGeometry.nWidth - aContentRect.size.width-1 - nX; + nX = mpParent->maGeometry.nWidth - static_cast<long int>( aContentRect.size.width-1) - nX; } NSRect aParentFrameRect = [mpParent->mpWindow frame]; aParentContentRect = [NSWindow contentRectForFrameRect: aParentFrameRect styleMask: mpParent->mnStyleMask]; diff --git a/vcl/aqua/source/window/salframeview.mm b/vcl/aqua/source/window/salframeview.mm index 7de43d770385..c7facd8c6c09 100755 --- a/vcl/aqua/source/window/salframeview.mm +++ b/vcl/aqua/source/window/salframeview.mm @@ -841,6 +841,16 @@ private: if( pUnmodifiedString && [pUnmodifiedString length] == 1 ) { + /* #i103102# key events with command and alternate don't make it through + interpretKeyEvents (why ?). Try to dispatch them here first, + if not successful continue normally + */ + if( (mpFrame->mnLastModifierFlags & (NSAlternateKeyMask | NSCommandKeyMask)) + == (NSAlternateKeyMask | NSCommandKeyMask) ) + { + if( [self sendSingleCharacter: mpLastEvent] ) + return YES; + } unichar keyChar = [pUnmodifiedString characterAtIndex: 0]; USHORT nKeyCode = ImplMapCharCode( keyChar ); @@ -1242,12 +1252,18 @@ private: } } --(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar +-(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar { return [self sendKeyInputAndReleaseToFrame: nKeyCode character: aChar modifiers: mpFrame->mnLastModifierFlags]; } --(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod +-(MacOSBOOL)sendKeyInputAndReleaseToFrame: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod +{ + return [self sendKeyToFrameDirect: nKeyCode character: aChar modifiers: nMod] || + [self sendSingleCharacter: mpLastEvent]; +} + +-(MacOSBOOL)sendKeyToFrameDirect: (USHORT)nKeyCode character: (sal_Unicode)aChar modifiers: (unsigned int)nMod { YIELD_GUARD; @@ -1283,7 +1299,7 @@ private: // don't send unicodes in the private use area if( keyChar >= 0xf700 && keyChar < 0xf780 ) keyChar = 0; - MacOSBOOL bRet = [self sendKeyInputAndReleaseToFrame: nKeyCode character: keyChar]; + MacOSBOOL bRet = [self sendKeyToFrameDirect: nKeyCode character: keyChar modifiers: mpFrame->mnLastModifierFlags]; mbInKeyInput = false; return bRet; diff --git a/vcl/aqua/source/window/salmenu.cxx b/vcl/aqua/source/window/salmenu.cxx index 4fafbbdbb4cf..5c838701933c 100644 --- a/vcl/aqua/source/window/salmenu.cxx +++ b/vcl/aqua/source/window/salmenu.cxx @@ -651,11 +651,9 @@ void AquaSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSMI, const Image& r NSImage* pImage = CreateNSImage( rImage ); + [pSalMenuItem->mpMenuItem setImage: pImage]; if( pImage ) - { - [pSalMenuItem->mpMenuItem setImage: pImage]; [pImage release]; - } } void AquaSalMenu::SetItemText( unsigned i_nPos, SalMenuItem* i_pSalMenuItem, const XubString& i_rText ) @@ -894,7 +892,13 @@ Rectangle AquaSalMenu::GetMenuBarButtonRectPixel( USHORT i_nItemId, SalFrame* i_ aRect.origin.x -= i_pReferenceFrame->maGeometry.nX; aRect.origin.y -= i_pReferenceFrame->maGeometry.nY + aRect.size.height; - return Rectangle( Point( aRect.origin.x, aRect.origin.y ), Size( aRect.size.width, aRect.size.height ) ); + return Rectangle( Point(static_cast<long int>(aRect.origin.x), + static_cast<long int>(aRect.origin.y) + ), + Size( static_cast<long int>(aRect.size.width), + static_cast<long int>(aRect.size.height) + ) + ); } // ======================================================================= diff --git a/vcl/inc/sft.h b/vcl/inc/sft.h deleted file mode 100644 index efda0903afc5..000000000000 --- a/vcl/inc/sft.h +++ /dev/null @@ -1,641 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: sft.h,v $ - * $Revision: 1.21 $ - * - * 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. - * - ************************************************************************/ - -/* $Id: sft.h,v 1.21 2008-06-25 14:20:49 kz Exp $ */ - -/** - - * - * @file sft.h - * @brief Sun Font Tools - * @author Alexander Gelfenbain - */ - -/* - * If NO_MAPPERS is defined, MapChar() and MapString() and consequently GetTTSimpleCharMetrics() - * don't get compiled in. This is done to avoid including a large chunk of code (TranslateXY() from - * xlat.c in the projects that don't require it. - * - * If NO_TYPE3 is defined CreateT3FromTTGlyphs() does not get compiled in. - * If NO_TYPE42 is defined Type42-related code is excluded - * If NO_TTCR is defined TrueType creation related code is excluded\ - * If NO_LIST is defined list.h and piblic functions that use it don't get compiled - */ - -/* - * Generated fonts contain an XUID entry in the form of: - * - * 103 0 T C1 N C2 C3 - * - * 103 - Sun's Adobe assigned XUID number. Contact person: Alexander Gelfenbain <gelf@eng.sun.com> - * - * T - font type. 0: Type 3, 1: Type 42 - * C1 - CRC-32 of the entire source TrueType font - * N - number of glyphs in the subset - * C2 - CRC-32 of the array of glyph IDs used to generate the subset - * C3 - CRC-32 of the array of encoding numbers used to generate the subset - * - */ - - -#ifndef __SUBFONT_H -#define __SUBFONT_H - -#ifdef UNX -#include <sys/types.h> -#include <unistd.h> -#endif -#include <stdio.h> - -#include <sal/types.h> - -#ifndef NO_LIST -#include "list.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/*@{*/ -#ifndef __cplusplus -#define false 0 /**< standard false value */ -#define true 1 /**< standard true value */ -#endif -/*@}*/ - -/*@{*/ - typedef sal_Int16 F2Dot14; /**< fixed: 2.14 */ - typedef sal_Int32 F16Dot16; /**< fixed: 16.16 */ -/*@}*/ - - typedef struct { - sal_uInt16 s; - sal_uInt16 d; - } sal_uInt16pair; - -/** Return value of OpenTTFont() and CreateT3FromTTGlyphs() */ - enum SFErrCodes { - SF_OK, /**< no error */ - SF_BADFILE, /**< file not found */ - SF_FILEIO, /**< file I/O error */ - SF_MEMORY, /**< memory allocation error */ - SF_GLYPHNUM, /**< incorrect number of glyphs */ - SF_BADARG, /**< incorrect arguments */ - SF_TTFORMAT, /**< incorrect TrueType font format */ - SF_TABLEFORMAT, /**< incorrect format of a TrueType table */ - SF_FONTNO /**< incorrect logical font number of a TTC font */ - }; - -#ifndef FW_THIN /* WIN32 compilation would conflict */ -/** Value of the weight member of the TTGlobalFontInfo struct */ - enum WeightClass { - FW_THIN = 100, /**< Thin */ - FW_EXTRALIGHT = 200, /**< Extra-light (Ultra-light) */ - FW_LIGHT = 300, /**< Light */ - FW_NORMAL = 400, /**< Normal (Regular) */ - FW_MEDIUM = 500, /**< Medium */ - FW_SEMIBOLD = 600, /**< Semi-bold (Demi-bold) */ - FW_BOLD = 700, /**< Bold */ - FW_EXTRABOLD = 800, /**< Extra-bold (Ultra-bold) */ - FW_BLACK = 900 /**< Black (Heavy) */ - }; - -/** Value of the width member of the TTGlobalFontInfo struct */ -#ifndef OS2 - enum WidthClass { - FWIDTH_ULTRA_CONDENSED = 1, /**< 50% of normal */ - FWIDTH_EXTRA_CONDENSED = 2, /**< 62.5% of normal */ - FWIDTH_CONDENSED = 3, /**< 75% of normal */ - FWIDTH_SEMI_CONDENSED = 4, /**< 87.5% of normal */ - FWIDTH_NORMAL = 5, /**< Medium, 100% */ - FWIDTH_SEMI_EXPANDED = 6, /**< 112.5% of normal */ - FWIDTH_EXPANDED = 7, /**< 125% of normal */ - FWIDTH_EXTRA_EXPANDED = 8, /**< 150% of normal */ - FWIDTH_ULTRA_EXPANDED = 9 /**< 200% of normal */ - }; -#endif // OS2 -#endif /* FW_THIN */ - -/** Type of the 'kern' table, stored in _TrueTypeFont::kerntype */ - enum KernType { - KT_NONE = 0, /**< no kern table */ - KT_APPLE_NEW = 1, /**< new Apple kern table */ - KT_MICROSOFT = 2 /**< Microsoft table */ - }; - -/* Composite glyph flags definition */ - enum CompositeFlags { - ARG_1_AND_2_ARE_WORDS = 1, - ARGS_ARE_XY_VALUES = 1<<1, - ROUND_XY_TO_GRID = 1<<2, - WE_HAVE_A_SCALE = 1<<3, - MORE_COMPONENTS = 1<<5, - WE_HAVE_AN_X_AND_Y_SCALE = 1<<6, - WE_HAVE_A_TWO_BY_TWO = 1<<7, - WE_HAVE_INSTRUCTIONS = 1<<8, - USE_MY_METRICS = 1<<9, - OVERLAP_COMPOUND = 1<<10 - }; - -#ifndef NO_TTCR -/** Flags for TrueType generation */ - enum TTCreationFlags { - TTCF_AutoName = 1, /**< Automatically generate a compact 'name' table. - If this flag is not set, name table is generated - either from an array of NameRecord structs passed as - arguments or if the array is NULL, 'name' table - of the generated TrueType file will be a copy - of the name table of the original file. - If this flag is set the array of NameRecord structs - is ignored and a very compact 'name' table is automatically - generated. */ - - TTCF_IncludeOS2 = 2 /** If this flag is set OS/2 table from the original font will be - copied to the subset */ - }; -#endif - - - - -/** Structure used by GetTTSimpleGlyphMetrics() and GetTTSimpleCharMetrics() functions */ - typedef struct { - sal_uInt16 adv; /**< advance width or height */ - sal_Int16 sb; /**< left or top sidebearing */ - } TTSimpleGlyphMetrics; - - - -/** Structure used by the TrueType Creator and GetRawGlyphData() */ - - typedef struct { - sal_uInt32 glyphID; /**< glyph ID */ - sal_uInt16 nbytes; /**< number of bytes in glyph data */ - sal_uInt8 *ptr; /**< pointer to glyph data */ - sal_uInt16 aw; /**< advance width */ - sal_Int16 lsb; /**< left sidebearing */ - sal_uInt16 compflag; /**< 0- if non-composite, 1- otherwise */ - sal_uInt16 npoints; /**< number of points */ - sal_uInt16 ncontours; /**< number of contours */ - /* */ - sal_uInt32 newID; /**< used internally by the TTCR */ - } GlyphData; - -/** Structure used by the TrueType Creator and CreateTTFromTTGlyphs() */ - typedef struct { - sal_uInt16 platformID; /**< Platform ID */ - sal_uInt16 encodingID; /**< Platform-specific encoding ID */ - sal_uInt16 languageID; /**< Language ID */ - sal_uInt16 nameID; /**< Name ID */ - sal_uInt16 slen; /**< String length in bytes */ - sal_uInt8 *sptr; /**< Pointer to string data (not zero-terminated!) */ - } NameRecord; - - - -/** Return value of GetTTGlobalFontInfo() */ - - typedef struct { - char *family; /**< family name */ - sal_uInt16 *ufamily; /**< family name UCS2 */ - char *subfamily; /**< subfamily name */ - sal_uInt16 *usubfamily; /**< subfamily name UCS2 */ - char *psname; /**< PostScript name */ - sal_uInt16 macStyle; /**< macstyle bits from 'HEAD' table */ - int weight; /**< value of WeightClass or 0 if can't be determined */ - int width; /**< value of WidthClass or 0 if can't be determined */ - int pitch; /**< 0: proportianal font, otherwise: monospaced */ - int italicAngle; /**< in counter-clockwise degrees * 65536 */ - int xMin; /**< global bounding box: xMin */ - int yMin; /**< global bounding box: yMin */ - int xMax; /**< global bounding box: xMax */ - int yMax; /**< global bounding box: yMax */ - int ascender; /**< typographic ascent. */ - int descender; /**< typographic descent. */ - int linegap; /**< typographic line gap.\ Negative values are treated as - zero in Win 3.1, System 6 and System 7. */ - int vascent; /**< typographic ascent for vertical writing mode */ - int vdescent; /**< typographic descent for vertical writing mode */ - int typoAscender; /**< OS/2 portable typographic ascender */ - int typoDescender; /**< OS/2 portable typographic descender */ - int typoLineGap; /**< OS/2 portable typographc line gap */ - int winAscent; /**< ascender metric for Windows */ - int winDescent; /**< descender metric for Windows */ - int symbolEncoded; /**< 1: MS symbol encoded 0: not symbol encoded */ - int rangeFlag; /**< if set to 1 Unicode Range flags are applicable */ - sal_uInt32 ur1; /**< bits 0 - 31 of Unicode Range flags */ - sal_uInt32 ur2; /**< bits 32 - 63 of Unicode Range flags */ - sal_uInt32 ur3; /**< bits 64 - 95 of Unicode Range flags */ - sal_uInt32 ur4; /**< bits 96 - 127 of Unicode Range flags */ - sal_uInt8 panose[10]; /**< PANOSE classification number */ - sal_uInt16 typeFlags; /**< type flags (copyright information) */ - } TTGlobalFontInfo; - -/** Structure used by KernGlyphs() */ - typedef struct { - int x; /**< positive: right, negative: left */ - int y; /**< positive: up, negative: down */ - } KernData; - - -/** ControlPoint structure used by GetTTGlyphPoints() */ - typedef struct { - sal_uInt32 flags; /**< 00000000 00000000 e0000000 bbbbbbbb */ - /**< b - byte flags from the glyf array */ - /**< e == 0 - regular point */ - /**< e == 1 - end contour */ - sal_Int16 x; /**< X coordinate in EmSquare units */ - sal_Int16 y; /**< Y coordinate in EmSquare units */ - } ControlPoint; - - typedef struct _TrueTypeFont TrueTypeFont; - -/** - * @defgroup sft Sun Font Tools Exported Functions - */ - - -/** - * Get the number of fonts contained in a TrueType collection - * @param fname - file name - * @return number of fonts or zero, if file is not a TTC file. - * @ingroup sft - */ - int CountTTCFonts(const char* fname); - - -/** - * TrueTypeFont constructor. - * The font file has to be provided as a memory buffer and length - * @param facenum - logical font number within a TTC file. This value is ignored - * for TrueType fonts - * @return value of SFErrCodes enum - * @ingroup sft - */ - int OpenTTFontBuffer(void* pBuffer, sal_uInt32 nLen, sal_uInt32 facenum, TrueTypeFont** ttf); /*FOLD01*/ -#if !defined(WIN32) && !defined(OS2) -/** - * TrueTypeFont constructor. - * Reads the font file and allocates the memory for the structure. - * on WIN32 the font has to be provided as a memory buffer and length - * @param facenum - logical font number within a TTC file. This value is ignored - * for TrueType fonts - * @return value of SFErrCodes enum - * @ingroup sft - */ - int OpenTTFontFile(const char *fname, sal_uInt32 facenum, TrueTypeFont** ttf); -#endif - -/** - * TrueTypeFont destructor. Deallocates the memory. - * @ingroup sft - */ - void CloseTTFont(TrueTypeFont *); - -/** - * Extracts TrueType control points, and stores them in an allocated array pointed to - * by *pointArray. This function returns the number of extracted points. - * - * @param ttf pointer to the TrueTypeFont structure - * @param glyphID Glyph ID - * @param pointArray Return value - address of the pointer to the first element of the array - * of points allocated by the function - * @return Returns the number of points in *pointArray or -1 if glyphID is - * invalid. - * @ingroup sft - * - */ - int GetTTGlyphPoints(TrueTypeFont *ttf, sal_uInt32 glyphID, ControlPoint **pointArray); - -/** - * Extracts raw glyph data from the 'glyf' table and returns it in an allocated - * GlyphData structure. - * - * @param ttf pointer to the TrueTypeFont structure - * @param glyphID Glyph ID - * - * @return pointer to an allocated GlyphData structure or NULL if - * glyphID is not present in the font - * @ingroup sft - * - */ - GlyphData *GetTTRawGlyphData(TrueTypeFont *ttf, sal_uInt32 glyphID); - -#ifndef NO_LIST -/** - * For a specified glyph adds all component glyphs IDs to the list and - * return their number. If the glyph is a single glyph it has one component - * glyph (which is added to the list) and the function returns 1. - * For a composite glyphs it returns the number of component glyphs - * and adds all of them to the list. - * - * @param ttf pointer to the TrueTypeFont structure - * @param glyphID Glyph ID - * @param glyphlist list of glyphs - * - * @return number of component glyphs - * @ingroup sft - * - */ - int GetTTGlyphComponents(TrueTypeFont *ttf, sal_uInt32 glyphID, list glyphlist); -#endif - -/** - * Extracts all Name Records from the font and stores them in an allocated - * array of NameRecord structs - * - * @param ttf pointer to the TrueTypeFont struct - * @param nr pointer to the array of NameRecord structs - * - * @return number of NameRecord structs - * @ingroup sft - */ - - int GetTTNameRecords(TrueTypeFont *ttf, NameRecord **nr); - -/** - * Deallocates previously allocated array of NameRecords. - * - * @param nr array of NameRecord structs - * @param n number of elements in the array - * - * @ingroup sft - */ - void DisposeNameRecords(NameRecord* nr, int n); - - -#ifndef NO_TYPE3 -/** - * Generates a new PostScript Type 3 font and dumps it to <b>outf</b> file. - * This functions subsititues glyph 0 for all glyphIDs that are not found in the font. - * @param ttf pointer to the TrueTypeFont structure - * @param outf the resulting font is written to this stream - * @param fname font name for the new font. If it is NULL the PostScript name of the - * original font will be used - * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf - * @param encoding array of encoding values. encoding[i] specifies the position of the glyph - * glyphArray[i] in the encoding vector of the resulting Type3 font - * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding - * @param wmode writing mode for the output file: 0 - horizontal, 1 - vertical - * @return return the value of SFErrCodes enum - * @see SFErrCodes - * @ingroup sft - * - */ - int CreateT3FromTTGlyphs(TrueTypeFont *ttf, FILE *outf, const char *fname, sal_uInt16 *glyphArray, sal_uInt8 *encoding, int nGlyphs, int wmode); -#endif - -#ifndef NO_TTCR -/** - * Generates a new TrueType font and dumps it to <b>outf</b> file. - * This functions subsititues glyph 0 for all glyphIDs that are not found in the font. - * @param ttf pointer to the TrueTypeFont structure - * @param fname file name for the output TrueType font file - * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf. The first - * element of this array has to be glyph 0 (default glyph) - * @param encoding array of encoding values. encoding[i] specifies character code for - * the glyphID glyphArray[i]. Character code 0 usually points to a default - * glyph (glyphID 0) - * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding - * @param nNameRecs number of NameRecords for the font, if 0 the name table from the - * original font will be used - * @param nr array of NameRecords - * @param flags or'ed TTCreationFlags - * @return return the value of SFErrCodes enum - * @see SFErrCodes - * @ingroup sft - * - */ - int CreateTTFromTTGlyphs(TrueTypeFont *ttf, - const char *fname, - sal_uInt16 *glyphArray, - sal_uInt8 *encoding, - int nGlyphs, - int nNameRecs, - NameRecord *nr, - sal_uInt32 flags); -#endif - -#ifndef NO_TYPE42 -/** - * Generates a new PostScript Type42 font and dumps it to <b>outf</b> file. - * This functions subsititues glyph 0 for all glyphIDs that are not found in the font. - * @param ttf pointer to the TrueTypeFont structure - * @param outf output stream for a resulting font - * @param psname PostScript name of the resulting font - * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf. The first - * element of this array has to be glyph 0 (default glyph) - * @param encoding array of encoding values. encoding[i] specifies character code for - * the glyphID glyphArray[i]. Character code 0 usually points to a default - * glyph (glyphID 0) - * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding - * @return SF_OK - no errors - * SF_GLYPHNUM - too many glyphs (> 255) - * SF_TTFORMAT - corrupted TrueType fonts - * - * @see SFErrCodes - * @ingroup sft - * - */ - int CreateT42FromTTGlyphs(TrueTypeFont *ttf, - FILE *outf, - const char *psname, - sal_uInt16 *glyphArray, - sal_uInt8 *encoding, - int nGlyphs); -#endif - - -/** - * Queries glyph metrics. Allocates an array of TTSimpleGlyphMetrics structs and returns it. - * - * @param ttf pointer to the TrueTypeFont structure - * @param glyphArray pointer to an array of glyphs that are to be extracted from ttf - * @param nGlyphs number of glyph IDs in glyphArray and encoding values in encoding - * @param mode writing mode: 0 - horizontal, 1 - vertical - * @ingroup sft - * - */ - TTSimpleGlyphMetrics *GetTTSimpleGlyphMetrics(TrueTypeFont *ttf, sal_uInt16 *glyphArray, int nGlyphs, int mode); - -#ifndef NO_MAPPERS -/** - * Queries glyph metrics. Allocates an array of TTSimpleGlyphMetrics structs and returns it. - * This function behaves just like GetTTSimpleGlyphMetrics() but it takes a range of Unicode - * characters instead of an array of glyphs. - * - * @param ttf pointer to the TrueTypeFont structure - * @param firstChar Unicode value of the first character in the range - * @param nChars number of Unicode characters in the range - * @param mode writing mode: 0 - horizontal, 1 - vertical - * - * @see GetTTSimpleGlyphMetrics - * @ingroup sft - * - */ - TTSimpleGlyphMetrics *GetTTSimpleCharMetrics(TrueTypeFont *ttf, sal_uInt16 firstChar, int nChars, int mode); - -/** - * Maps a Unicode (UCS-2) string to a glyph array. Returns the number of glyphs in the array, - * which for TrueType fonts is always the same as the number of input characters. - * - * @param ttf pointer to the TrueTypeFont structure - * @param str pointer to a UCS-2 string - * @param nchars number of characters in <b>str</b> - * @param glyphArray pointer to the glyph array where glyph IDs are to be recorded. - * - * @return MapString() returns -1 if the TrueType font has no usable 'cmap' tables. - * Otherwise it returns the number of characters processed: <b>nChars</b> - * - * glyphIDs of TrueType fonts are 2 byte positive numbers. glyphID of 0 denotes a missing - * glyph and traditionally defaults to an empty square. - * glyphArray should be at least sizeof(sal_uInt16) * nchars bytes long. If glyphArray is NULL - * MapString() replaces the UCS-2 characters in str with glyphIDs. - * @ingroup sft - */ - int MapString(TrueTypeFont *ttf, sal_uInt16 *str, int nchars, sal_uInt16 *glyphArray, int bvertical); - -/** - * Maps a Unicode (UCS-2) character to a glyph ID and returns it. Missing glyph has - * a glyphID of 0 so this function can be used to test if a character is encoded in the font. - * - * @param ttf pointer to the TrueTypeFont structure - * @param ch Unicode (UCS-2) character - * @return glyph ID, if the character is missing in the font, the return value is 0. - * @ingroup sft - */ - sal_uInt16 MapChar(TrueTypeFont *ttf, sal_uInt16 ch, int bvertical); - -/** - * Returns 0 when the font does not substitute vertical glyphs - * - * @param ttf pointer to the TrueTypeFont structure - */ - int DoesVerticalSubstitution( TrueTypeFont *ttf, int bvertical); - -#endif - -/** - * Returns global font information about the TrueType font. - * @see TTGlobalFontInfo - * - * @param ttf pointer to a TrueTypeFont structure - * @param info pointer to a TTGlobalFontInfo structure - * @ingroup sft - * - */ - void GetTTGlobalFontInfo(TrueTypeFont *ttf, TTGlobalFontInfo *info); - -#ifdef TEST5 -/** - * Returns kerning information for an array of glyphs. - * Kerning is not cumulative. - * kern[i] contains kerning information for a pair of glyphs at positions i and i+1 - * - * @param ttf pointer to a TrueTypeFont structure - * @param glyphs array of source glyphs - * @param nglyphs number of glyphs in the array - * @param wmode writing mode: 0 - horizontal, 1 - vertical - * @param kern array of KernData structures. It should contain nglyphs-1 elements - * @see KernData - * @ingroup sft - * - */ - void KernGlyphs(TrueTypeFont *ttf, sal_uInt16 *glyphs, int nglyphs, int wmode, KernData *kern); -#endif - -/** - * Returns nonzero if font is a symbol encoded font - */ - int CheckSymbolEncoding(TrueTypeFont* ttf); - -/** - * returns the number of glyphs in a font - */ - int GetTTGlyphCount( TrueTypeFont* ttf ); - -/*- private definitions */ /*FOLD00*/ - - struct _TrueTypeFont { - sal_uInt32 tag; - - char *fname; - sal_Int32 fsize; - sal_uInt8 *ptr; - - char *psname; - char *family; - sal_uInt16 *ufamily; - char *subfamily; - sal_uInt16 *usubfamily; - - sal_uInt32 ntables; - sal_uInt32 *goffsets; - sal_uInt32 nglyphs; - sal_uInt32 unitsPerEm; - sal_uInt32 numberOfHMetrics; - sal_uInt32 numOfLongVerMetrics; /* if this number is not 0, font has vertical metrics information */ - sal_uInt8 *cmap; - int cmapType; - sal_uInt32 (*mapper)(const sal_uInt8 *, sal_uInt32); /* character to glyphID translation function */ - void **tables; /* array of pointers to tables */ - sal_uInt32 *tlens; /* array of table lengths */ - int kerntype; /* Defined in the KernType enum */ - sal_uInt32 nkern; /* number of kern subtables */ - sal_uInt8 **kerntables; /* array of pointers to kern subtables */ - void *pGSubstitution; /* info provided by GSUB for UseGSUB() */ - }; - -#ifdef __cplusplus -} -#endif - -/* indexes into _TrueTypeFont::tables[] and _TrueTypeFont::tlens[] */ -#define O_maxp 0 /* 'maxp' */ -#define O_glyf 1 /* 'glyf' */ -#define O_head 2 /* 'head' */ -#define O_loca 3 /* 'loca' */ -#define O_name 4 /* 'name' */ -#define O_hhea 5 /* 'hhea' */ -#define O_hmtx 6 /* 'hmtx' */ -#define O_cmap 7 /* 'cmap' */ -#define O_vhea 8 /* 'vhea' */ -#define O_vmtx 9 /* 'vmtx' */ -#define O_OS2 10 /* 'OS/2' */ -#define O_post 11 /* 'post' */ -#define O_kern 12 /* 'kern' */ -#define O_cvt 13 /* 'cvt_' - only used in TT->TT generation */ -#define O_prep 14 /* 'prep' - only used in TT->TT generation */ -#define O_fpgm 15 /* 'fpgm' - only used in TT->TT generation */ -#define O_gsub 16 /* 'GSUB' */ -#define NUM_TAGS 17 - -#endif /* __SUBFONT_H */ diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx index 62439d4d4613..c53460d35584 100644 --- a/vcl/inc/vcl/gdimtf.hxx +++ b/vcl/inc/vcl/gdimtf.hxx @@ -164,6 +164,14 @@ public: void Scale( double fScaleX, double fScaleY ); void Scale( const Fraction& rScaleX, const Fraction& rScaleY ); void Rotate( long nAngle10 ); + /* get the bound rect of the contained actions + * caveats: + * - clip actions will limit the contained actions, + * but the current clipregion of the passed OutputDevice will not + * - coordinates of actions will be transformed to preferred mapmode + * - the returned rectangle is relative to the preferred mapmode of the metafile + */ + Rectangle GetBoundRect( OutputDevice& i_rReference ); void Adjust( short nLuminancePercent = 0, short nContrastPercent = 0, short nChannelRPercent = 0, short nChannelGPercent = 0, diff --git a/vcl/inc/vcl/graph.hxx b/vcl/inc/vcl/graph.hxx index f56c55b7db42..9d70c67d3e55 100644 --- a/vcl/inc/vcl/graph.hxx +++ b/vcl/inc/vcl/graph.hxx @@ -53,6 +53,36 @@ class OutputDevice; class Font; class GfxLink; +class VCL_DLLPUBLIC GraphicConversionParameters +{ +private: + Size maSizePixel; // default is (0,0) + + // bitfield + unsigned mbUnlimitedSize : 1; // default is false + unsigned mbAntiAliase : 1; // default is false + unsigned mbSnapHorVerLines : 1; // default is false + +public: + GraphicConversionParameters( + const Size& rSizePixel = Size(), + bool bUnlimitedSize = false, + bool bAntiAliase = false, + bool bSnapHorVerLines = false) + : maSizePixel(rSizePixel), + mbUnlimitedSize(bUnlimitedSize), + mbAntiAliase(bAntiAliase), + mbSnapHorVerLines(bSnapHorVerLines) + { + } + + // data read access + const Size getSizePixel() const { return maSizePixel; } + bool getUnlimitedSize() const { return mbUnlimitedSize; } + bool getAntiAliase() const { return mbAntiAliase; } + bool getSnapHorVerLines() const { return mbSnapHorVerLines; } +}; + class VCL_DLLPUBLIC Graphic : public SvDataCopyStream { private: @@ -96,12 +126,14 @@ public: BOOL IsAlpha() const; BOOL IsAnimated() const; - Bitmap GetBitmap() const; - Bitmap GetBitmap( const Size* pSizePixel ) const; - BitmapEx GetBitmapEx() const; - BitmapEx GetBitmapEx( const Size* pSizePixel ) const; - Bitmap GetUnlimitedBitmap( const Size* pSizePixel ) const; - BitmapEx GetUnlimitedBitmapEx( const Size* pSizePixel ) const; + // #i102089# Access of Bitmap potentially will have to rasterconvert the Graphic + // if it is a MetaFile. To be able to control this conversion it is necessary to + // allow giving parameters which control AntiAliasing and LineSnapping of the + // MetaFile when played. Defaults will use a no-AAed, not snapped conversion as + // before. + Bitmap GetBitmap(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const; + BitmapEx GetBitmapEx(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const; + Animation GetAnimation() const; const GDIMetaFile& GetGDIMetaFile() const; diff --git a/vcl/inc/vcl/graphite_adaptors.hxx b/vcl/inc/vcl/graphite_adaptors.hxx new file mode 100644 index 000000000000..41ffa00b0f8f --- /dev/null +++ b/vcl/inc/vcl/graphite_adaptors.hxx @@ -0,0 +1,154 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +#ifndef _SV_GRAPHITEADAPTORS_HXX +#define _SV_GRAPHITEADAPTORS_HXX + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +// Standard Library +#include <stdexcept> +// Platform + +#ifndef _SVWIN_H +#include <tools/svwin.h> +#endif + +#ifndef _SV_SVSYS_HXX +#include <svsys.h> +#endif + +#ifndef _SV_SALGDI_HXX +#include <vcl/salgdi.hxx> +#endif + +#ifndef _SV_SALLAYOUT_HXX +#include <vcl/sallayout.hxx> +#endif + +// Module +#include "vcl/dllapi.h" + +// Libraries +#include <graphite/GrClient.h> +#include <graphite/Font.h> +#include <graphite/ITextSource.h> + + +// Module type definitions and forward declarations. +// +#ifndef MSC +// SAL/VCL types +class ServerFont; +class FreetypeServerFont; + +// Graphite types + +struct FontProperties : gr::FontProps +{ + FontProperties(const FreetypeServerFont & font) throw(); +}; + +namespace grutils +{ + class GrFeatureParser; +} + +// This class adapts the Sal font and graphics services to form required by +// the Graphite engine. +// @author tse +// +class VCL_DLLPUBLIC GraphiteFontAdaptor : public gr::Font +{ +typedef std::map<const gr::gid16, std::pair<gr::Rect, gr::Point> > GlyphMetricMap; + +public: + static bool IsGraphiteEnabledFont(ServerFont &) throw(); + + GraphiteFontAdaptor(ServerFont & font, const sal_Int32 dpi_x, const sal_Int32 dpi_y); + GraphiteFontAdaptor(const GraphiteFontAdaptor &) throw(); + ~GraphiteFontAdaptor() throw(); + + gr::Font * copyThis(); + + // Basic attribute accessors. + virtual float ascent(); + virtual float descent(); + virtual bool bold(); + virtual bool italic(); + virtual float height(); + virtual unsigned int getDPIx(); + virtual unsigned int getDPIy(); + + // Font access methods. + virtual const void * getTable(gr::fontTableId32 tableID, size_t * pcbSize); + virtual void getFontMetrics(float * ascent_out, float * descent_out = 0, float * em_square_out = 0); + + // Glyph metrics. + virtual void getGlyphMetrics(gr::gid16 glyphID, gr::Rect & boundingBox, gr::Point & advances); + + // Adaptor attributes. + const FontProperties & fontProperties() const throw(); + FreetypeServerFont & font() const throw(); + const grutils::GrFeatureParser * features() const { return mpFeatures; }; + +private: + virtual void UniqueCacheInfo(std::wstring &, bool &, bool &); + + FreetypeServerFont& mrFont; + FontProperties maFontProperties; + const unsigned int mnDpiX, mnDpiY; + const float mfAscent, + mfDescent, + mfEmUnits; + grutils::GrFeatureParser * mpFeatures; + GlyphMetricMap maGlyphMetricMap; +}; + +// Partial implementation of class GraphiteFontAdaptor. +// +inline const FontProperties & GraphiteFontAdaptor::fontProperties() const throw() { + return maFontProperties; +} + +inline FreetypeServerFont & GraphiteFontAdaptor::font() const throw() { + return mrFont; +} +#endif // not MFC + +// Partial implementation of class TextSourceAdaptor. +// +//inline const ImplLayoutArgs & TextSourceAdaptor::layoutArgs() const throw() { +// return _layout_args; +//} + + +#endif // _SV_GRAPHITEADAPTORS_HXX diff --git a/vcl/inc/vcl/graphite_cache.hxx b/vcl/inc/vcl/graphite_cache.hxx new file mode 100644 index 000000000000..5a537c5f1e48 --- /dev/null +++ b/vcl/inc/vcl/graphite_cache.hxx @@ -0,0 +1,265 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// Description: Classes to cache Graphite Segments to try to improve +// rendering performance. + +#ifndef GraphiteSegmentCache_h +#define GraphiteSegmentCache_h + +#include <tools/solar.h> +#include <rtl/ustring.h> + +#define GRCACHE_REUSE_VECTORS 1 + +//#include <rope> +#include <hash_map> + +class TextSourceAdaptor; +/** +* GrSegRecord stores a Graphite Segment and its associated text +*/ +class GrSegRecord { +public: + GrSegRecord(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl); + + ~GrSegRecord(); + + void reuse(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl); + + void clearVectors(); + void clear(); +#ifdef GRCACHE_REUSE_VECTORS + void setGlyphVectors(long nWidth, GraphiteLayout::Glyphs & vGlyphs, std::vector<int> vCharDxs, + std::vector<int> & vChar2Base, std::vector<int> & vGlyph2Char) + { + clearVectors(); + mnWidth = nWidth; + mvGlyphs.insert(mvGlyphs.begin(), vGlyphs.begin(), vGlyphs.end()); + mvCharDxs.insert(mvCharDxs.begin(),vCharDxs.begin(),vCharDxs.end()); + mvChar2BaseGlyph.insert(mvChar2BaseGlyph.begin(),vChar2Base.begin(),vChar2Base.end()); + mvGlyph2Char.insert(mvGlyph2Char.begin(),vGlyph2Char.begin(),vGlyph2Char.end()); + } +#endif + gr::Segment * getSegment() { return m_seg; } + TextSourceAdaptor * getTextSrc() { return m_text; } + void unlock() { --m_lockCount; } + bool isRtl() const { return mbIsRtl; } +#ifdef GRCACHE_REUSE_VECTORS + const long & width() const { return mnWidth; } + const GraphiteLayout::Glyphs & glyphs() const { return mvGlyphs; } + const std::vector<int> & charDxs() const { return mvCharDxs; } + const std::vector<int> & char2BaseGlyph() const { return mvChar2BaseGlyph; } + const std::vector<int> & glyph2Char() const { return mvGlyph2Char; } +#endif +private: + rtl::OUString * m_rope; + TextSourceAdaptor * m_text; + gr::Segment * m_seg; + const xub_Unicode * m_nextKey; + const xub_Unicode* m_pStr; + size_t m_startChar; + float m_fontScale; + long mnWidth; + GraphiteLayout::Glyphs mvGlyphs; // glyphs in display order + std::vector<int> mvCharDxs; // right hand side x offset of each glyph + std::vector<int> mvChar2BaseGlyph; + std::vector<int> mvGlyph2Char; + bool mbIsRtl; + int m_lockCount; + friend class GraphiteSegmentCache; +}; + +typedef std::hash_map<long, GrSegRecord*, std::hash<long> > GraphiteSegMap; +typedef std::hash_multimap<size_t, GrSegRecord*> GraphiteRopeMap; +typedef std::pair<GraphiteRopeMap::iterator, GraphiteRopeMap::iterator> GrRMEntry; + +/** +* GraphiteSegmentCache contains the cached Segments for one particular font size +*/ +class GraphiteSegmentCache +{ + enum { + // not really sure what good values are here, + // bucket size should be >> cache size + SEG_BUCKET_SIZE = 4096, + SEG_CACHE_SIZE = 255 + }; +public: + GraphiteSegmentCache() + : m_segMap(SEG_BUCKET_SIZE), + m_oldestKey(NULL) {}; + ~GraphiteSegmentCache() + { + m_ropeMap.clear(); + GraphiteSegMap::iterator i = m_segMap.begin(); + while (i != m_segMap.end()) + { + GrSegRecord *r = i->second; + delete r; + ++i; + } + m_segMap.clear(); + }; + GrSegRecord * getSegment(ImplLayoutArgs & layoutArgs, bool bIsRtl) + { + GrSegRecord * found = NULL; + // try to find a segment starting at correct place, if not, try to find a + // match for the complete buffer + GraphiteSegMap::iterator iMap = + m_segMap.find(reinterpret_cast<long>(layoutArgs.mpStr + + layoutArgs.mnMinCharPos)); + if (iMap != m_segMap.end()) + { + found = iMap->second; + } + else + { + iMap = m_segMap.find(reinterpret_cast<long>(layoutArgs.mpStr)); + if (iMap != m_segMap.end()) + { + found = iMap->second; + } + } + if (found) + { + if (found->m_seg->startCharacter() <= layoutArgs.mnMinCharPos && + found->m_seg->stopCharacter() >= layoutArgs.mnEndCharPos) + { + const size_t seg_char_limit = min(layoutArgs.mnLength, layoutArgs.mnEndCharPos + + GraphiteLayout::EXTRA_CONTEXT_LENGTH); + DBG_ASSERT(found && found->m_seg, "null entry in GraphiteSegmentCache"); + // restore original start character, in case it has changed + found->m_seg->setTextSourceOffset(found->m_startChar); + // check that characters are the same, at least in the range of + // interest + // We could use substr and ==, but substr does a copy, + // so its probably faster to do it like this + for (size_t i = layoutArgs.mnMinCharPos; i < seg_char_limit; i++) + { + //if (!found->m_rope->match(rtl::OUString(layoutArgs.mpStr[i], layoutArgs.mnLength), i - found->m_seg->startCharacter())) + if (found->m_rope->getStr()[i-found->m_seg->startCharacter()] != layoutArgs.mpStr[i]) + return NULL; + } + if (found->isRtl() != bIsRtl) + { + return NULL; + } +// if (found->m_lockCount != 0) +// OutputDebugString("Multple users of SegRecord!"); + found->m_lockCount++; + } + else found = NULL; + } + else + { + // the pointers aren't the same, but we might still have the same text in a segment + // this is expecially needed when editing a large paragraph + // each edit changes the pointers, but if we don't reuse any segments it gets very + // slow. + const size_t seg_char_limit = min(layoutArgs.mnLength, layoutArgs.mnEndCharPos + + GraphiteLayout::EXTRA_CONTEXT_LENGTH); + rtl::OUString * rope = new rtl::OUString(layoutArgs.mpStr + layoutArgs.mnMinCharPos, + seg_char_limit - layoutArgs.mnMinCharPos); + if (!rope) return NULL; + size_t nHash = (*(rope)).hashCode(); + GrRMEntry range = m_ropeMap.equal_range(nHash); + while (range.first != range.second) + { + found = range.first->second; + if (found->m_lockCount == 0) + { + if(rope->match(*(found->m_rope))) + { + // found, but the pointers are all wrong + found->m_seg->setTextSourceOffset(layoutArgs.mnMinCharPos); + // the switch is done in graphite_layout.cxx + //found->m_text->switchLayoutArgs(layoutArgs); + found->m_lockCount++; + break; + } + else + found = NULL; + } + else + found = NULL; + ++(range.first); + } + delete rope; + } + return found; + }; + GrSegRecord * cacheSegment(TextSourceAdaptor * adapter, gr::Segment * seg, bool bIsRtl); +private: + GraphiteSegMap m_segMap; + GraphiteRopeMap m_ropeMap; + const xub_Unicode * m_oldestKey; + const xub_Unicode * m_prevKey; +}; + +typedef std::hash_map<int, GraphiteSegmentCache *, std::hash<int> > GraphiteCacheMap; + +/** +* GraphiteCacheHandler maps a particular font, style, size to a GraphiteSegmentCache +*/ +class GraphiteCacheHandler +{ +public: + GraphiteCacheHandler() : m_cacheMap(255) {}; + ~GraphiteCacheHandler() + { + GraphiteCacheMap::iterator i = m_cacheMap.begin(); + while (i != m_cacheMap.end()) + { + GraphiteSegmentCache *r = i->second; + delete r; + ++i; + } + m_cacheMap.clear(); + }; + + static GraphiteCacheHandler instance; + + GraphiteSegmentCache * getCache(sal_Int32 & fontHash) + { + if (m_cacheMap.count(fontHash) > 0) + { + return m_cacheMap.find(fontHash)->second; + } + GraphiteSegmentCache *pCache = new GraphiteSegmentCache(); + m_cacheMap[fontHash] = pCache; + return pCache; + } +private: + GraphiteCacheMap m_cacheMap; +}; + +#endif + diff --git a/vcl/inc/vcl/graphite_features.hxx b/vcl/inc/vcl/graphite_features.hxx new file mode 100644 index 000000000000..6cfe5dfca0fd --- /dev/null +++ b/vcl/inc/vcl/graphite_features.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// Description: +// Parse a string of features specified as ; separated pairs. +// e.g. +// 1001=1&2002=2&fav1=0 + +#include <graphite/GrClient.h> +#include <graphite/Font.h> +#include <graphite/GrFeature.h> + +namespace grutils +{ + + class GrFeatureParser + { + public: + enum { MAX_FEATURES = 64 }; + static const char FEAT_PREFIX; + static const char FEAT_SEPARATOR; + static const char FEAT_ID_VALUE_SEPARATOR; + static const std::string ISO_LANG; + GrFeatureParser(gr::Font & font, const std::string features, const std::string lang); + GrFeatureParser(gr::Font & font, const std::string lang); + GrFeatureParser(const GrFeatureParser & copy); + ~GrFeatureParser(); + size_t getFontFeatures(gr::FeatureSetting settings[MAX_FEATURES]) const; + bool parseErrors() { return mbErrors; }; + static bool isValid(gr::Font & font, gr::FeatureSetting & setting); + gr::isocode getLanguage() const { return maLang; }; + bool hasLanguage() const { return (maLang.rgch[0] != '\0'); } + sal_Int32 hashCode() const; + private: + void setLang(gr::Font & font, const std::string & lang); + bool isCharId(const std::string & id, size_t offset, size_t length); + int getCharId(const std::string & id, size_t offset, size_t length); + int getIntValue(const std::string & id, size_t offset, size_t length); + size_t mnNumSettings; + gr::isocode maLang; + bool mbErrors; + gr::FeatureSetting maSettings[64]; + }; + + union FeatId + { + gr::featid num; + unsigned char label[5]; + }; +} diff --git a/vcl/inc/vcl/graphite_layout.hxx b/vcl/inc/vcl/graphite_layout.hxx new file mode 100644 index 000000000000..2ec3bc4c2391 --- /dev/null +++ b/vcl/inc/vcl/graphite_layout.hxx @@ -0,0 +1,167 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +#ifndef _SV_GRAPHITELAYOUT_HXX +#define _SV_GRAPHITELAYOUT_HXX +// Description: An implementation of the SalLayout interface that uses the +// Graphite engine. + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +#define GRCACHE 1 + +// Standard Library +#include <memory> +#include <vector> +#include <utility> +// Libraries +#include <graphite/GrClient.h> +#include <graphite/Font.h> +#include <graphite/GrConstants.h> +#include <graphite/GrAppData.h> +#include <graphite/SegmentAux.h> +// Platform +#include <vcl/sallayout.hxx> +#include <vcl/dllapi.h> +// Module + +// For backwards compatibility with 2.4.x +#if (SUPD == 680) +typedef sal_Int32 sal_GlyphId; +#endif + + +// Module type definitions and forward declarations. +// +class TextSourceAdaptor; +class GraphiteFontAdaptor; +class GrSegRecord; +// SAL/VCL types +class ServerFont; +// Graphite types +namespace gr { class Segment; class GlyphIterator; } +namespace grutils { class GrFeatureParser; } + +// This class uses the SIL Graphite engine to provide complex text layout services to the VCL +// @author tse +// +class VCL_DLLPUBLIC GraphiteLayout : public SalLayout +{ +public: + class Glyphs : public std::vector<GlyphItem> + { + public: + typedef std::pair<Glyphs::const_iterator, Glyphs::const_iterator> iterator_pair_t; + + void fill_from(gr::Segment & rSeg, ImplLayoutArgs & rArgs, + bool bRtl, long &rWidth, float fScaling, + std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, + std::vector<int> & rCharDxs); + void move_glyph(Glyphs::iterator, long dx); + + const_iterator cluster_base(const_iterator) const; + iterator_pair_t neighbour_clusters(const_iterator) const; + private: + std::pair<float,float> appendCluster(gr::Segment & rSeg, ImplLayoutArgs & rArgs, + bool bRtl, int nFirstCharInCluster, int nNextChar, + int nFirstGlyphInCluster, int nNextGlyph, float fScaling, + std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, + std::vector<int> & rCharDxs, long & rDXOffset); + void append(gr::Segment & rSeg, ImplLayoutArgs & rArgs, gr::GlyphInfo & rGi, float nextGlyphOrigin, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs, long & rDXOffset, bool bIsBase); + }; + + mutable Glyphs mvGlyphs; + void clear(); + +private: + TextSourceAdaptor * mpTextSrc; // Text source. + gr::LayoutEnvironment maLayout; + const gr::Font &mrFont; + long mnWidth; + std::vector<int> mvCharDxs; + std::vector<int> mvChar2BaseGlyph; + std::vector<int> mvGlyph2Char; + float mfScaling; + const grutils::GrFeatureParser * mpFeatures; + +public: + GraphiteLayout(const gr::Font & font, const grutils::GrFeatureParser * features = NULL) throw(); + + // used by upper layers + virtual bool LayoutText( ImplLayoutArgs& ); // first step of layout + // split into two stages to allow dc to be restored on the segment +#ifdef GRCACHE + gr::Segment * CreateSegment(ImplLayoutArgs& rArgs, GrSegRecord ** pRecord = NULL); + bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment, GrSegRecord * pSegRecord); +#else + gr::Segment * CreateSegment(ImplLayoutArgs& rArgs); + bool LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment); +#endif + + virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting positions + + // methods using string indexing + virtual int GetTextBreak( long nMaxWidth, long nCharExtra=0, int nFactor=1 ) const; + virtual long FillDXArray( sal_Int32* pDXArray ) const; + virtual void ApplyDXArray(ImplLayoutArgs &rArgs, std::vector<int> & rDeltaWidth); + + virtual void GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const; + + // methods using glyph indexing + virtual int GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&, + sal_Int32* pGlyphAdvAry = 0, int* pCharPosAry = 0 ) const; + + // used by glyph+font+script fallback + virtual void MoveGlyph( int nStart, long nNewXPos ); + virtual void DropGlyph( int nStart ); + virtual void Simplify( bool bIsBase ); + + // Dummy implementation so layout can be shared between Linux/Windows + virtual void DrawText(SalGraphics&) const {}; + + virtual ~GraphiteLayout() throw(); + void SetFeatures(grutils::GrFeatureParser * aFeature) { mpFeatures = aFeature; } + void SetFontScale(float s) { mfScaling = s; }; + const TextSourceAdaptor * textSrc() const { return mpTextSrc; }; + virtual sal_GlyphId getKashidaGlyph(int & width) = 0; + void kashidaJustify(std::vector<int> & rDeltaWidth, sal_GlyphId, int width); + + static const int EXTRA_CONTEXT_LENGTH; +private: + int glyph_to_char(Glyphs::iterator); + std::pair<int,int> glyph_to_chars(const GlyphItem &) const; + + std::pair<long,long> caret_positions(size_t) const; +}; + + + +#endif // _SV_GRAPHITELAYOUT_HXX diff --git a/vcl/inc/vcl/graphite_serverfont.hxx b/vcl/inc/vcl/graphite_serverfont.hxx new file mode 100644 index 000000000000..d9e6670df79b --- /dev/null +++ b/vcl/inc/vcl/graphite_serverfont.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +#ifndef _SV_GRAPHITESERVERFONT_HXX +#define _SV_GRAPHITESERVERFONT_HXX + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +#ifndef MSC +#include <vcl/graphite_layout.hxx> +#include <vcl/graphite_adaptors.hxx> + +// Modules + +class VCL_DLLPUBLIC GraphiteLayoutImpl : public GraphiteLayout +{ +public: + GraphiteLayoutImpl(const gr::Font & font, const grutils::GrFeatureParser * features, GraphiteFontAdaptor * pFont) throw() + : GraphiteLayout(font, features), mpFont(pFont) {}; + virtual ~GraphiteLayoutImpl() throw() {}; + virtual sal_GlyphId getKashidaGlyph(int & width); +private: + GraphiteFontAdaptor * mpFont; +}; + +// This class implments the server font specific parts. +// @author tse +// +class VCL_DLLPUBLIC GraphiteServerFontLayout : public ServerFontLayout +{ +private: + mutable GraphiteFontAdaptor * mpFont; + // mutable so that the DrawOffset/DrawBase can be set + mutable GraphiteLayoutImpl maImpl; +public: + GraphiteServerFontLayout(GraphiteFontAdaptor * font) throw(); + + virtual bool LayoutText( ImplLayoutArgs& rArgs) { SalLayout::AdjustLayout(rArgs); return maImpl.LayoutText(rArgs); }; // first step of layout + virtual void AdjustLayout( ImplLayoutArgs& rArgs) + { + SalLayout::AdjustLayout(rArgs); + maImpl.DrawBase() = maDrawBase; + maImpl.DrawOffset() = maDrawOffset; + maImpl.AdjustLayout(rArgs); + }; + virtual long GetTextWidth() const { return maImpl.GetTextWidth(); } + virtual long FillDXArray( sal_Int32* dxa ) const { return maImpl.FillDXArray(dxa); } + virtual int GetTextBreak( long mw, long ce, int f ) const { return maImpl.GetTextBreak(mw, ce, f); } + virtual void GetCaretPositions( int as, sal_Int32* cxa ) const { maImpl.GetCaretPositions(as, cxa); } + + // used by display layers + virtual int GetNextGlyphs( int l, sal_GlyphId* gia, Point& p, int& s, + sal_Int32* gaa = NULL, int* cpa = NULL ) const + { + maImpl.DrawBase() = maDrawBase; + maImpl.DrawOffset() = maDrawOffset; + return maImpl.GetNextGlyphs(l, gia, p, s, gaa, cpa); + } + + virtual void MoveGlyph( int nStart, long nNewXPos ) { maImpl.MoveGlyph(nStart, nNewXPos); }; + virtual void DropGlyph( int nStart ) { maImpl.DropGlyph(nStart); }; + virtual void Simplify( bool bIsBase ) { maImpl.Simplify(bIsBase); }; + + virtual ~GraphiteServerFontLayout() throw(); + +// For use with PspGraphics + const sal_Unicode* getTextPtr() const; + int getMinCharPos() const { return mnMinCharPos; } + int getMaxCharPos() const { return mnEndCharPos; } +}; + + + +#endif +#endif //_SV_GRAPHITESERVERFONT_HXX diff --git a/vcl/inc/vcl/impgraph.hxx b/vcl/inc/vcl/impgraph.hxx index 34b61a5fe21c..3b36173891ae 100644 --- a/vcl/inc/vcl/impgraph.hxx +++ b/vcl/inc/vcl/impgraph.hxx @@ -55,6 +55,7 @@ struct ImpSwapInfo class OutputDevice; class GfxLink; struct ImpSwapFile; +class GraphicConversionParameters; class ImpGraphic { @@ -102,8 +103,8 @@ private: BOOL ImplIsAlpha() const; BOOL ImplIsAnimated() const; - Bitmap ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) const; - BitmapEx ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) const; + Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const; + BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const; Animation ImplGetAnimation() const; const GDIMetaFile& ImplGetGDIMetaFile() const; diff --git a/vcl/inc/vcl/jobset.h b/vcl/inc/vcl/jobset.h index 5d08319a7e6c..9f3eefd507d5 100644 --- a/vcl/inc/vcl/jobset.h +++ b/vcl/inc/vcl/jobset.h @@ -61,7 +61,7 @@ struct ImplJobSetup String maDriver; // Driver-Name Orientation meOrientation; // Orientation USHORT mnPaperBin; // Papierschacht - Paper mePaperFormat; // Papierformat + Paper mePaperFormat; // Papierformat long mnPaperWidth; // Papierbreite in 100tel mm long mnPaperHeight; // Papierhoehe in 100tel mm ULONG mnDriverDataLen; // Laenge der systemabhaengigen Daten diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 3f821f995a51..f4e42846dd5e 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -563,6 +563,20 @@ public: // tells whether this output device is RTL in an LTR UI or LTR in a RTL UI SAL_DLLPRIVATE bool ImplIsAntiparallel() const ; + // #i101491# + // Helper which holds the old line geometry creation and is extended to use AA when + // switched on. Advantage is that line geometry is only temporarily used for paint + SAL_DLLPRIVATE void ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo); + + // #i101491# + // Helper who implements the DrawPolyPolygon functionality for basegfx::B2DPolyPolygon + // without MetaFile processing + SAL_DLLPRIVATE void ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly); + + // #i101491# + // Helper who tries to use SalGDI's DrawPolyLine direct and returns it's bool. Contains no AA check. + SAL_DLLPRIVATE bool ImpTryDrawPolyLineDirect(const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, basegfx::B2DLineJoin eLineJoin); + protected: OutputDevice(); @@ -655,20 +669,20 @@ public: void GetKerningPairs( ULONG nPairs, KerningPair* pKernPairs ) const; BOOL GetTextBoundRect( Rectangle& rRect, - const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0, - xub_StrLen nLen = STRING_LEN ) const; + const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, + ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const; BOOL GetTextOutline( PolyPolygon&, const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, BOOL bOptimize = TRUE, - const ULONG nWidth = 0, const sal_Int32* pDXArray = NULL ) const; + ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const; BOOL GetTextOutlines( PolyPolyVector&, const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, BOOL bOptimize = TRUE, - const ULONG nWidth = 0, const sal_Int32* pDXArray = NULL ) const; + ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const; BOOL GetTextOutlines( ::basegfx::B2DPolyPolygonVector&, const String& rStr, xub_StrLen nBase = 0, xub_StrLen nIndex = 0, xub_StrLen nLen = STRING_LEN, BOOL bOptimize = TRUE, - const ULONG nWidth = 0, const sal_Int32* pDXArray = NULL ) const; + ULONG nLayoutWidth = 0, const sal_Int32* pDXArray = NULL ) const; BOOL GetGlyphBoundRects( const Point& rOrigin, const String& rStr, int nIndex, int nLen, int nBase, MetricVector& rVector ); diff --git a/vcl/inc/vcl/pngread.hxx b/vcl/inc/vcl/pngread.hxx index 200b52eb6182..285af1407c1c 100644 --- a/vcl/inc/vcl/pngread.hxx +++ b/vcl/inc/vcl/pngread.hxx @@ -65,6 +65,8 @@ namespace vcl std::vector< sal_uInt8 > aData; }; const std::vector< ChunkData >& GetChunks() const; + + void SetIgnoreGammaChunk( sal_Bool b ); }; } diff --git a/vcl/inc/vcl/print.hxx b/vcl/inc/vcl/print.hxx index fdc7f2ba9c69..b9176f4106dc 100644 --- a/vcl/inc/vcl/print.hxx +++ b/vcl/inc/vcl/print.hxx @@ -330,17 +330,12 @@ public: USHORT GetPaperBin() const; BOOL SetPaper( Paper ePaper ); BOOL SetPaperSizeUser( const Size& rSize ); - Paper GetPaper() const; + Paper GetPaper() const; // returns number of available paper formats int GetPaperInfoCount() const; // returns info about paper format nPaper - const vcl::PaperInfo& GetPaperInfo( int nPaper ) const; - // sets current paper to format contained in rInfo - BOOL SetPaperFromInfo( const vcl::PaperInfo& rInfo ); - // gets info about paper fromat best matching current paper - const vcl::PaperInfo& GetCurrentPaperInfo() const; - + const PaperInfo& GetPaperInfo( int nPaper ) const; USHORT GetPaperBinCount() const; XubString GetPaperBinName( USHORT nPaperBin ) const; diff --git a/vcl/inc/vcl/prntypes.hxx b/vcl/inc/vcl/prntypes.hxx index 84ef320de20e..681f4f972a7c 100644 --- a/vcl/inc/vcl/prntypes.hxx +++ b/vcl/inc/vcl/prntypes.hxx @@ -33,6 +33,7 @@ #include <tools/string.hxx> #include <vcl/sv.h> +#include <i18npool/paper.hxx> // --------------- // - Duplex Mode - @@ -46,33 +47,6 @@ enum DuplexMode { DUPLEX_UNKNOWN, DUPLEX_OFF, DUPLEX_ON }; enum Orientation { ORIENTATION_PORTRAIT, ORIENTATION_LANDSCAPE }; -// --------- -// - Paper - -// --------- - -typedef USHORT Paper; -#define PAPER_A3 ((Paper)0) -#define PAPER_A4 ((Paper)1) -#define PAPER_A5 ((Paper)2) -#define PAPER_B4 ((Paper)3) -#define PAPER_B5 ((Paper)4) -#define PAPER_LETTER ((Paper)5) -#define PAPER_LEGAL ((Paper)6) -#define PAPER_TABLOID ((Paper)7) -#define PAPER_USER ((Paper)8) - -namespace vcl -{ -struct PaperInfo -{ - String m_aPaperName; // user readable name of paper - unsigned long m_nPaperWidth; // width in mm - unsigned long m_nPaperHeight; // height in mm - - PaperInfo() : m_nPaperWidth( 0 ), m_nPaperHeight( 0 ) {} -}; -} - // ------------------- // - QueueInfo-Types - // ------------------- diff --git a/vcl/inc/vcl/salprn.hxx b/vcl/inc/vcl/salprn.hxx index a80c5873cbfb..2927215034b5 100644 --- a/vcl/inc/vcl/salprn.hxx +++ b/vcl/inc/vcl/salprn.hxx @@ -68,7 +68,7 @@ struct VCL_DLLPUBLIC SalPrinterQueueInfo class VCL_DLLPUBLIC SalInfoPrinter { public: - std::vector< vcl::PaperInfo > m_aPaperFormats; // all printer supported formats + std::vector< PaperInfo > m_aPaperFormats; // all printer supported formats bool m_bPapersInit; // set to true after InitPaperFormats bool m_bCompatMetrics; diff --git a/vcl/inc/vcl/settings.hxx b/vcl/inc/vcl/settings.hxx index 5ee27e3aeb31..a7cd61477519 100644 --- a/vcl/inc/vcl/settings.hxx +++ b/vcl/inc/vcl/settings.hxx @@ -139,7 +139,7 @@ private: ULONG mnMenuDelay; ULONG mnFollow; USHORT mnMiddleButtonAction; - BOOL mbNoWheelActionWithoutFocus; + USHORT mnWheelBehavior; BOOL mbAlign1; }; @@ -158,6 +158,10 @@ private: #define MOUSE_MIDDLE_AUTOSCROLL ((USHORT)1) #define MOUSE_MIDDLE_PASTESELECTION ((USHORT)2) +#define MOUSE_WHEEL_DISABLE ((USHORT)0) +#define MOUSE_WHEEL_FOCUS_ONLY ((USHORT)1) +#define MOUSE_WHEEL_ALWAYS ((USHORT)2) + class VCL_DLLPUBLIC MouseSettings { void CopyData(); @@ -257,10 +261,10 @@ public: USHORT GetMiddleButtonAction() const { return mpData->mnMiddleButtonAction; } - void SetNoWheelActionWithoutFocus( BOOL bAction ) - { CopyData(); mpData->mbNoWheelActionWithoutFocus = bAction; } - BOOL GetNoWheelActionWithoutFocus() const - { return mpData->mbNoWheelActionWithoutFocus; } + void SetWheelBehavior( USHORT nBehavior ) + { CopyData(); mpData->mnWheelBehavior = nBehavior; } + USHORT GetWheelBehavior() const + { return mpData->mnWheelBehavior; } const MouseSettings& operator =( const MouseSettings& rSet ); diff --git a/vcl/inc/vcl/sndstyle.hxx b/vcl/inc/vcl/sndstyle.hxx index 2fc568a5e86d..55255171ad9f 100644 --- a/vcl/inc/vcl/sndstyle.hxx +++ b/vcl/inc/vcl/sndstyle.hxx @@ -44,6 +44,6 @@ typedef USHORT SoundType; #define SOUND_ERROR ((SoundType)3) #define SOUND_QUERY ((SoundType)4) -#define SOUND_DISABLE (SOUND_DEFAULT) +#define SOUND_DISABLE ((SoundType)5) #endif // _SV_SNDSTYLE_HXX diff --git a/vcl/prj/build.lst b/vcl/prj/build.lst index cd6d32dc3d2a..52b444164029 100644 --- a/vcl/prj/build.lst +++ b/vcl/prj/build.lst @@ -1,4 +1,4 @@ -vc vcl : apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools transex3 icc SO:print_header cpputools NULL +vc vcl : l10n apple_remote BOOST:boost rsc sot ucbhelper unotools ICU:icu GRAPHITE:graphite i18npool i18nutil unoil ridljar X11_EXTENSIONS:x11_extensions offuh basegfx basebmp tools transex3 icc SO:print_header cpputools NULL vc vcl usr1 - all vc_mkout NULL vc vcl\inc nmake - all vc_inc NULL vc vcl\source\glyphs nmake - all vc_glyphs vc_inc NULL @@ -32,6 +32,7 @@ vc vcl\unx\gtk\window nmake - u vc__gtkw vc_inc NULL vc vcl\unx\gtk\gdi nmake - u vc__gtkg vc_inc NULL vc vcl\unx\headless nmake - u vc__hl vc_inc NULL vc vcl\unx\kde nmake - u vc__kde vc_inc NULL +vc vcl\unx\kde4 nmake - u vc__kde4 vc_inc NULL vc vcl\aqua\source\a11y nmake - u vc__aquy vc_inc NULL vc vcl\aqua\source\app nmake - u vc__appa vc_inc NULL vc vcl\aqua\source\gdi nmake - u vc__gdia vc_inc NULL @@ -41,6 +42,6 @@ vc vcl\mac\source\app nmake - m vc__appm vc_inc NULL vc vcl\mac\source\gdi nmake - m vc__gdim vc_inc NULL vc vcl\mac\source\window nmake - m vc__winm vc_inc NULL vc vcl\mac\source\src nmake - m vc__srcm vc_inc NULL -vc vcl\util nmake - all vc_util vc__plug.u vc__aquy.u vc__appa.u vc__appm.m vc__appu.u vc__appw.w vc__appp.p vc__gdia.u vc__gdim.m vc__gdiu.u vc__gdiw.w vc__gdip.p vc__srcm.m vc__srcw.w vc__srcp.p vc__wina.u vc__winm.m vc__winu.u vc__winw.w vc__winp.p vc__gtka.u vc__gtky.u vc__gtkw.u vc__gtkg.u vc__kde.u vc__hl.u vc__ftmu.u vc__prgu.u vc__prnu.u vc_app vc_ctrl vc_gdi vc_hlp vc_src vc_win vc_glyphs vc_fts vc_components NULL +vc vcl\util nmake - all vc_util vc__plug.u vc__aquy.u vc__appa.u vc__appm.m vc__appu.u vc__appw.w vc__appp.p vc__gdia.u vc__gdim.m vc__gdiu.u vc__gdiw.w vc__gdip.p vc__srcm.m vc__srcw.w vc__srcp.p vc__wina.u vc__winm.m vc__winu.u vc__winw.w vc__winp.p vc__gtka.u vc__gtky.u vc__gtkw.u vc__gtkg.u vc__kde.u vc__kde4.u vc__hl.u vc__ftmu.u vc__prgu.u vc__prnu.u vc_app vc_ctrl vc_gdi vc_hlp vc_src vc_win vc_glyphs vc_fts vc_components NULL vc vcl\util\linksvp nmake - u vc_lsvp vc_util NULL vc vcl\workben nmake - all vc_wrkb vc_util vc_salmain NULL diff --git a/vcl/source/app/dbggui.cxx b/vcl/source/app/dbggui.cxx index c8567264b9b9..36d0991c7640 100644 --- a/vcl/source/app/dbggui.cxx +++ b/vcl/source/app/dbggui.cxx @@ -1782,7 +1782,7 @@ void DbgDialogTest( Window* pWindow ) i++; } - delete pRectAry; + delete [] pRectAry; } // ======================================================================= diff --git a/vcl/source/app/settings.cxx b/vcl/source/app/settings.cxx index 12213c25a64f..444f1f58c8fb 100644 --- a/vcl/source/app/settings.cxx +++ b/vcl/source/app/settings.cxx @@ -189,7 +189,7 @@ ImplMouseData::ImplMouseData() mnActionDelay = 250; mnMenuDelay = 150; mnFollow = MOUSE_FOLLOW_MENU | MOUSE_FOLLOW_DDLIST; - mbNoWheelActionWithoutFocus = FALSE; + mnWheelBehavior = MOUSE_WHEEL_FOCUS_ONLY; } // ----------------------------------------------------------------------- @@ -217,7 +217,7 @@ ImplMouseData::ImplMouseData( const ImplMouseData& rData ) mnActionDelay = rData.mnActionDelay; mnMenuDelay = rData.mnMenuDelay; mnFollow = rData.mnFollow; - mbNoWheelActionWithoutFocus = rData.mbNoWheelActionWithoutFocus; + mnWheelBehavior = rData.mnWheelBehavior; } // ----------------------------------------------------------------------- @@ -308,7 +308,7 @@ BOOL MouseSettings::operator ==( const MouseSettings& rSet ) const (mpData->mnActionDelay == rSet.mpData->mnActionDelay) && (mpData->mnMenuDelay == rSet.mpData->mnMenuDelay) && (mpData->mnFollow == rSet.mpData->mnFollow) && - (mpData->mbNoWheelActionWithoutFocus == rSet.mpData->mbNoWheelActionWithoutFocus) ) + (mpData->mnWheelBehavior == rSet.mpData->mnWheelBehavior ) ) return TRUE; else return FALSE; diff --git a/vcl/source/control/combobox.cxx b/vcl/source/control/combobox.cxx index 42abe3fd248a..49c7e5457da7 100644 --- a/vcl/source/control/combobox.cxx +++ b/vcl/source/control/combobox.cxx @@ -142,23 +142,19 @@ void ComboBox::ImplCalcEditHeight() if ( !IsDropDownBox() ) mnDDHeight += 4; - // FIXME: currently only on aqua; see if we can use this on other platforms - if( ImplGetSVData()->maNWFData.mbNoFocusRects ) + Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 10, 10 ) ) ); + Region aBoundRegion, aContentRegion; + ImplControlValue aControlValue; + ControlType aType = IsDropDownBox() ? CTRL_COMBOBOX : CTRL_EDITBOX; + if( GetNativeControlRegion( aType, PART_ENTIRE_CONTROL, + aCtrlRegion, + CTRL_STATE_ENABLED, + aControlValue, rtl::OUString(), + aBoundRegion, aContentRegion ) ) { - Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 10, 10 ) ) ); - Region aBoundRegion, aContentRegion; - ImplControlValue aControlValue; - ControlType aType = IsDropDownBox() ? CTRL_COMBOBOX : CTRL_EDITBOX; - if( GetNativeControlRegion( aType, PART_ENTIRE_CONTROL, - aCtrlRegion, - CTRL_STATE_ENABLED, - aControlValue, rtl::OUString(), - aBoundRegion, aContentRegion ) ) - { - const long nNCHeight = aBoundRegion.GetBoundRect().GetHeight(); - if( mnDDHeight < nNCHeight ) - mnDDHeight = sal::static_int_cast<USHORT>( nNCHeight ); - } + const long nNCHeight = aBoundRegion.GetBoundRect().GetHeight(); + if( mnDDHeight < nNCHeight ) + mnDDHeight = sal::static_int_cast<USHORT>( nNCHeight ); } } @@ -876,10 +872,19 @@ long ComboBox::Notify( NotifyEvent& rNEvt ) (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) && (rNEvt.GetWindow() == mpSubEdit) ) { - if( ! GetSettings().GetMouseSettings().GetNoWheelActionWithoutFocus() || HasChildPathFocus() ) + USHORT nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() ); + if ( ( nWheelBehavior == MOUSE_WHEEL_ALWAYS ) + || ( ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY ) + && HasChildPathFocus() + ) + ) + { nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() ); + } else + { nDone = 0; // don't eat this event, let the default handling happen (i.e. scroll the context) + } } return nDone ? nDone : Edit::Notify( rNEvt ); diff --git a/vcl/source/control/lstbox.cxx b/vcl/source/control/lstbox.cxx index 66722b70eef8..a5e9ff1cc7d0 100644 --- a/vcl/source/control/lstbox.cxx +++ b/vcl/source/control/lstbox.cxx @@ -31,21 +31,21 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" -#ifndef _SV_RC_H -#include <tools/rc.h> -#endif -#include <vcl/svdata.hxx> -#include <vcl/decoview.hxx> -#include <vcl/event.hxx> -#include <vcl/scrbar.hxx> -#include <vcl/button.hxx> -#include <vcl/edit.hxx> -#include <vcl/subedit.hxx> -#include <vcl/ilstbox.hxx> -#include <vcl/lstbox.hxx> -#include <vcl/combobox.hxx> -#include <vcl/controllayout.hxx> -#include <tools/debug.hxx> +#include "tools/rc.h" + +#include "vcl/svdata.hxx" +#include "vcl/decoview.hxx" +#include "vcl/event.hxx" +#include "vcl/scrbar.hxx" +#include "vcl/button.hxx" +#include "vcl/edit.hxx" +#include "vcl/subedit.hxx" +#include "vcl/ilstbox.hxx" +#include "vcl/lstbox.hxx" +#include "vcl/combobox.hxx" +#include "vcl/controllayout.hxx" + +#include "tools/debug.hxx" @@ -127,9 +127,7 @@ void ListBox::ImplInit( Window* pParent, WinBits nStyle ) GetBorder( nLeft, nTop, nRight, nBottom ); mnDDHeight = (USHORT)(GetTextHeight() + nTop + nBottom + 4); - // FIXME: this is currently only on mac/aqua - if( ImplGetSVData()->maNWFData.mbNoFocusRects && - IsNativeWidgetEnabled() && + if( IsNativeWidgetEnabled() && IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) ) { ImplControlValue aControlValue; @@ -650,6 +648,7 @@ void ListBox::Resize() long nTop = 0; long nBottom = aOutSz.Height(); + // note: in case of no border, pBorder will actually be this Window *pBorder = GetWindow( WINDOW_BORDER ); ImplControlValue aControlValue; Point aPoint; @@ -678,6 +677,17 @@ void ListBox::Resize() // use the themes drop down size Rectangle aContentRect = aContent.GetBoundRect(); + if( ! (GetStyle() & WB_BORDER) && ImplGetSVData()->maNWFData.mbNoFocusRects ) + { + // no border but focus ring behavior -> we have a problem; the + // native rect relies on the border to draw the focus + // let's do the best we can and center vertically, so it doesn't look + // completely wrong. + Size aSz( GetOutputSizePixel() ); + long nDiff = aContentRect.Top() - (aSz.Height() - aContentRect.GetHeight())/2; + aContentRect.Top() -= nDiff; + aContentRect.Bottom() -= nDiff; + } mpImplWin->SetPosSizePixel( aContentRect.TopLeft(), aContentRect.GetSize() ); } else @@ -959,10 +969,19 @@ long ListBox::PreNotify( NotifyEvent& rNEvt ) (rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL) && (rNEvt.GetWindow() == mpImplWin) ) { - if( ! GetSettings().GetMouseSettings().GetNoWheelActionWithoutFocus() || HasChildPathFocus() ) + USHORT nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() ); + if ( ( nWheelBehavior == MOUSE_WHEEL_ALWAYS ) + || ( ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY ) + && HasChildPathFocus() + ) + ) + { nDone = mpImplLB->HandleWheelAsCursorTravel( *rNEvt.GetCommandEvent() ); + } else + { nDone = 0; // don't eat this event, let the default handling happen (i.e. scroll the context) + } } } @@ -1264,6 +1283,26 @@ Size ListBox::CalcMinimumSize() const else { aSz.Height() = mpImplLB->CalcSize( 1 ).Height(); + if( aSz.Height() < mnDDHeight ) + { + aSz.Height() = mnDDHeight; + // FIXME: this is currently only on mac/aqua + if( ImplGetSVData()->maNWFData.mbNoFocusRects && + IsNativeWidgetEnabled() && + const_cast<ListBox*>(this)->IsNativeControlSupported( CTRL_LISTBOX, PART_ENTIRE_CONTROL ) ) + { + ImplControlValue aControlValue; + Region aCtrlRegion( Rectangle( (const Point&)Point(), Size( 20, mnDDHeight ) ) ); + Region aBoundingRgn( aCtrlRegion ); + Region aContentRgn( aCtrlRegion ); + // adjust the size of the edit field + if( const_cast<ListBox*>(this)->GetNativeControlRegion( CTRL_LISTBOX, PART_ENTIRE_CONTROL, + aCtrlRegion, 0, aControlValue, rtl::OUString(), aBoundingRgn, aContentRgn) ) + { + aSz.Height() = aContentRgn.GetBoundRect().GetHeight(); + } + } + } aSz.Width() = mpImplLB->GetMaxEntryWidth(); aSz.Width() += GetSettings().GetStyleSettings().GetScrollBarSize(); } diff --git a/vcl/source/control/spinfld.cxx b/vcl/source/control/spinfld.cxx index 3f8779dc2e90..0d656da40ba7 100644 --- a/vcl/source/control/spinfld.cxx +++ b/vcl/source/control/spinfld.cxx @@ -599,7 +599,12 @@ long SpinField::Notify( NotifyEvent& rNEvt ) { if ( ( rNEvt.GetCommandEvent()->GetCommand() == COMMAND_WHEEL ) && !IsReadOnly() ) { - if( ! GetSettings().GetMouseSettings().GetNoWheelActionWithoutFocus() || HasChildPathFocus() ) + USHORT nWheelBehavior( GetSettings().GetMouseSettings().GetWheelBehavior() ); + if ( ( nWheelBehavior == MOUSE_WHEEL_ALWAYS ) + || ( ( nWheelBehavior == MOUSE_WHEEL_FOCUS_ONLY ) + && HasChildPathFocus() + ) + ) { const CommandWheelData* pData = rNEvt.GetCommandEvent()->GetWheelData(); if ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) diff --git a/vcl/source/fontsubset/sft.cxx b/vcl/source/fontsubset/sft.cxx index 10d4cf774b04..7744b2f9a59c 100644 --- a/vcl/source/fontsubset/sft.cxx +++ b/vcl/source/fontsubset/sft.cxx @@ -329,7 +329,7 @@ _inline void PutInt16(sal_Int16 val, sal_uInt8 *ptr, size_t offset, int bigendia } -#if defined(OSL_BIG_ENDIAN) +#if defined(OSL_BIGENDIAN) #define Int16FromMOTA(a) (a) #define Int32FromMOTA(a) (a) #else diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 3a29e6d56095..6483c8292df7 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -1403,6 +1403,436 @@ void GDIMetaFile::Rotate( long nAngle10 ) // ------------------------------------------------------------------------ +static void ImplActionBounds( Rectangle& o_rOutBounds, + const Rectangle& i_rInBounds, + const std::vector<Rectangle>& i_rClipStack ) +{ + Rectangle aBounds( i_rInBounds ); + if( ! i_rInBounds.IsEmpty() && ! i_rClipStack.empty() && ! i_rClipStack.back().IsEmpty() ) + aBounds.Intersection( i_rClipStack.back() ); + if( ! aBounds.IsEmpty() ) + { + if( ! o_rOutBounds.IsEmpty() ) + o_rOutBounds.Union( aBounds ); + else + o_rOutBounds = aBounds; + } +} + +Rectangle GDIMetaFile::GetBoundRect( OutputDevice& i_rReference ) +{ + GDIMetaFile aMtf; + VirtualDevice aMapVDev( i_rReference ); + + aMapVDev.EnableOutput( FALSE ); + aMapVDev.SetMapMode( GetPrefMapMode() ); + + std::vector<Rectangle> aClipStack( 1, Rectangle() ); + std::vector<USHORT> aPushFlagStack; + + Rectangle aBound; + + for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() ) + { + const USHORT nActionType = pAction->GetType(); + + switch( nActionType ) + { + case( META_PIXEL_ACTION ): + { + MetaPixelAction* pAct = (MetaPixelAction*) pAction; + ImplActionBounds( aBound, + Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), + aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), + aClipStack ); + } + break; + + case( META_POINT_ACTION ): + { + MetaPointAction* pAct = (MetaPointAction*) pAction; + ImplActionBounds( aBound, + Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), + aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), + aClipStack ); + } + break; + + case( META_LINE_ACTION ): + { + MetaLineAction* pAct = (MetaLineAction*) pAction; + Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() ); + Rectangle aRect( aP1, aP2 ); + aRect.Justify(); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_RECT_ACTION ): + { + MetaRectAction* pAct = (MetaRectAction*) pAction; + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_ROUNDRECT_ACTION ): + { + MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction; + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_ELLIPSE_ACTION ): + { + MetaEllipseAction* pAct = (MetaEllipseAction*) pAction; + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_ARC_ACTION ): + { + MetaArcAction* pAct = (MetaArcAction*) pAction; + // FIXME: this is imprecise + // e.g. for small arcs the whole rectangle is WAY too large + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_PIE_ACTION ): + { + MetaPieAction* pAct = (MetaPieAction*) pAction; + // FIXME: this is imprecise + // e.g. for small arcs the whole rectangle is WAY too large + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_CHORD_ACTION ): + { + MetaChordAction* pAct = (MetaChordAction*) pAction; + // FIXME: this is imprecise + // e.g. for small arcs the whole rectangle is WAY too large + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_POLYLINE_ACTION ): + { + MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction; + Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_POLYGON_ACTION ): + { + MetaPolygonAction* pAct = (MetaPolygonAction*) pAction; + Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_POLYPOLYGON_ACTION ): + { + MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_TEXT_ACTION ): + { + MetaTextAction* pAct = (MetaTextAction*) pAction; + Rectangle aRect; + // hdu said base = index + aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() ); + Point aPt( pAct->GetPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_TEXTARRAY_ACTION ): + { + MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction; + Rectangle aRect; + // hdu said base = index + aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), + 0, pAct->GetDXArray() ); + Point aPt( pAct->GetPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_STRETCHTEXT_ACTION ): + { + MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction; + Rectangle aRect; + // hdu said base = index + aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), + pAct->GetWidth(), NULL ); + Point aPt( pAct->GetPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_TEXTLINE_ACTION ): + { + MetaTextLineAction* pAct = (MetaTextLineAction*) pAction; + // measure a test string to get ascend and descent right + static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 }; + String aStr( pStr ); + + Rectangle aRect; + aMapVDev.GetTextBoundRect( aRect, aStr, 0, 0, aStr.Len(), 0, NULL ); + Point aPt( pAct->GetStartPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + aRect.Right() = aRect.Left() + pAct->GetWidth(); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_BMPSCALE_ACTION ): + { + MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_BMPSCALEPART_ACTION ): + { + MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_BMPEXSCALE_ACTION ): + { + MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_BMPEXSCALEPART_ACTION ): + { + MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_GRADIENT_ACTION ): + { + MetaGradientAction* pAct = (MetaGradientAction*) pAction; + Rectangle aRect( pAct->GetRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_GRADIENTEX_ACTION ): + { + MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_COMMENT_ACTION ): + { + // nothing to do + }; + break; + + case( META_HATCH_ACTION ): + { + MetaHatchAction* pAct = (MetaHatchAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_TRANSPARENT_ACTION ): + { + MetaTransparentAction* pAct = (MetaTransparentAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_FLOATTRANSPARENT_ACTION ): + { + MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; + GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); + // get the bound rect of the contained metafile + Rectangle aRect( aTransMtf.GetBoundRect( i_rReference ) ); + // scale the rect now on the assumption that the correct top left of the metafile + // (not its bounds !) is (0,0) + Size aPSize( aTransMtf.GetPrefSize() ); + aPSize = aMapVDev.LogicToLogic( aPSize, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); + Size aActSize( pAct->GetSize() ); + double fX = double(aActSize.Width())/double(aPSize.Width()); + double fY = double(aActSize.Height())/double(aPSize.Height()); + aRect.Left() = long(double(aRect.Left())*fX); + aRect.Right() = long(double(aRect.Right())*fX); + aRect.Top() = long(double(aRect.Top())*fY); + aRect.Bottom() = long(double(aRect.Bottom())*fY); + + // transform the rect to current VDev state + aRect = aMapVDev.LogicToLogic( aRect, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); + + ImplActionBounds( aBound, aRect, aClipStack ); + } + break; + + case( META_EPS_ACTION ): + { + MetaEPSAction* pAct = (MetaEPSAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_CLIPREGION_ACTION ): + { + MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction; + if( pAct->IsClipping() ) + aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ); + else + aClipStack.back() = Rectangle(); + } + break; + + case( META_ISECTRECTCLIPREGION_ACTION ): + { + MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction; + Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); + if( aClipStack.back().IsEmpty() ) + aClipStack.back() = aRect; + else + aClipStack.back().Intersection( aRect ); + } + break; + + case( META_ISECTREGIONCLIPREGION_ACTION ): + { + MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction; + Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); + if( aClipStack.back().IsEmpty() ) + aClipStack.back() = aRect; + else + aClipStack.back().Intersection( aRect ); + } + break; + + case( META_BMP_ACTION ): + { + MetaBmpAction* pAct = (MetaBmpAction*) pAction; + Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_BMPEX_ACTION ): + { + MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; + Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_MASK_ACTION ): + { + MetaMaskAction* pAct = (MetaMaskAction*) pAction; + Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_MASKSCALE_ACTION ): + { + MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_MASKSCALEPART_ACTION ): + { + MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_WALLPAPER_ACTION ): + { + MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; + Rectangle aRect( pAct->GetRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_TEXTRECT_ACTION ): + { + MetaTextRectAction* pAct = (MetaTextRectAction*) pAction; + Rectangle aRect( pAct->GetRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; + + case( META_MOVECLIPREGION_ACTION ): + { + MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction; + if( ! aClipStack.back().IsEmpty() ) + { + Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() ); + aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() ); + aClipStack.back().Move( aDelta.Width(), aDelta.Width() ); + } + } + break; + + default: + { + pAction->Execute( &aMapVDev ); + + if( nActionType == META_PUSH_ACTION ) + { + MetaPushAction* pAct = (MetaPushAction*) pAction; + aPushFlagStack.push_back( pAct->GetFlags() ); + if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 ) + { + Rectangle aRect( aClipStack.back() ); + aClipStack.push_back( aRect ); + } + } + else if( nActionType == META_POP_ACTION ) + { + // sanity check + if( ! aPushFlagStack.empty() ) + { + if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 ) + { + if( aClipStack.size() > 1 ) + aClipStack.pop_back(); + } + aPushFlagStack.pop_back(); + } + } + } + break; + } + } + return aBound; +} + +// ------------------------------------------------------------------------ + Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam ) { return Color( rColor.GetTransparency(), diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index dfa155e29eae..77f065912e5d 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -430,44 +430,16 @@ BOOL Graphic::IsAnimated() const // ------------------------------------------------------------------------ -Bitmap Graphic::GetBitmap() const +Bitmap Graphic::GetBitmap(const GraphicConversionParameters& rParameters) const { - return GetBitmap( NULL ); + return mpImpGraphic->ImplGetBitmap(rParameters); } // ------------------------------------------------------------------------ -BitmapEx Graphic::GetBitmapEx() const +BitmapEx Graphic::GetBitmapEx(const GraphicConversionParameters& rParameters) const { - return GetBitmapEx( NULL ); -} - -// ------------------------------------------------------------------------ - -Bitmap Graphic::GetBitmap( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmap( pSizePixel, FALSE ); -} - -// ------------------------------------------------------------------------ - -BitmapEx Graphic::GetBitmapEx( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmapEx( pSizePixel, FALSE ); -} - -// ------------------------------------------------------------------------ - -Bitmap Graphic::GetUnlimitedBitmap( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmap( pSizePixel, TRUE ) ; -} - -// ------------------------------------------------------------------------ - -BitmapEx Graphic::GetUnlimitedBitmapEx( const Size* pSizePixel ) const -{ - return mpImpGraphic->ImplGetBitmapEx( pSizePixel, TRUE ) ; + return mpImpGraphic->ImplGetBitmapEx(rParameters); } // ------------------------------------------------------------------------ @@ -553,7 +525,7 @@ Size Graphic::GetSizePixel( const OutputDevice* pRefDevice ) const Size aRet; if( GRAPHIC_BITMAP == mpImpGraphic->ImplGetType() ) - aRet = mpImpGraphic->ImplGetBitmapEx( NULL, FALSE ).GetSizePixel(); + aRet = mpImpGraphic->ImplGetBitmapEx(GraphicConversionParameters()).GetSizePixel(); else aRet = ( pRefDevice ? pRefDevice : Application::GetDefaultDevice() )->LogicToPixel( GetPrefSize(), GetPrefMapMode() ); diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index a67d6fa7feac..d73f35bef962 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -483,7 +483,7 @@ BOOL ImpGraphic::ImplIsAnimated() const // ------------------------------------------------------------------------ -Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) const +Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const { Bitmap aRetBmp; @@ -494,8 +494,8 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor ); - if( pSizePixel ) - aRetBmp.Scale( *pSizePixel ); + if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) + aRetBmp.Scale(rParameters.getSizePixel()); } else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) { @@ -508,16 +508,18 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons Size aDrawSize( aVDev.LogicToPixel( maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode() ) ); Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 ); - if( pSizePixel && aSizePix.Width() && aSizePix.Height() ) + if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height()) { - aDrawSize.Width() = FRound( (double) pSizePixel->Width() * (double) aDrawSize.Width() / (double) aSizePix.Width() ); - aDrawSize.Height() = FRound( (double) pSizePixel->Height() * (double) aDrawSize.Height() / (double) aSizePix.Height() ); + aDrawSize.Width() = FRound((double)rParameters.getSizePixel().Width() * + (double)aDrawSize.Width() / (double)aSizePix.Width()); + aDrawSize.Height() = FRound((double)rParameters.getSizePixel().Height() * + (double)aDrawSize.Height() / (double)aSizePix.Height()); - aSizePix = *pSizePixel; + aSizePix = rParameters.getSizePixel(); } - if( aSizePix.Width() && aSizePix.Height() && !bUnlimited && - ( aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT ) ) + if( aSizePix.Width() && aSizePix.Height() && !rParameters.getUnlimitedSize() + && (aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT)) { const Size aOldSizePix( aSizePix ); double fWH = (double) aSizePix.Width() / aSizePix.Height(); @@ -533,6 +535,16 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons if( aVDev.SetOutputSizePixel( aSizePix ) ) { + if(rParameters.getAntiAliase()) + { + aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW); + } + + if(rParameters.getSnapHorVerLines()) + { + aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_PIXELSNAPHAIRLINE); + } + ImplDraw( &aVDev, aNullPt, aDrawSize ); aRetBmp = aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ); } @@ -549,7 +561,7 @@ Bitmap ImpGraphic::ImplGetBitmap( const Size* pSizePixel, BOOL bUnlimited ) cons // ------------------------------------------------------------------------ -BitmapEx ImpGraphic::ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) const +BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const { BitmapEx aRetBmpEx; @@ -557,13 +569,13 @@ BitmapEx ImpGraphic::ImplGetBitmapEx( const Size* pSizePixel, BOOL bUnlimited ) { aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx ); - if( pSizePixel ) - aRetBmpEx.Scale( *pSizePixel ); + if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height()) + aRetBmpEx.Scale(rParameters.getSizePixel()); } else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() ) { const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) ); - aRetBmpEx = BitmapEx( ImplGetBitmap( pSizePixel, bUnlimited ), aMonoMask.ImplGetBitmap( pSizePixel, bUnlimited ) ); + aRetBmpEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters)); } return aRetBmpEx; diff --git a/vcl/source/gdi/impimagetree.cxx b/vcl/source/gdi/impimagetree.cxx index 64cddece1199..9e1378f22326 100644 --- a/vcl/source/gdi/impimagetree.cxx +++ b/vcl/source/gdi/impimagetree.cxx @@ -102,8 +102,11 @@ void loadFromStream( rtl::OUString const & path, BitmapEx & bitmap) { std::auto_ptr< SvStream > s(wrapStream(stream)); - if (path.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".png"))) { - bitmap = vcl::PNGReader(*s).Read(); + if (path.endsWithAsciiL(RTL_CONSTASCII_STRINGPARAM(".png"))) + { + vcl::PNGReader aPNGReader( *s ); + aPNGReader.SetIgnoreGammaChunk( sal_True ); + bitmap = aPNGReader.Read(); } else { *s >> bitmap; } diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index 977e5386fe97..a09ae92dcb5e 100644 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -45,6 +45,9 @@ TARGET=gdi .IF "$(COM)"=="ICC" CDEFS+=-D_STD_NO_NAMESPACE -D_VOS_NO_NAMESPACE -D_UNO_NO_NAMESPACE .ENDIF +.IF "$(ENABLE_GRAPHITE)" == "TRUE" +CDEFS+=-DENABLE_GRAPHITE +.ENDIF # --- Files -------------------------------------------------------- @@ -137,6 +140,7 @@ EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ $(SLO)$/pngwrite.obj \ $(SLO)$/virdev.obj \ $(SLO)$/impprn.obj \ + $(SLO)$/gdimtf.obj \ $(SLO)$/graphictools.obj diff --git a/vcl/source/gdi/outdev.cxx b/vcl/source/gdi/outdev.cxx index 0e9da9f81136..5b543258cb0b 100644 --- a/vcl/source/gdi/outdev.cxx +++ b/vcl/source/gdi/outdev.cxx @@ -68,6 +68,8 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dlinegeometry.hxx> #include <com/sun/star/awt/XGraphics.hpp> #include <com/sun/star/uno/Sequence.hxx> @@ -2285,8 +2287,35 @@ void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt ) if ( mbInitLineColor ) ImplInitLineColor(); - Point aStartPt = ImplLogicToDevicePixel( rStartPt ); - Point aEndPt = ImplLogicToDevicePixel( rEndPt ); + // #i101598# support AA and snap for lines, too + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()) + { + // at least transform with double precision to device coordinates; this will + // avoid pixel snap of single, appended lines + const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); + const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + basegfx::B2DPolygon aB2DPolyLine; + + aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y())); + aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y())); + aB2DPolyLine.transform( aTransform ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); + } + + if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) + { + return; + } + } + + const Point aStartPt(ImplLogicToDevicePixel(rStartPt)); + const Point aEndPt(ImplLogicToDevicePixel(rEndPt)); mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this ); @@ -2444,22 +2473,30 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly ) if ( mbInitLineColor ) ImplInitLineColor(); + const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()); + // use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon(), 0.0, basegfx::B2DLINEJOIN_NONE)) { - ::basegfx::B2DPolygon aB2DPolyLine = rPoly.getB2DPolygon(); + basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon()); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - aB2DPolyLine.transform( aTransform ); const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && (mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)) + // transform the polygon + aB2DPolyLine.transform( aTransform ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) { - // #i98289# aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine); } - if( mpGraphics->DrawPolyLine( aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_ROUND, this ) ) + if(mpGraphics->DrawPolyLine(aB2DPolyLine, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this)) + { return; + } } Polygon aPoly = ImplLogicToDevicePixel( rPoly ); @@ -2499,9 +2536,23 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo return; } + // #i101491# + // Try direct Fallback to B2D-Version of DrawPolyLine + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && LINE_SOLID == rLineInfo.GetStyle()) + { + DrawPolyLine(rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), basegfx::B2DLINEJOIN_ROUND); + return; + } + if ( mpMetaFile ) mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) ); + ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo); +} + +void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo) +{ USHORT nPoints = rPoly.GetSize(); if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() ) @@ -2527,6 +2578,10 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo return; const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) ); + const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()); if( aInfo.GetWidth() > 1L ) { @@ -2540,9 +2595,32 @@ void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo ImplInitLineColor(); SetFillColor( aOldLineColor ); ImplInitFillColor(); + bool bDone(false); + + if(bTryAA) + { + // #i101491# try AAed version + // Use old on-the-fly geometry preparation, combine with AA + bool bSuccess(true); - for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) - mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this ); + for(const Polygon* pPoly = aLineCvt.ImplGetFirst(); bSuccess && pPoly; pPoly = aLineCvt.ImplGetNext()) + { + bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(pPoly->getB2DPolygon()), 0.0, this); + } + + if(bSuccess) + { + bDone = true; + } + } + + if(!bDone) + { + for( const Polygon* pPoly = aLineCvt.ImplGetFirst(); pPoly; pPoly = aLineCvt.ImplGetNext() ) + { + mpGraphics->DrawPolygon( pPoly->GetSize(), (const SalPoint*) pPoly->GetConstPointAry(), this ); + } + } SetLineColor( aOldLineColor ); SetFillColor( aOldFillColor ); @@ -2598,13 +2676,40 @@ void OutputDevice::DrawPolygon( const Polygon& rPoly ) ImplInitFillColor(); // use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && (IsLineColor() || IsFillColor())) { - ::basegfx::B2DPolyPolygon aB2DPolyPolygon( rPoly.getB2DPolygon() ); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - aB2DPolyPolygon.transform( aTransform ); - if( mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, 0.0, this ) ) + basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon()); + bool bSuccess(true); + + // transform the polygon and ensure closed + aB2DPolygon.transform(aTransform); + aB2DPolygon.setClosed(true); + + if(IsFillColor()) + { + bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this); + } + + if(bSuccess && IsLineColor()) + { + const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); + } + + bSuccess = mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + } + + if(bSuccess) + { return; + } } Polygon aPoly = ImplLogicToDevicePixel( rPoly ); @@ -2661,13 +2766,43 @@ void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly ) ImplInitFillColor(); // use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && (IsLineColor() || IsFillColor())) { - ::basegfx::B2DPolyPolygon aB2DPolyPolygon = rPolyPoly.getB2DPolyPolygon(); const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - aB2DPolyPolygon.transform( aTransform ); - if( mpGraphics->DrawPolyPolygon( aB2DPolyPolygon, 0.0, this ) ) + basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon()); + bool bSuccess(true); + + // transform the polygon and ensure closed + aB2DPolyPolygon.transform(aTransform); + aB2DPolyPolygon.setClosed(true); + + if(IsFillColor()) + { + bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this); + } + + if(bSuccess && IsLineColor()) + { + const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon); + } + + for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++) + { + bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + } + } + + if(bSuccess) + { return; + } } if ( nPoly == 1 ) @@ -2729,6 +2864,12 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) ); #endif + // call helper + ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly); +} + +void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly) +{ // AW: Do NOT paint empty PolyPolygons if(!rB2DPolyPoly.count()) return; @@ -2748,13 +2889,43 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly if( mbInitFillColor ) ImplInitFillColor(); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && (IsLineColor() || IsFillColor())) { - const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - ::basegfx::B2DPolyPolygon aB2DPP = rB2DPolyPoly; - aB2DPP.transform( aTransform ); - if( mpGraphics->DrawPolyPolygon( aB2DPP, 0.0, this ) ) + const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation()); + basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly); + bool bSuccess(true); + + // transform the polygon and ensure closed + aB2DPolyPolygon.transform(aTransform); + aB2DPolyPolygon.setClosed(true); + + if(IsFillColor()) + { + bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this); + } + + if(bSuccess && IsLineColor()) + { + const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 ); + + if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + { + aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon); + } + + for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++) + { + bSuccess = mpGraphics->DrawPolyLine(aB2DPolyPolygon.getB2DPolygon(a), aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this); + } + } + + if(bSuccess) + { return; + } } // fallback to old polygon drawing if needed @@ -2765,6 +2936,38 @@ void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly // ----------------------------------------------------------------------- +bool OutputDevice::ImpTryDrawPolyLineDirect( + const basegfx::B2DPolygon& rB2DPolygon, + double fLineWidth, + basegfx::B2DLineJoin eLineJoin) +{ + const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); + basegfx::B2DVector aB2DLineWidth(1.0, 1.0); + + // transform the line width if used + if( fLineWidth != 0.0 ) + { + aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth ); + } + + // transform the polygon + basegfx::B2DPolygon aB2DPolygon(rB2DPolygon); + aB2DPolygon.transform(aTransform); + + if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE) + && aB2DPolygon.count() < 1000) + { + // #i98289#, #i101491# + // better to remove doubles on device coordinates. Also assume from a given amount + // of points that the single edges are not long enough to smooth + aB2DPolygon.removeDoublePoints(); + aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon); + } + + // draw the polyline + return mpGraphics->DrawPolyLine(aB2DPolygon, aB2DLineWidth, eLineJoin, this); +} + void OutputDevice::DrawPolyLine( const basegfx::B2DPolygon& rB2DPolygon, double fLineWidth, @@ -2808,37 +3011,62 @@ void OutputDevice::DrawPolyLine( if( mbInitLineColor ) ImplInitLineColor(); - // #i98289# use b2dpolygon drawing if possible - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsLineColor()); + + // use b2dpolygon drawing if possible + if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, eLineJoin)) { - const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - ::basegfx::B2DVector aB2DLineWidth(1.0, 1.0); + return; + } - // transform the line width if used - if( fLineWidth != 0.0 ) - aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth ); + // #i101491# + // no output yet; fallback to geometry decomposition and use filled polygon paint + // when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon + // will do internal needed AA checks etc. + if(fLineWidth >= 2.5 + && rB2DPolygon.count() + && rB2DPolygon.count() <= 1000) + { + const double fHalfLineWidth((fLineWidth * 0.5) + 0.5); + const basegfx::B2DPolyPolygon aAreaPolyPolygon(basegfx::tools::createAreaGeometry( + rB2DPolygon, fHalfLineWidth, eLineJoin)); - // transform the polygon - ::basegfx::B2DPolygon aB2DPL = rB2DPolygon; - aB2DPL.transform( aTransform ); + const Color aOldLineColor(maLineColor); + const Color aOldFillColor(maFillColor); + + SetLineColor(); + ImplInitLineColor(); + SetFillColor(aOldLineColor); + ImplInitFillColor(); + + ImpDrawPolyPolygonWithB2DPolyPolygon(aAreaPolyPolygon); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && (mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)) + SetLineColor(aOldLineColor); + ImplInitLineColor(); + SetFillColor(aOldFillColor); + ImplInitFillColor(); + + if(bTryAA) { - // #i98289# - aB2DPL = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPL); + // when AA it is necessary to also paint the filled polygon's outline + // to avoid optical gaps + for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++) + { + ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a), 0.0, basegfx::B2DLINEJOIN_NONE); + } } - - // draw the polyline - if( mpGraphics->DrawPolyLine( aB2DPL, aB2DLineWidth, eLineJoin, this ) ) - return; } - // fallback to old polygon drawing if needed + // fallback to old polygon drawing if needed. This will really + // use ImplLineConverter, but still try to AA lines const Polygon aToolsPolygon( rB2DPolygon ); LineInfo aLineInfo; if( fLineWidth != 0.0 ) aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) ); - DrawPolyLine( aToolsPolygon, aLineInfo ); + ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo ); } // ----------------------------------------------------------------------- diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx index 537964582ceb..345dc162e67e 100644 --- a/vcl/source/gdi/outdev3.cxx +++ b/vcl/source/gdi/outdev3.cxx @@ -7,7 +7,6 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: outdev3.cxx,v $ - * $Revision: 1.240.14.5 $ * * This file is part of OpenOffice.org. * @@ -67,6 +66,9 @@ #ifndef _OSL_FILE_H #include <osl/file.h> #endif +#ifdef ENABLE_GRAPHITE +#include <vcl/graphite_features.hxx> +#endif #include <vcl/unohelp.hxx> #include <pdfwriter_impl.hxx> @@ -2750,6 +2752,14 @@ size_t ImplFontCache::IFSD_Hash::operator()( const ImplFontSelectData& rFSD ) co // TODO: does it pay off to improve this hash function? static FontNameHash aFontNameHash; size_t nHash = aFontNameHash( rFSD.maSearchName ); +#ifdef ENABLE_GRAPHITE + // check for features and generate a unique hash if necessary + if (rFSD.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + != STRING_NOTFOUND) + { + nHash = aFontNameHash( rFSD.maTargetName ); + } +#endif nHash += 11 * rFSD.mnHeight; nHash += 19 * rFSD.meWeight; nHash += 29 * rFSD.meItalic; @@ -2801,6 +2811,15 @@ bool ImplFontCache::IFSD_Equal::operator()(const ImplFontSelectData& rA, const I return false; } +#ifdef ENABLE_GRAPHITE + // check for features + if ((rA.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + != STRING_NOTFOUND || + rB.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + != STRING_NOTFOUND) && rA.maTargetName != rB.maTargetName) + return false; +#endif + return true; } @@ -2838,7 +2857,12 @@ ImplFontEntry* ImplFontCache::GetFontEntry( ImplDevFontList* pFontList, // if it is already known get its normalized search name FontNameList::const_iterator it_name = maFontNameList.find( aSearchName ); if( it_name != maFontNameList.end() ) - if( !(*it_name).second.EqualsAscii( "hg", 0, 2) ) + if( !(*it_name).second.EqualsAscii( "hg", 0, 2) +#ifdef ENABLE_GRAPHITE + && (aSearchName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + == STRING_NOTFOUND) +#endif + ) aSearchName = (*it_name).second; } @@ -2943,6 +2967,22 @@ ImplDevFontListData* ImplDevFontList::ImplFindByFont( ImplFontSelectData& rFSD, { rFSD.maTargetName = GetNextFontToken( rFSD.maName, nTokenPos ); aSearchName = rFSD.maTargetName; + +#ifdef ENABLE_GRAPHITE + // Until features are properly supported, they are appended to the + // font name, so we need to strip them off so the font is found. + xub_StrLen nFeat = aSearchName.Search(grutils::GrFeatureParser::FEAT_PREFIX); + String aOrigName = rFSD.maTargetName; + String aBaseFontName(aSearchName, 0, (nFeat != STRING_NOTFOUND)?nFeat:aSearchName.Len()); + if (nFeat != STRING_NOTFOUND && STRING_NOTFOUND != + aSearchName.Search(grutils::GrFeatureParser::FEAT_ID_VALUE_SEPARATOR, nFeat)) + { + aSearchName = aBaseFontName; + rFSD.maTargetName = aBaseFontName; + } + +#endif + ImplGetEnglishSearchFontName( aSearchName ); ImplFontSubstitute( aSearchName, nSubstFlags, pDevSpecific ); // #114999# special emboldening for Ricoh fonts @@ -2973,6 +3013,10 @@ ImplDevFontListData* ImplDevFontList::ImplFindByFont( ImplFontSelectData& rFSD, } } +#ifdef ENABLE_GRAPHITE + // restore the features to make the font selection data unique + rFSD.maTargetName = aOrigName; +#endif // check if the current font name token or its substitute is valid ImplDevFontListData* pFoundData = ImplFindBySearchName( aSearchName ); if( pFoundData ) @@ -2981,16 +3025,21 @@ ImplDevFontListData* ImplDevFontList::ImplFindByFont( ImplFontSelectData& rFSD, // some systems provide special customization // e.g. they suggest "serif" as UI-font, but this name cannot be used directly // because the system wants to map it to another font first, e.g. "Helvetica" +#ifdef ENABLE_GRAPHITE + // use the target name to search in the prematch hook + rFSD.maTargetName = aBaseFontName; +#endif if( mpPreMatchHook ) - { if( mpPreMatchHook->FindFontSubstitute( rFSD ) ) - { ImplGetEnglishSearchFontName( aSearchName ); - pFoundData = ImplFindBySearchName( aSearchName ); - if( pFoundData ) - return pFoundData; - } - } +#ifdef ENABLE_GRAPHITE + // the prematch hook uses the target name to search, but we now need + // to restore the features to make the font selection data unique + rFSD.maTargetName = aOrigName; +#endif + pFoundData = ImplFindBySearchName( aSearchName ); + if( pFoundData ) + return pFoundData; // break after last font name token was checked unsuccessfully if( nTokenPos == STRING_NOTFOUND) @@ -5441,6 +5490,7 @@ void OutputDevice::SetFont( const Font& rNewFont ) DBG_CHKOBJ( &rNewFont, Font, NULL ); Font aFont( rNewFont ); + aFont.SetLanguage(rNewFont.GetLanguage()); if ( mnDrawMode & (DRAWMODE_BLACKTEXT | DRAWMODE_WHITETEXT | DRAWMODE_GRAYTEXT | DRAWMODE_GHOSTEDTEXT | DRAWMODE_SETTINGSTEXT | DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL | DRAWMODE_GRAYFILL | DRAWMODE_NOFILL | DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) ) @@ -6484,7 +6534,7 @@ SalLayout* OutputDevice::ImplLayout( const String& rOrigStr, nRTLOffset = nPixelWidth; else nRTLOffset = pSalLayout->GetTextWidth() / pSalLayout->GetUnitsPerPixel(); - pSalLayout->DrawOffset().X() = -nRTLOffset; + pSalLayout->DrawOffset().X() = 1 - nRTLOffset; } return pSalLayout; @@ -6919,13 +6969,13 @@ void OutputDevice::ImplDrawText( const Rectangle& rRect, nStyle &= ~TEXT_DRAW_CLIP; } - // Vertikales Alignment + // horizontal text alignment if ( nStyle & TEXT_DRAW_RIGHT ) aPos.X() += nWidth-nTextWidth; else if ( nStyle & TEXT_DRAW_CENTER ) aPos.X() += (nWidth-nTextWidth)/2; - // Font Alignment + // vertical font alignment if ( eAlign == ALIGN_BOTTOM ) aPos.Y() += nTextHeight; else if ( eAlign == ALIGN_BASELINE ) @@ -7919,8 +7969,8 @@ BOOL OutputDevice::GetGlyphBoundRects( const Point& rOrigin, const String& rStr, // ----------------------------------------------------------------------- BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect, - const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, - xub_StrLen nLen ) const + const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen, + ULONG nLayoutWidth, const sal_Int32* pDXAry ) const { DBG_TRACE( "OutputDevice::GetTextBoundRect()" ); DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); @@ -7929,13 +7979,14 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect, rRect.SetEmpty(); SalLayout* pSalLayout = NULL; + const Point aPoint; // calculate offset when nBase!=nIndex long nXOffset = 0; if( nBase != nIndex ) { xub_StrLen nStart = Min( nBase, nIndex ); xub_StrLen nOfsLen = Max( nBase, nIndex ) - nStart; - pSalLayout = ImplLayout( rStr, nStart, nOfsLen ); + pSalLayout = ImplLayout( rStr, nStart, nOfsLen, aPoint, nLayoutWidth, pDXAry ); if( pSalLayout ) { nXOffset = pSalLayout->GetTextWidth(); @@ -7947,7 +7998,7 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect, } } - pSalLayout = ImplLayout( rStr, nIndex, nLen ); + pSalLayout = ImplLayout( rStr, nIndex, nLen, aPoint, nLayoutWidth, pDXAry ); Rectangle aPixelRect; if( pSalLayout ) { @@ -7997,7 +8048,7 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect, aVDev.SetTextAlign( ALIGN_TOP ); // layout the text on the virtual device - pSalLayout = aVDev.ImplLayout( rStr, nIndex, nLen ); + pSalLayout = aVDev.ImplLayout( rStr, nIndex, nLen, aPoint, nLayoutWidth, pDXAry ); if( !pSalLayout ) return false; @@ -8097,7 +8148,7 @@ BOOL OutputDevice::GetTextBoundRect( Rectangle& rRect, BOOL OutputDevice::GetTextOutlines( ::basegfx::B2DPolyPolygonVector& rVector, const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen, - BOOL bOptimize, const ULONG nTWidth, const sal_Int32* pDXArray ) const + BOOL bOptimize, ULONG nTWidth, const sal_Int32* pDXArray ) const { // the fonts need to be initialized if( mbNewFont ) @@ -8326,7 +8377,7 @@ BOOL OutputDevice::GetTextOutlines( ::basegfx::B2DPolyPolygonVector& rVector, BOOL OutputDevice::GetTextOutlines( PolyPolyVector& rResultVector, const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, - xub_StrLen nLen, BOOL bOptimize, const ULONG nTWidth, const sal_Int32* pDXArray ) const + xub_StrLen nLen, BOOL bOptimize, ULONG nTWidth, const sal_Int32* pDXArray ) const { rResultVector.clear(); @@ -8349,7 +8400,7 @@ BOOL OutputDevice::GetTextOutlines( PolyPolyVector& rResultVector, BOOL OutputDevice::GetTextOutline( PolyPolygon& rPolyPoly, const String& rStr, xub_StrLen nBase, xub_StrLen nIndex, xub_StrLen nLen, - BOOL bOptimize, const ULONG nTWidth, const sal_Int32* pDXArray ) const + BOOL bOptimize, ULONG nTWidth, const sal_Int32* pDXArray ) const { rPolyPoly.Clear(); diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx index cee4f475a577..a11e276982f7 100644 --- a/vcl/source/gdi/outdev6.cxx +++ b/vcl/source/gdi/outdev6.cxx @@ -185,14 +185,20 @@ void OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, if( mbInitFillColor ) ImplInitFillColor(); - if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)) + if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW) + && mpGraphics->supportsOperation(OutDevSupport_B2DDraw) + && ROP_OVERPAINT == GetRasterOp() + && IsFillColor()) { // b2dpolygon support not implemented yet on non-UNX platforms const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation(); - ::basegfx::B2DPolyPolygon aB2DPP = rB2DPolyPoly; - aB2DPP.transform( aTransform ); + basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly); - if( mpGraphics->DrawPolyPolygon( aB2DPP, fTransparency, this ) ) + // transform the polygon and ensure closed + aB2DPolyPolygon.transform(aTransform); + aB2DPolyPolygon.setClosed(true); + + if(mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, fTransparency, this)) { #if 0 // MetaB2DPolyPolygonAction is not implemented yet: diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 3f648fda8589..25f02a1b2718 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -792,7 +792,8 @@ static void appendNonStrokingColor( const Color& rColor, OStringBuffer& rBuffer } // matrix helper class -namespace vcl +// TODO: use basegfx matrix class instead or derive from it +namespace vcl // TODO: use anonymous namespace to keep this class local { /* for sparse matrices of the form (2D linear transformations) * f[0] f[1] 0 @@ -812,6 +813,7 @@ public: void scale( double sx, double sy ); void rotate( double angle ); void translate( double tx, double ty ); + bool invert(); void append( PDFWriterImpl::PDFPage& rPage, OStringBuffer& rBuffer, Point* pBack = NULL ); @@ -888,6 +890,36 @@ void Matrix3::translate( double tx, double ty ) f[5] += ty; } +bool Matrix3::invert() +{ + // short circuit trivial cases + if( f[1]==f[2] && f[1]==0.0 && f[0]==f[3] && f[0]==1.0 ) + { + f[4] = -f[4]; + f[5] = -f[5]; + return true; + } + + // check determinant + const double fDet = f[0]*f[3]-f[1]*f[2]; + if( fDet == 0.0 ) + return false; + + // invert the matrix + double fn[6]; + fn[0] = +f[3] / fDet; + fn[1] = -f[1] / fDet; + fn[2] = -f[2] / fDet; + fn[3] = +f[0] / fDet; + + // apply inversion to translation + fn[4] = -(f[4]*fn[0] + f[5]*fn[2]); + fn[5] = -(f[4]*fn[1] + f[5]*fn[3]); + + set( fn ); + return true; +} + void Matrix3::append( PDFWriterImpl::PDFPage& rPage, OStringBuffer& rBuffer, Point* pBack ) { appendDouble( f[0], rBuffer ); @@ -6635,6 +6667,7 @@ void PDFWriterImpl::drawHorizontalGlyphs( // subsequent use of that operator would move // the texline matrix relative to what was set before // making use of that would drive us into rounding issues + Matrix3 aMat; if( nRun == 0 && fAngle == 0.0 && fXScale == 1.0 && fSkew == 0.0 ) { m_aPages.back().appendPoint( aCurPos, rLine, false ); @@ -6642,7 +6675,6 @@ void PDFWriterImpl::drawHorizontalGlyphs( } else { - Matrix3 aMat; if( fSkew != 0.0 ) aMat.skew( 0.0, fSkew ); aMat.scale( fXScale, 1.0 ); @@ -6665,15 +6697,17 @@ void PDFWriterImpl::drawHorizontalGlyphs( appendHex( rGlyphs[nBeginRun].m_nMappedGlyphId, aKernedLine ); appendHex( rGlyphs[nBeginRun].m_nMappedGlyphId, aUnkernedLine ); + aMat.invert(); bool bNeedKern = false; for( sal_uInt32 nPos = nBeginRun+1; nPos < aRunEnds[nRun]; nPos++ ) { appendHex( rGlyphs[nPos].m_nMappedGlyphId, aUnkernedLine ); - // check for adjustment - double fTheoreticalGlyphWidth = rGlyphs[nPos].m_aPos.X() - rGlyphs[nPos-1].m_aPos.X(); - fTheoreticalGlyphWidth = fabs( fTheoreticalGlyphWidth ); // #i100522# workaround until #i87686# gets fixed - fTheoreticalGlyphWidth = 1000.0 * fTheoreticalGlyphWidth / fXScale / double(nPixelFontHeight); - sal_Int32 nAdjustment = rGlyphs[nPos-1].m_nNativeWidth - sal_Int32(fTheoreticalGlyphWidth+0.5); + // check if glyph advance matches with the width of the previous glyph, else adjust + const Point aThisPos = aMat.transform( rGlyphs[nPos].m_aPos ); + const Point aPrevPos = aMat.transform( rGlyphs[nPos-1].m_aPos ); + double fAdvance = aThisPos.X() - aPrevPos.X(); + fAdvance *= 1000.0 / (fXScale * nPixelFontHeight); + const sal_Int32 nAdjustment = rGlyphs[nPos-1].m_nNativeWidth - sal_Int32(fAdvance+0.5); if( nAdjustment != 0 ) { bNeedKern = true; diff --git a/vcl/source/gdi/pngread.cxx b/vcl/source/gdi/pngread.cxx index 56c9025018b9..834116a9ffe9 100644 --- a/vcl/source/gdi/pngread.cxx +++ b/vcl/source/gdi/pngread.cxx @@ -156,6 +156,7 @@ private: BOOL mbIDAT; // TRUE if finished with enough IDAT chunks BOOL mbGamma; // TRUE if Gamma Correction available BOOL mbpHYs; // TRUE if pysical size of pixel available + sal_Bool mbIgnoreGammaChunk; bool ReadNextChunk(); void ReadRemainingChunks(); @@ -186,6 +187,7 @@ public: BitmapEx GetBitmapEx( const Size& rPreviewSizeHint ); const std::vector< PNGReader::ChunkData >& GetAllChunks(); + void SetIgnoreGammaChunk( sal_Bool bIgnore ){ mbIgnoreGammaChunk = bIgnore; }; }; // ------------------------------------------------------------------------------ @@ -205,8 +207,9 @@ PNGReaderImpl::PNGReaderImpl( SvStream& rPNGStream ) mbzCodecInUse ( sal_False ), mbStatus( TRUE), mbIDAT( FALSE ), - mbGamma ( sal_False ), - mbpHYs ( sal_False ) + mbGamma ( sal_False ), + mbpHYs ( sal_False ), + mbIgnoreGammaChunk ( sal_False ) { // prepare the PNG data stream mnOrigStreamMode = mrPNGStream.GetNumberFormatInt(); @@ -382,9 +385,9 @@ BitmapEx PNGReaderImpl::GetBitmapEx( const Size& rPreviewSizeHint ) break; case PNGCHUNK_gAMA : // the gamma chunk must precede - { - if ( mbIDAT == FALSE ) // the 'IDAT' and also the - ImplGetGamma(); // 'PLTE'(if available ) + { // the 'IDAT' and also the 'PLTE'(if available ) + if ( !mbIgnoreGammaChunk && ( mbIDAT == FALSE ) ) + ImplGetGamma(); } break; @@ -1568,4 +1571,12 @@ const std::vector< vcl::PNGReader::ChunkData >& PNGReader::GetChunks() const return mpImpl->GetAllChunks(); } +// ------------------------------------------------------------------------ + +void PNGReader::SetIgnoreGammaChunk( sal_Bool b ) +{ + mpImpl->SetIgnoreGammaChunk( b ); +} + + } // namespace vcl diff --git a/vcl/source/gdi/print.cxx b/vcl/source/gdi/print.cxx index 0a5fbb189885..937d966b3978 100644 --- a/vcl/source/gdi/print.cxx +++ b/vcl/source/gdi/print.cxx @@ -70,44 +70,22 @@ int nImplSysDialog = 0; // ======================================================================= -#define PAPER_SLOPPY 50 // Bigger sloppy value as PaperInfo uses only mm accuracy! -#define PAPER_COUNT 9 - -// Use more accurate metric values for Letter/Legal/Tabloid paper formats -static long ImplPaperFormats[PAPER_COUNT*2] = -{ - 29700, 42000, // A3 - 21000, 29700, // A4 - 14800, 21000, // A5 - 25000, 35300, // B4 - 17600, 25000, // B5 - 21590, 27940, // Letter - 21590, 35570, // Legal - 27960, 43130, // Tabloid - 0, 0 // USER -}; - -// ======================================================================= - -Paper ImplGetPaperFormat( long nWidth100thMM, long nHeight100thMM ) +namespace { - USHORT i; - - for( i = 0; i < PAPER_COUNT; i++ ) + static Paper ImplGetPaperFormat( long nWidth100thMM, long nHeight100thMM ) { - if ( (ImplPaperFormats[i*2] == nWidth100thMM) && - (ImplPaperFormats[i*2+1] == nHeight100thMM) ) - return (Paper)i; + PaperInfo aInfo(nWidth100thMM, nHeight100thMM); + aInfo.doSloppyFit(); + return aInfo.getPaper(); } - for( i = 0; i < PAPER_COUNT; i++ ) +// ----------------------------------------------------------------------- + + static const PaperInfo& ImplGetEmptyPaper() { - if ( (Abs( ImplPaperFormats[i*2]-nWidth100thMM ) < PAPER_SLOPPY) && - (Abs( ImplPaperFormats[i*2+1]-nHeight100thMM ) < PAPER_SLOPPY) ) - return (Paper)i; + static PaperInfo aInfo(PAPER_USER); + return aInfo; } - - return PAPER_USER; } // ======================================================================= @@ -121,8 +99,9 @@ void ImplUpdateJobSetupPaper( JobSetup& rJobSetup ) if ( pConstData->mePaperFormat != PAPER_USER ) { ImplJobSetup* pData = rJobSetup.ImplGetData(); - pData->mnPaperWidth = ImplPaperFormats[((USHORT)pConstData->mePaperFormat)*2]; - pData->mnPaperHeight = ImplPaperFormats[((USHORT)pConstData->mePaperFormat)*2+1]; + PaperInfo aInfo(pConstData->mePaperFormat); + pData->mnPaperWidth = aInfo.getWidth(); + pData->mnPaperHeight = aInfo.getHeight(); } } else if ( pConstData->mePaperFormat == PAPER_USER ) @@ -997,17 +976,6 @@ USHORT Printer::GetPaperBin() const // ----------------------------------------------------------------------- -static BOOL ImplPaperSizeEqual( unsigned long nPaperWidth1, unsigned long nPaperHeight1, - unsigned long nPaperWidth2, unsigned long nPaperHeight2 ) -{ - const long PAPER_ACCURACY = 1; // 1.0 mm accuracy - - return ( (Abs( long(nPaperWidth1)-long(nPaperWidth2) ) <= PAPER_ACCURACY ) && - (Abs( long(nPaperHeight1)-long(nPaperHeight2) ) <= PAPER_ACCURACY ) ); -} - -// ----------------------------------------------------------------------- - // Map user paper format to a available printer paper formats void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup ) { @@ -1016,21 +984,17 @@ void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup ) int nLandscapeAngle = GetLandscapeAngle(); int nPaperCount = GetPaperInfoCount(); - unsigned long nPaperWidth = pSetupData->mnPaperWidth/100; - unsigned long nPaperHeight = pSetupData->mnPaperHeight/100; + PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight); // Alle Papierformate vergleichen und ein passendes raussuchen for ( int i = 0; i < nPaperCount; i++ ) { - const vcl::PaperInfo& rPaperInfo = GetPaperInfo( i ); + const PaperInfo& rPaperInfo = GetPaperInfo( i ); - if ( ImplPaperSizeEqual( rPaperInfo.m_nPaperWidth, - rPaperInfo.m_nPaperHeight, - nPaperWidth, - nPaperHeight ) ) + if ( aInfo.sloppyEqual(rPaperInfo) ) { - pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.m_nPaperWidth*100, - rPaperInfo.m_nPaperHeight*100 ); + pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(), + rPaperInfo.getHeight() ); break; } } @@ -1042,17 +1006,17 @@ void Printer::ImplFindPaperFormatForUserSize( JobSetup& aJobSetup ) nLandscapeAngle != 0 && HasSupport( SUPPORT_SET_ORIENTATION )) { + + PaperInfo aRotatedInfo(pSetupData->mnPaperHeight, pSetupData->mnPaperWidth); + for ( int i = 0; i < nPaperCount; i++ ) { - const vcl::PaperInfo& rPaperInfo = GetPaperInfo( i ); + const PaperInfo& rPaperInfo = GetPaperInfo( i ); - if ( ImplPaperSizeEqual( rPaperInfo.m_nPaperWidth, - rPaperInfo.m_nPaperHeight, - nPaperHeight, - nPaperWidth )) + if ( aRotatedInfo.sloppyEqual( rPaperInfo ) ) { - pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.m_nPaperWidth*100, - rPaperInfo.m_nPaperHeight*100 ); + pSetupData->mePaperFormat = ImplGetPaperFormat( rPaperInfo.getWidth(), + rPaperInfo.getHeight() ); break; } } @@ -1073,8 +1037,9 @@ BOOL Printer::SetPaper( Paper ePaper ) pSetupData->mePaperFormat = ePaper; if ( ePaper != PAPER_USER ) { - pSetupData->mnPaperWidth = ImplPaperFormats[((USHORT)ePaper)*2]; - pSetupData->mnPaperHeight = ImplPaperFormats[((USHORT)ePaper)*2+1]; + PaperInfo aInfo(ePaper); + pSetupData->mnPaperWidth = aInfo.getWidth(); + pSetupData->mnPaperHeight = aInfo.getHeight(); } if ( IsDisplayPrinter() ) @@ -1110,9 +1075,8 @@ BOOL Printer::SetPaperSizeUser( const Size& rSize ) if ( mbInPrintPage ) return FALSE; - MapMode aMap100thMM( MAP_100TH_MM ); Size aPixSize = LogicToPixel( rSize ); - Size aPageSize = PixelToLogic( aPixSize, aMap100thMM ); + Size aPageSize = PixelToLogic( aPixSize, MAP_100TH_MM ); if ( (maJobSetup.ImplGetConstData()->mePaperFormat != PAPER_USER) || (maJobSetup.ImplGetConstData()->mnPaperWidth != aPageSize.Width()) || (maJobSetup.ImplGetConstData()->mnPaperHeight != aPageSize.Height()) ) @@ -1150,15 +1114,6 @@ BOOL Printer::SetPaperSizeUser( const Size& rSize ) return TRUE; } - -// ----------------------------------------------------------------------- - -static const vcl::PaperInfo& ImplGetEmptyPaper() -{ - static vcl::PaperInfo aInfo; - return aInfo; -} - // ----------------------------------------------------------------------- int Printer::GetPaperInfoCount() const @@ -1172,7 +1127,7 @@ int Printer::GetPaperInfoCount() const // ----------------------------------------------------------------------- -const vcl::PaperInfo& Printer::GetPaperInfo( int nPaper ) const +const PaperInfo& Printer::GetPaperInfo( int nPaper ) const { if( ! mpInfoPrinter ) return ImplGetEmptyPaper(); @@ -1185,17 +1140,6 @@ const vcl::PaperInfo& Printer::GetPaperInfo( int nPaper ) const // ----------------------------------------------------------------------- -BOOL Printer::SetPaperFromInfo( const vcl::PaperInfo& rInfo ) -{ - MapMode aMap( MAP_MM ); - Size aSize( rInfo.m_nPaperWidth, rInfo.m_nPaperHeight ); - aSize = LogicToPixel( aSize, aMap ); - aSize = PixelToLogic( aSize ); - return SetPaperSizeUser( aSize ); -} - -// ----------------------------------------------------------------------- - DuplexMode Printer::GetDuplexMode() const { return mpInfoPrinter ? mpInfoPrinter->GetDuplexMode( maJobSetup.ImplGetConstData() ) : DUPLEX_UNKNOWN; @@ -1210,38 +1154,6 @@ int Printer::GetLandscapeAngle() const // ----------------------------------------------------------------------- -const vcl::PaperInfo& Printer::GetCurrentPaperInfo() const -{ - if( ! mpInfoPrinter ) - return ImplGetEmptyPaper(); - if( ! mpInfoPrinter->m_bPapersInit ) - mpInfoPrinter->InitPaperFormats( maJobSetup.ImplGetConstData() ); - if( mpInfoPrinter->m_aPaperFormats.empty() ) - return ImplGetEmptyPaper(); - - MapMode aMap( MAP_MM ); - Size aSize = PixelToLogic( GetPaperSizePixel(), aMap ); - int nMatch = -1; - long nDelta = 0; - for( unsigned int i = 0; i < mpInfoPrinter->m_aPaperFormats.size(); i++ ) - { - long nW = mpInfoPrinter->m_aPaperFormats[i].m_nPaperWidth; - long nH = mpInfoPrinter->m_aPaperFormats[i].m_nPaperHeight; - if( nW >= (aSize.Width()-1) && nH >= (aSize.Height()-1) ) - { - long nCurDelta = (nW - aSize.Width())*(nW - aSize.Width()) + (nH - aSize.Height() )*(nH - aSize.Height() ); - if( nMatch == -1 || nCurDelta < nDelta ) - { - nMatch = i; - nDelta = nCurDelta; - } - } - } - return nMatch != -1 ? mpInfoPrinter->m_aPaperFormats[nMatch] : ImplGetEmptyPaper(); -} - -// ----------------------------------------------------------------------- - Paper Printer::GetPaper() const { return maJobSetup.ImplGetConstData()->mePaperFormat; diff --git a/vcl/source/gdi/sallayout.cxx b/vcl/source/gdi/sallayout.cxx index a96d4dc64b89..21ac05a498fc 100755 --- a/vcl/source/gdi/sallayout.cxx +++ b/vcl/source/gdi/sallayout.cxx @@ -63,6 +63,26 @@ #include <algorithm> +#ifdef DEBUG +//#define MULTI_SL_DEBUG +#endif + +#ifdef MULTI_SL_DEBUG +#include <string> +FILE * mslLogFile = NULL; +FILE * mslLog() +{ +#ifdef MSC + std::string logFileName(getenv("TEMP")); + logFileName.append("\\msllayout.log"); + if (mslLogFile == NULL) mslLogFile = fopen(logFileName.c_str(),"w"); + else fflush(mslLogFile); + return mslLogFile; +#else + return stdout; +#endif +} +#endif // ======================================================================= // TODO: ask the glyph directly, for now we need this method because of #i99367# @@ -1157,11 +1177,17 @@ void GenericSalLayout::ApplyDXArray( ImplLayoutArgs& rArgs ) for( int nCharPos = i = -1; rArgs.GetNextPos( &nCharPos, &bRTL ); ) { n = nCharPos - rArgs.mnMinCharPos; - i = pLogCluster[ n ]; - long nDelta = rArgs.mpDXArray[ n ] ; - if( n > 0 ) - nDelta -= rArgs.mpDXArray[ n-1 ]; - pNewGlyphWidths[ i ] += nDelta * mnUnitsPerPixel; + if( (n < 0) || (nCharCount <= n) ) continue; + + if( pLogCluster[ n ] >= 0 ) + i = pLogCluster[ n ]; + if( i >= 0 ) + { + long nDelta = rArgs.mpDXArray[ n ] ; + if( n > 0 ) + nDelta -= rArgs.mpDXArray[ n-1 ]; + pNewGlyphWidths[ i ] += nDelta * mnUnitsPerPixel; + } } // move cluster positions using the adjusted widths @@ -1768,6 +1794,19 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) } } + // Compute rtl flags, since in some scripts glyphs/char order can be + // reversed for a few character sequencies e.g. Myanmar + std::vector<bool> vRtl(rArgs.mnEndCharPos - rArgs.mnMinCharPos, false); + rArgs.ResetPos(); + bool bRtl; + int nRunStart, nRunEnd; + while (rArgs.GetNextRun(&nRunStart, &nRunEnd, &bRtl)) + { + if (bRtl) std::fill(vRtl.begin() + nRunStart - rArgs.mnMinCharPos, + vRtl.begin() + nRunEnd - rArgs.mnMinCharPos, true); + } + rArgs.ResetPos(); + // prepare "merge sort" int nStartOld[ MAX_FALLBACK ]; int nStartNew[ MAX_FALLBACK ]; @@ -1804,6 +1843,10 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) nStartNew[ nLevel ] = nStartOld[ nLevel ] = 0; nValid[ nLevel ] = mpLayouts[n]->GetNextGlyphs( 1, &nDummy, aPos, nStartNew[ nLevel ], &nGlyphAdv[ nLevel ], &nCharPos[ nLevel ] ); +#ifdef MULTI_SL_DEBUG + if (nValid[nLevel]) fprintf(mslLog(), "layout[%d]->GetNextGlyphs %d,%d x%d a%d c%d %x\n", n, nStartOld[nLevel], nStartNew[nLevel], aPos.X(), nGlyphAdv[nLevel], nCharPos[nLevel], + rArgs.mpStr[nCharPos[nLevel]]); +#endif if( (n > 0) && !nValid[ nLevel ] ) { // an empty fallback layout can be released @@ -1829,6 +1872,9 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) for( n = 0; n < nLevel; ++n ) maFallbackRuns[n].ResetPos(); int nActiveCharPos = nCharPos[0]; + int nLastRunEndChar = (vRtl[nActiveCharPos - mnMinCharPos])? + rArgs.mnEndCharPos : rArgs.mnMinCharPos - 1; + int nRunVisibleEndChar = nCharPos[0]; while( nValid[0] && (nLevel > 0)) { // find best fallback level @@ -1864,6 +1910,9 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) nStartOld[0] = nStartNew[0]; nValid[0] = mpLayouts[0]->GetNextGlyphs( 1, &nDummy, aPos, nStartNew[0], &nGlyphAdv[0], &nCharPos[0] ); +#ifdef MULTI_SL_DEBUG + if (nValid[0]) fprintf(mslLog(), "layout[0]->GetNextGlyphs %d,%d x%d a%d c%d %x\n", nStartOld[0], nStartNew[0], aPos.X(), nGlyphAdv[0], nCharPos[0], rArgs.mpStr[nCharPos[0]]); +#endif if( !nValid[0] ) break; } @@ -1881,7 +1930,9 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) int nOrigCharPos = nCharPos[n]; nValid[n] = mpLayouts[n]->GetNextGlyphs( 1, &nDummy, aPos, nStartNew[n], &nGlyphAdv[n], &nCharPos[n] ); - +#ifdef MULTI_SL_DEBUG + if (nValid[n]) fprintf(mslLog(), "layout[%d]->GetNextGlyphs %d,%d a%d c%d %x\n", n, nStartOld[n], nStartNew[n], nGlyphAdv[n], nCharPos[n], rArgs.mpStr[nCharPos[n]]); +#endif // break after last glyph of active layout if( !nValid[n] ) { @@ -1927,6 +1978,27 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) { maFallbackRuns[0].NextRun(); break; } bKeepNotDef = bNeedFallback; } + // check for reordered glyphs + if (aMultiArgs.mpDXArray && + nRunVisibleEndChar < mnEndCharPos && + nRunVisibleEndChar >= mnMinCharPos && + nCharPos[n] < mnEndCharPos && + nCharPos[n] >= mnMinCharPos) + { + if (vRtl[nActiveCharPos - mnMinCharPos]) + { + if (aMultiArgs.mpDXArray[nRunVisibleEndChar-mnMinCharPos] + >= aMultiArgs.mpDXArray[nCharPos[n] - mnMinCharPos]) + { + nRunVisibleEndChar = nCharPos[n]; + } + } + else if (aMultiArgs.mpDXArray[nRunVisibleEndChar-mnMinCharPos] + <= aMultiArgs.mpDXArray[nCharPos[n] - mnMinCharPos]) + { + nRunVisibleEndChar = nCharPos[n]; + } + } } // if a justification array is available @@ -1936,16 +2008,40 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) // the run advance is the width from the first char // in the run to the first char in the next run nRunAdvance = 0; - const bool bLTR = (nActiveCharPos < nCharPos[0]); +#ifdef MULTI_SL_DEBUG + const bool bLTR = !(vRtl[nActiveCharPos - mnMinCharPos]);//(nActiveCharPos < nCharPos[0]); + int nOldRunAdv = 0; int nDXIndex = nCharPos[0] - mnMinCharPos - bLTR; if( nDXIndex >= 0 ) - nRunAdvance += aMultiArgs.mpDXArray[ nDXIndex ]; + nOldRunAdv += aMultiArgs.mpDXArray[ nDXIndex ]; nDXIndex = nActiveCharPos - mnMinCharPos - bLTR; if( nDXIndex >= 0 ) - nRunAdvance -= aMultiArgs.mpDXArray[ nDXIndex ]; + nOldRunAdv -= aMultiArgs.mpDXArray[ nDXIndex ]; if( !bLTR ) - nRunAdvance = -nRunAdvance; - + nOldRunAdv = -nOldRunAdv; +#endif + if (vRtl[nActiveCharPos - mnMinCharPos]) + { + if (nRunVisibleEndChar > mnMinCharPos && nRunVisibleEndChar <= mnEndCharPos) + nRunAdvance -= aMultiArgs.mpDXArray[nRunVisibleEndChar - 1 - mnMinCharPos]; + if (nLastRunEndChar > mnMinCharPos && nLastRunEndChar <= mnEndCharPos) + nRunAdvance += aMultiArgs.mpDXArray[nLastRunEndChar - 1 - mnMinCharPos]; +#ifdef MULTI_SL_DEBUG + fprintf(mslLog(), "rtl visible %d-%d,%d-%d adv%d(%d)\n", nLastRunEndChar-1, nRunVisibleEndChar-1, nActiveCharPos - bLTR, nCharPos[0] - bLTR, nRunAdvance, nOldRunAdv); +#endif + } + else + { + if (nRunVisibleEndChar >= mnMinCharPos) + nRunAdvance += aMultiArgs.mpDXArray[nRunVisibleEndChar - mnMinCharPos]; + if (nLastRunEndChar >= mnMinCharPos) + nRunAdvance -= aMultiArgs.mpDXArray[nLastRunEndChar - mnMinCharPos]; +#ifdef MULTI_SL_DEBUG + fprintf(mslLog(), "visible %d-%d,%d-%d adv%d(%d)\n", nLastRunEndChar, nRunVisibleEndChar, nActiveCharPos - bLTR, nCharPos[0] - bLTR, nRunAdvance, nOldRunAdv); +#endif + } + nLastRunEndChar = nRunVisibleEndChar; + nRunVisibleEndChar = nCharPos[0]; // the requested width is still in pixel units // => convert it to base level font units nRunAdvance *= mnUnitsPerPixel; @@ -1963,9 +2059,27 @@ void MultiSalLayout::AdjustLayout( ImplLayoutArgs& rArgs ) // prepare for next fallback run nActiveCharPos = nCharPos[0]; + // it essential that the runs don't get ahead of themselves and in the + // if( bKeepNotDef && !bNeedFallback ) statement above, the next run may + // have already been reached on the base level for( int i = nFBLevel; --i >= 0;) - if( !maFallbackRuns[i].PosIsInRun( nActiveCharPos ) ) - maFallbackRuns[i].NextRun(); + { + if (maFallbackRuns[i].GetRun(&nRunStart, &nRunEnd, &bRtl)) + { + if (bRtl) + { + if (nRunStart > nActiveCharPos) + maFallbackRuns[i].NextRun(); + } + else + { + if (nRunEnd <= nActiveCharPos) + maFallbackRuns[i].NextRun(); + } + } + } +// if( !maFallbackRuns[i].PosIsInRun( nActiveCharPos ) ) +// maFallbackRuns[i].NextRun(); } mpLayouts[0]->Simplify( true ); diff --git a/vcl/source/glyphs/gcach_ftyp.cxx b/vcl/source/glyphs/gcach_ftyp.cxx index d149ee26284f..ebb530b1acf6 100644 --- a/vcl/source/glyphs/gcach_ftyp.cxx +++ b/vcl/source/glyphs/gcach_ftyp.cxx @@ -1058,7 +1058,7 @@ static inline void SplitGlyphFlags( const FreetypeServerFont& rFont, int& nGlyph // ----------------------------------------------------------------------- int FreetypeServerFont::ApplyGlyphTransform( int nGlyphFlags, - FT_GlyphRec_* pGlyphFT, bool bForBitmapProcessing ) const + FT_Glyph pGlyphFT, bool bForBitmapProcessing ) const { int nAngle = GetFontSelData().mnOrientation; // shortcut most common case @@ -1130,9 +1130,9 @@ int FreetypeServerFont::ApplyGlyphTransform( int nGlyphFlags, else { // FT<=2005 ignores transforms for bitmaps, so do it manually - FT_BitmapGlyph& rBmpGlyphFT = reinterpret_cast<FT_BitmapGlyph&>(pGlyphFT); - rBmpGlyphFT->left += (aVector.x + 32) >> 6; - rBmpGlyphFT->top += (aVector.y + 32) >> 6; + FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<FT_BitmapGlyph>(pGlyphFT); + pBmpGlyphFT->left += (aVector.x + 32) >> 6; + pBmpGlyphFT->top += (aVector.y + 32) >> 6; } return nAngle; @@ -1425,6 +1425,20 @@ bool FreetypeServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap FT_Glyph_Transform( pGlyphFT, &aMatrix, NULL ); } + // Check for zero area bounding boxes as this crashes some versions of FT. + // This also provides a handy short cut as much of the code following + // becomes an expensive nop when a glyph covers no pixels. + FT_BBox cbox; + FT_Glyph_Get_CBox(pGlyphFT, ft_glyph_bbox_unscaled, &cbox); + + if( (cbox.xMax - cbox.xMin) == 0 || (cbox.yMax - cbox.yMin == 0) ) + { + nAngle = 0; + memset(&rRawBitmap, 0, sizeof rRawBitmap); + FT_Done_Glyph( pGlyphFT ); + return true; + } + if( pGlyphFT->format != FT_GLYPH_FORMAT_BITMAP ) { if( pGlyphFT->format == FT_GLYPH_FORMAT_OUTLINE ) @@ -1440,12 +1454,12 @@ bool FreetypeServerFont::GetGlyphBitmap1( int nGlyphIndex, RawBitmap& rRawBitmap } } - const FT_BitmapGlyph& rBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph&>(pGlyphFT); + const FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph>(pGlyphFT); // NOTE: autohinting in FT<=2.0.2 miscalculates the offsets below by +-1 - rRawBitmap.mnXOffset = +rBmpGlyphFT->left; - rRawBitmap.mnYOffset = -rBmpGlyphFT->top; + rRawBitmap.mnXOffset = +pBmpGlyphFT->left; + rRawBitmap.mnYOffset = -pBmpGlyphFT->top; - const FT_Bitmap& rBitmapFT = rBmpGlyphFT->bitmap; + const FT_Bitmap& rBitmapFT = pBmpGlyphFT->bitmap; rRawBitmap.mnHeight = rBitmapFT.rows; rRawBitmap.mnBitCount = 1; if( mbArtBold && !pFTEmbolden ) @@ -1595,11 +1609,11 @@ bool FreetypeServerFont::GetGlyphBitmap8( int nGlyphIndex, RawBitmap& rRawBitmap } } - const FT_BitmapGlyph& rBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph&>(pGlyphFT); - rRawBitmap.mnXOffset = +rBmpGlyphFT->left; - rRawBitmap.mnYOffset = -rBmpGlyphFT->top; + const FT_BitmapGlyph pBmpGlyphFT = reinterpret_cast<const FT_BitmapGlyph>(pGlyphFT); + rRawBitmap.mnXOffset = +pBmpGlyphFT->left; + rRawBitmap.mnYOffset = -pBmpGlyphFT->top; - const FT_Bitmap& rBitmapFT = rBmpGlyphFT->bitmap; + const FT_Bitmap& rBitmapFT = pBmpGlyphFT->bitmap; rRawBitmap.mnHeight = rBitmapFT.rows; rRawBitmap.mnWidth = rBitmapFT.width; rRawBitmap.mnBitCount = 8; diff --git a/vcl/source/glyphs/glyphcache.cxx b/vcl/source/glyphs/glyphcache.cxx index acfc8e3ac38d..f4e2de486b4b 100644 --- a/vcl/source/glyphs/glyphcache.cxx +++ b/vcl/source/glyphs/glyphcache.cxx @@ -41,6 +41,10 @@ #include <vcl/bitmap.hxx> #include <vcl/outfont.hxx> +#ifdef ENABLE_GRAPHITE +#include <vcl/graphite_features.hxx> +#endif + #include <rtl/ustring.hxx> // used only for string=>hashvalue #include <osl/file.hxx> #include <tools/debug.hxx> @@ -85,12 +89,23 @@ size_t GlyphCache::IFSD_Hash::operator()( const ImplFontSelectData& rFontSelData { // TODO: is it worth to improve this hash function? sal_IntPtr nFontId = reinterpret_cast<sal_IntPtr>( rFontSelData.mpFontData ); +#ifdef ENABLE_GRAPHITE + if (rFontSelData.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + != STRING_NOTFOUND) + { + rtl::OString aFeatName = rtl::OUStringToOString( rFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); + nFontId ^= aFeatName.hashCode(); + } +#endif size_t nHash = nFontId << 8; nHash += rFontSelData.mnHeight; nHash += rFontSelData.mnOrientation; nHash += rFontSelData.mbVertical; nHash += rFontSelData.meItalic; nHash += rFontSelData.meWeight; +#ifdef ENABLE_GRAPHITE + nHash += rFontSelData.meLanguage; +#endif return nHash; } @@ -121,7 +136,16 @@ bool GlyphCache::IFSD_Equal::operator()( const ImplFontSelectData& rA, const Imp if( (rA.mnWidth != rB.mnWidth) && ((rA.mnHeight != rB.mnWidth) || (rA.mnWidth != 0)) ) return false; - +#ifdef ENABLE_GRAPHITE + if (rA.meLanguage != rB.meLanguage) + return false; + // check for features + if ((rA.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + != STRING_NOTFOUND || + rB.maTargetName.Search(grutils::GrFeatureParser::FEAT_PREFIX) + != STRING_NOTFOUND) && rA.maTargetName != rB.maTargetName) + return false; +#endif return true; } diff --git a/vcl/source/glyphs/graphite_adaptors.cxx b/vcl/source/glyphs/graphite_adaptors.cxx new file mode 100644 index 000000000000..67330698ffdf --- /dev/null +++ b/vcl/source/glyphs/graphite_adaptors.cxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// Description: Implements the Graphite interfaces with access to the +// platform's font and graphics systems. + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +// Header files +// +// Standard Library +#include <string> +#include <cassert> +// Libraries +#include <rtl/string.hxx> +#include <rtl/ustring.hxx> +#include <i18npool/mslangid.hxx> +// Platform +#ifndef MSC +#include <saldisp.hxx> + +#include <vcl/salgdi.hxx> + +#include <freetype/ftsynth.h> + +// Module +#include "gcach_ftyp.hxx" + +#include <vcl/graphite_features.hxx> +#include <vcl/graphite_adaptors.hxx> + +// Module private type definitions and forward declarations. +// +using gr::GrResult; +namespace +{ + inline float from_hinted(const int x) { + return static_cast<float>(x + 32) / 64.0; + } + typedef std::hash_map<long,bool> SilfMap; + SilfMap sSilfMap; +} + +// class CharacterRenderProperties implentation. +// +FontProperties::FontProperties(const FreetypeServerFont &font) throw() +{ + clrFore = gr::kclrBlack; + clrBack = gr::kclrTransparent; + + pixHeight = from_hinted(font.GetMetricsFT().height); + + switch (font.GetFontSelData().meWeight) + { + case WEIGHT_SEMIBOLD: case WEIGHT_BOLD: + case WEIGHT_ULTRABOLD: case WEIGHT_BLACK: + fBold = true; + break; + default : + fBold = false; + } + + switch (font.GetFontSelData().meItalic) + { + case ITALIC_NORMAL: case ITALIC_OBLIQUE: + fItalic = true; + break; + default : + fItalic = false; + } + + // Get the font name. + const sal_Unicode * name = font.GetFontSelData().maName.GetBuffer(); + const size_t name_sz = std::min(sizeof szFaceName/sizeof(wchar_t)-1, + size_t(font.GetFontSelData().maName.Len())); + + std::copy(name, name + name_sz, szFaceName); + szFaceName[name_sz] = '\0'; +} + +// class GraphiteFontAdaptor implementaion. +// +GraphiteFontAdaptor::GraphiteFontAdaptor(ServerFont & sfont, const sal_Int32 dpiX, const sal_Int32 dpiY) + : mrFont(static_cast<FreetypeServerFont &>(sfont)), + maFontProperties(static_cast<FreetypeServerFont &>(sfont)), + mnDpiX(dpiX), + mnDpiY(dpiY), + mfAscent(from_hinted(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().ascender)), + mfDescent(from_hinted(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().descender)), + mfEmUnits(static_cast<FreetypeServerFont &>(sfont).GetMetricsFT().y_ppem), + mpFeatures(NULL) +{ + //std::wstring face_name(maFontProperties.szFaceName); + const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( sfont.GetFontSelData().meLanguage ); +#ifdef DEBUG + printf("GraphiteFontAdaptor %lx\n", (long)this); +#endif + rtl::OString name = rtl::OUStringToOString( + sfont.GetFontSelData().maTargetName, RTL_TEXTENCODING_UTF8 ); + sal_Int32 nFeat = name.indexOf(grutils::GrFeatureParser::FEAT_PREFIX) + 1; + if (nFeat > 0) + { + rtl::OString aFeat = name.copy(nFeat, name.getLength() - nFeat); + mpFeatures = new grutils::GrFeatureParser(*this, aFeat.getStr(), aLang.getStr()); +#ifdef DEBUG + printf("GraphiteFontAdaptor %s/%s/%s %x language %d features %d errors\n", + rtl::OUStringToOString( sfont.GetFontSelData().maName, + RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( sfont.GetFontSelData().maTargetName, + RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( sfont.GetFontSelData().maSearchName, + RTL_TEXTENCODING_UTF8 ).getStr(), + sfont.GetFontSelData().meLanguage, + (int)mpFeatures->getFontFeatures(NULL), mpFeatures->parseErrors()); +#endif + } + else + { + mpFeatures = new grutils::GrFeatureParser(*this, aLang.getStr()); + } +} + +GraphiteFontAdaptor::GraphiteFontAdaptor(const GraphiteFontAdaptor &rhs) throw() + : Font(rhs), + mrFont (rhs.mrFont), maFontProperties(rhs.maFontProperties), + mnDpiX(rhs.mnDpiX), mnDpiY(rhs.mnDpiY), + mfAscent(rhs.mfAscent), mfDescent(rhs.mfDescent), mfEmUnits(rhs.mfEmUnits), + mpFeatures(NULL) +{ + if (rhs.mpFeatures) mpFeatures = new grutils::GrFeatureParser(*(rhs.mpFeatures)); +} + + +GraphiteFontAdaptor::~GraphiteFontAdaptor() throw() +{ + maGlyphMetricMap.clear(); + if (mpFeatures) delete mpFeatures; + mpFeatures = NULL; +} + +void GraphiteFontAdaptor::UniqueCacheInfo(std::wstring & face_name_out, bool & bold_out, bool & italic_out) +{ + face_name_out = maFontProperties.szFaceName; + bold_out = maFontProperties.fBold; + italic_out = maFontProperties.fItalic; +} + +bool GraphiteFontAdaptor::IsGraphiteEnabledFont(ServerFont & font) throw() +{ + // NOTE: this assumes that the same FTFace pointer won't be reused, + // so FtFontInfo::ReleaseFaceFT must only be called at shutdown. + FreetypeServerFont & aFtFont = dynamic_cast<FreetypeServerFont &>(font); + FT_Face aFace = reinterpret_cast<FT_FaceRec_*>(aFtFont.GetFtFace()); + SilfMap::iterator i = sSilfMap.find(reinterpret_cast<long>(aFace)); + if (i != sSilfMap.end()) + { +#ifdef DEBUG + if (static_cast<bool>(aFtFont.GetTable("Silf", 0)) != (*i).second) + printf("Silf cache font mismatch\n"); +#endif + return (*i).second; + } + bool bHasSilf = aFtFont.GetTable("Silf", 0); + sSilfMap[reinterpret_cast<long>(aFace)] = bHasSilf; + return bHasSilf; +} + + +gr::Font * GraphiteFontAdaptor::copyThis() { + return new GraphiteFontAdaptor(*this); +} + + +unsigned int GraphiteFontAdaptor::getDPIx() { + return mnDpiX; +} + + +unsigned int GraphiteFontAdaptor::getDPIy() { + return mnDpiY; +} + + +float GraphiteFontAdaptor::ascent() { + return mfAscent; +} + + +float GraphiteFontAdaptor::descent() { + return mfDescent; +} + + +bool GraphiteFontAdaptor::bold() { + return maFontProperties.fBold; +} + + +bool GraphiteFontAdaptor::italic() { + return maFontProperties.fItalic; +} + + +float GraphiteFontAdaptor::height() { + return maFontProperties.pixHeight; +} + + +void GraphiteFontAdaptor::getFontMetrics(float * ascent_out, float * descent_out, float * em_square_out) { + if (ascent_out) *ascent_out = mfAscent; + if (descent_out) *descent_out = mfDescent; + if (em_square_out) *em_square_out = mfEmUnits; +} + + +const void * GraphiteFontAdaptor::getTable(gr::fontTableId32 table_id, size_t * buffer_sz) +{ + char tag_name[5] = {char(table_id >> 24), char(table_id >> 16), char(table_id >> 8), char(table_id), 0}; + ULONG temp = *buffer_sz; + + const void * const tbl_buf = static_cast<FreetypeServerFont &>(mrFont).GetTable(tag_name, &temp); + *buffer_sz = temp; + + return tbl_buf; +} + +#define fix26_6(x) (x >> 6) + (x & 32 ? (x > 0 ? 1 : 0) : (x < 0 ? -1 : 0)) + +// Return the glyph's metrics in pixels. +void GraphiteFontAdaptor::getGlyphMetrics(gr::gid16 nGlyphId, gr::Rect & aBounding, gr::Point & advances) +{ + // Graphite gets really confused if the glyphs have been transformed, so + // if orientation has been set we can't use the font's glyph cache + // unfortunately the font selection data, doesn't always have the orientation + // set, even if it was when the glyphs were cached, so we use our own cache. + +// const GlyphMetric & metric = mrFont.GetGlyphMetric(nGlyphId); +// +// aBounding.right = aBounding.left = metric.GetOffset().X(); +// aBounding.bottom = aBounding.top = -metric.GetOffset().Y(); +// aBounding.right += metric.GetSize().Width(); +// aBounding.bottom -= metric.GetSize().Height(); +// +// advances.x = metric.GetDelta().X(); +// advances.y = -metric.GetDelta().Y(); + + GlyphMetricMap::const_iterator gm_itr = maGlyphMetricMap.find(nGlyphId); + if (gm_itr != maGlyphMetricMap.end()) + { + // We've cached the results from last time. + aBounding = gm_itr->second.first; + advances = gm_itr->second.second; + } + else + { + // We need to look up the glyph. + FT_Int nLoadFlags = mrFont.GetLoadFlags(); + + FT_Face aFace = reinterpret_cast<FT_Face>(mrFont.GetFtFace()); + if (!aFace) + { + aBounding.top = aBounding.bottom = aBounding.left = aBounding.right = 0; + advances.x = advances.y = 0; + return; + } + FT_Error aStatus = -1; + aStatus = FT_Load_Glyph(aFace, nGlyphId, nLoadFlags); + if( aStatus != FT_Err_Ok || (!aFace->glyph)) + { + aBounding.top = aBounding.bottom = aBounding.left = aBounding.right = 0; + advances.x = advances.y = 0; + return; + } + // check whether we need synthetic bold/italic otherwise metric is wrong + if (mrFont.NeedsArtificialBold()) + FT_GlyphSlot_Embolden(aFace->glyph); + + if (mrFont.NeedsArtificialItalic()) + FT_GlyphSlot_Oblique(aFace->glyph); + + const FT_Glyph_Metrics &gm = aFace->glyph->metrics; + + // Fill out the bounding box an advances. + aBounding.top = aBounding.bottom = fix26_6(gm.horiBearingY); + aBounding.bottom -= fix26_6(gm.height); + aBounding.left = aBounding.right = fix26_6(gm.horiBearingX); + aBounding.right += fix26_6(gm.width); + advances.x = fix26_6(gm.horiAdvance); + advances.y = 0; + + // Now add an entry to our metrics map. + maGlyphMetricMap[nGlyphId] = std::make_pair(aBounding, advances); + } +} + +#endif diff --git a/vcl/source/glyphs/graphite_cache.cxx b/vcl/source/glyphs/graphite_cache.cxx new file mode 100644 index 000000000000..c1bca0f87cb8 --- /dev/null +++ b/vcl/source/glyphs/graphite_cache.cxx @@ -0,0 +1,198 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#ifdef MSC +#include <tools/svwin.h> +#include <svsys.h> +#endif + +#include <tools/debug.hxx> +#include <vcl/sallayout.hxx> + +#include <graphite/GrClient.h> +#include <graphite/Segment.h> + +#include <rtl/ustring.hxx> +#include <vcl/graphite_layout.hxx> +#include <vcl/graphite_cache.hxx> + +#include "graphite_textsrc.hxx" + +GrSegRecord::GrSegRecord(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl) + : m_rope(rope), m_text(textSrc), m_seg(seg), m_nextKey(NULL), + m_fontScale(0.0f), mbIsRtl(bIsRtl), m_lockCount(0) +{ + m_pStr = textSrc->getLayoutArgs().mpStr + seg->startCharacter(); + m_startChar = seg->startCharacter(); +} + +GrSegRecord::~GrSegRecord() +{ + clear(); +} + +void GrSegRecord::reuse(rtl::OUString * rope, TextSourceAdaptor * textSrc, gr::Segment * seg, bool bIsRtl) +{ + clear(); + mnWidth = 0; + m_rope = rope; + m_text = textSrc; + m_seg = seg; + m_nextKey = NULL; + m_pStr = textSrc->getLayoutArgs().mpStr + seg->startCharacter(); + m_startChar = seg->startCharacter(); + mbIsRtl = bIsRtl; +} + +void GrSegRecord::clearVectors() +{ + mvGlyphs.clear(); + mvCharDxs.clear(); + mvChar2BaseGlyph.clear(); + mvGlyph2Char.clear(); +} + +void GrSegRecord::clear() +{ +#ifdef GR_DEBUG_TEXT + if (m_lockCount != 0) + OutputDebugString("GrSegRecord locked!"); +#endif + clearVectors(); + delete m_rope; + delete m_seg; + delete m_text; + m_rope = NULL; + m_seg = NULL; + m_text = NULL; + m_fontScale = 0.0f; + m_lockCount = 0; +} + +GrSegRecord * GraphiteSegmentCache::cacheSegment(TextSourceAdaptor * adapter, gr::Segment * seg, bool bIsRtl) +{ + GrSegRecord * record = NULL; + // We keep a record of the oldest key and the last key added + // when the next key is added, the record for the prevKey's m_nextKey field + // is updated to the newest key so that m_oldestKey can be updated to the + // next oldest key when the record for m_oldestKey is deleted + if (m_segMap.size() > SEG_CACHE_SIZE) + { + GraphiteSegMap::iterator oldestPair = m_segMap.find(reinterpret_cast<long>(m_oldestKey)); + // oldest record may no longer exist if a buffer was changed + if (oldestPair != m_segMap.end()) + { + record = oldestPair->second; + m_segMap.erase(reinterpret_cast<long>(m_oldestKey)); + GrRMEntry range = m_ropeMap.equal_range((*(record->m_rope)).hashCode()); + while (range.first != range.second) + { + if (range.first->second == record) + { + m_ropeMap.erase(range.first); + break; + } + ++range.first; + } + m_oldestKey = record->m_nextKey; + // record will be reused, so don't delete + } + } + + +// const int seg_char_limit = min(adapter->maLayoutArgs().mnLength, +// adapter->maLayoutArgs().mnEndCharPos +// + GraphiteLayout::EXTRA_CONTEXT_LENGTH); +// if (seg->stopCharacter() - seg->startCharacter() <= 0) +// OutputDebugString("Invalid seg indices\n"); + rtl::OUString * pRope = new rtl::OUString(adapter->getLayoutArgs().mpStr + seg->startCharacter(), + seg->stopCharacter() - seg->startCharacter()); + if (!pRope) return NULL; + bool reuse = false; + if (record) + record->reuse(pRope, adapter, seg, bIsRtl); + else + record = new GrSegRecord(pRope, adapter, seg, bIsRtl); + if (!record) + { + delete pRope; + return NULL; + } + GraphiteSegMap::iterator iMap = + m_segMap.find(reinterpret_cast<long>(record->m_pStr)); + if (iMap != m_segMap.end()) + { + // the buffer has changed, so the old cached Segment is useless + reuse = true; + GrSegRecord * found = iMap->second; + // Note: we reuse the old next key to avoid breaking our history + // chain. This means it will be prematurely deleted, but this is + // unlikely to happen very often. + record->m_nextKey = found->m_nextKey; + // overwrite the old record + m_segMap[reinterpret_cast<long>(record->m_pStr)] = record; + // erase the old rope key and save the new one + GrRMEntry range = m_ropeMap.equal_range((*(found->m_rope)).hashCode()); + while (range.first != range.second) + { + if (range.first->second == found) + { + m_ropeMap.erase(range.first); + break; + } + ++range.first; + } + GraphiteRopeMap::value_type mapEntry(record->m_rope->hashCode(), record); + m_ropeMap.insert(mapEntry); + // remove the old record + delete found; + record->m_lockCount++; + return record; + } + m_segMap[reinterpret_cast<long>(record->m_pStr)] = record; + GraphiteRopeMap::value_type mapEntry((*(record->m_rope)).hashCode(), record); + m_ropeMap.insert(mapEntry); + + if (m_oldestKey == NULL) + { + m_oldestKey = record->m_pStr; + m_prevKey = record->m_pStr; + } + else if (reuse == false) + { + DBG_ASSERT(m_segMap.count(reinterpret_cast<long>(m_prevKey)), + "Previous key got lost somehow!"); + m_segMap.find(reinterpret_cast<long>(m_prevKey)) + ->second->m_nextKey = record->m_pStr; + m_prevKey = record->m_pStr; + } + record->m_lockCount++; + return record; +} diff --git a/vcl/source/glyphs/graphite_features.cxx b/vcl/source/glyphs/graphite_features.cxx new file mode 100644 index 000000000000..3c5214d3c420 --- /dev/null +++ b/vcl/source/glyphs/graphite_features.cxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// Description: +// Parse a string of features specified as & separated pairs. +// e.g. +// 1001=1&2002=2&fav1=0 + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <sal/types.h> + +#ifdef MSC +#include <tools/svwin.h> +#include <svsys.h> +#endif + +#include <vcl/graphite_features.hxx> + +using namespace grutils; +// These mustn't conflict with font name lists which use ; and , +const char GrFeatureParser::FEAT_PREFIX = ':'; +const char GrFeatureParser::FEAT_SEPARATOR = '&'; +const char GrFeatureParser::FEAT_ID_VALUE_SEPARATOR = '='; +const std::string GrFeatureParser::ISO_LANG("lang"); + +GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string lang) + : mnNumSettings(0), mbErrors(false) +{ + maLang.rgch[0] = maLang.rgch[1] = maLang.rgch[2] = maLang.rgch[3] = '\0'; + setLang(font, lang); +} + +GrFeatureParser::GrFeatureParser(gr::Font & font, const std::string features, const std::string lang) + : mnNumSettings(0), mbErrors(false) +{ + size_t nEquals = 0; + size_t nFeatEnd = 0; + size_t pos = 0; + maLang.rgch[0] = maLang.rgch[1] = maLang.rgch[2] = maLang.rgch[3] = '\0'; + setLang(font, lang); + while (pos < features.length() && mnNumSettings < MAX_FEATURES) + { + nEquals = features.find(FEAT_ID_VALUE_SEPARATOR,pos); + if (nEquals == std::string::npos) + { + mbErrors = true; + break; + } + // check for a lang=xxx specification + if (features.compare(pos, nEquals - pos, ISO_LANG) == 0) + { + pos = nEquals + 1; + nFeatEnd = features.find(FEAT_SEPARATOR, pos); + if (nFeatEnd == std::string::npos) + { + nFeatEnd = features.length(); + } + if (nFeatEnd - pos > 3) + mbErrors = true; + else + { + gr::isocode aLang = maLang; + for (size_t i = pos; i < nFeatEnd; i++) + aLang.rgch[i-pos] = features[i]; + std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported + = font.getSupportedLanguages(); + gr::LanguageIterator iL = aSupported.first; + while (iL != aSupported.second) + { + gr::isocode aSupportedLang = *iL; + // here we only expect full 3 letter codes + if (aLang.rgch[0] == aSupportedLang.rgch[0] && + aLang.rgch[1] == aSupportedLang.rgch[1] && + aLang.rgch[2] == aSupportedLang.rgch[2] && + aLang.rgch[3] == aSupportedLang.rgch[3]) break; + ++iL; + } + if (iL == aSupported.second) mbErrors = true; + else maLang = aLang; + } + } + else + { + if (isCharId(features, pos, nEquals - pos)) + maSettings[mnNumSettings].id = getCharId(features, pos, nEquals - pos); + else maSettings[mnNumSettings].id = getIntValue(features, pos, nEquals - pos); + pos = nEquals + 1; + nFeatEnd = features.find(FEAT_SEPARATOR, pos); + if (nFeatEnd == std::string::npos) + { + nFeatEnd = features.length(); + } + if (isCharId(features, pos, nFeatEnd - pos)) + maSettings[mnNumSettings].value = getCharId(features, pos, nFeatEnd - pos); + else + maSettings[mnNumSettings].value= getIntValue(features, pos, nFeatEnd - pos); + if (isValid(font, maSettings[mnNumSettings])) + mnNumSettings++; + else + mbErrors = true; + } + pos = nFeatEnd + 1; + } +} + +void GrFeatureParser::setLang(gr::Font & font, const std::string & lang) +{ + gr::isocode aLang = {{0,0,0,0}}; + if (lang.length() > 2) + { + for (size_t i = 0; i < lang.length() && i < 3; i++) + { + if (lang[i] == '-') break; + aLang.rgch[i] = lang[i]; + } + std::pair<gr::LanguageIterator,gr::LanguageIterator> aSupported + = font.getSupportedLanguages(); + gr::LanguageIterator iL = aSupported.first; + while (iL != aSupported.second) + { + gr::isocode aSupportedLang = *iL; + if (aLang.rgch[0] == aSupportedLang.rgch[0] && + aLang.rgch[1] == aSupportedLang.rgch[1] && + aLang.rgch[2] == aSupportedLang.rgch[2] && + aLang.rgch[3] == aSupportedLang.rgch[3]) break; + ++iL; + } + if (iL != aSupported.second) + maLang = aLang; +#ifdef DEBUG + else + printf("%s has no features\n", aLang.rgch); +#endif + } +} + +GrFeatureParser::GrFeatureParser(const GrFeatureParser & aCopy) + : maLang(aCopy.maLang), mbErrors(aCopy.mbErrors) +{ + mnNumSettings = aCopy.getFontFeatures(maSettings); +} + +GrFeatureParser::~GrFeatureParser() +{ +} + +size_t GrFeatureParser::getFontFeatures(gr::FeatureSetting settings[64]) const +{ + if (settings) + { + std::copy(maSettings, maSettings + mnNumSettings, settings); + } + return mnNumSettings; +} + +bool GrFeatureParser::isValid(gr::Font & font, gr::FeatureSetting & setting) +{ + gr::FeatureIterator i = font.featureWithID(setting.id); + if (font.getFeatures().second == i) + { + return false; + } + std::pair< gr::FeatureSettingIterator, gr::FeatureSettingIterator > + validValues = font.getFeatureSettings(i); + gr::FeatureSettingIterator j = validValues.first; + while (j != validValues.second) + { + if (*j == setting.value) return true; + ++j; + } + return false; +} + +bool GrFeatureParser::isCharId(const std::string & id, size_t offset, size_t length) +{ + if (length > 4) return false; + for (size_t i = 0; i < length; i++) + { + if (i > 0 && id[offset+i] == '\0') continue; + if ((id[offset+i]) < 0x20 || (id[offset+i]) < 0) + return false; + if (i==0 && id[offset+i] < 0x41) + return false; + } + return true; +} + +int GrFeatureParser::getCharId(const std::string & id, size_t offset, size_t length) +{ + FeatId charId; + charId.num = 0; +#ifdef WORDS_BIGENDIAN + for (size_t i = 0; i < length; i++) + { + charId.label[i] = id[offset+i]; + } +#else + for (size_t i = 0; i < length; i++) + { + charId.label[3-i] = id[offset+i]; + } +#endif + return charId.num; +} + +int GrFeatureParser::getIntValue(const std::string & id, size_t offset, size_t length) +{ + int value = 0; + int sign = 1; + for (size_t i = 0; i < length; i++) + { + switch (id[offset + i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + value *= 10; + if (sign < 0) + { + value = -(id[offset + i] - '0'); + sign = 1; + } + value += (id[offset + i] - '0'); + break; + case '-': + if (i == 0) + sign = -1; + else + { + mbErrors = true; + break; + } + default: + mbErrors = true; + break; + } + } + return value; +} + + +sal_Int32 GrFeatureParser::hashCode() const +{ + union IsoHash { sal_Int32 mInt; gr::isocode mCode; }; + IsoHash isoHash; + isoHash.mCode = maLang; + sal_Int32 hash = isoHash.mInt; + for (size_t i = 0; i < mnNumSettings; i++) + { + hash = (hash << 16) ^ ((maSettings[i].id << 8) | maSettings[i].value); + } + return hash; +} diff --git a/vcl/source/glyphs/graphite_layout.cxx b/vcl/source/glyphs/graphite_layout.cxx new file mode 100644 index 000000000000..751c3694d033 --- /dev/null +++ b/vcl/source/glyphs/graphite_layout.cxx @@ -0,0 +1,1367 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// Description: An implementation of the SalLayout interface that uses the +// Graphite engine. + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +// Enable lots of debug info +#ifdef DEBUG +//#define GRLAYOUT_DEBUG 1 +//#undef NDEBUG +#endif + +// Header files +// +// Standard Library +#include <algorithm> +#include <cassert> +#include <functional> +#include <limits> +#include <numeric> +#include <deque> + +// Platform +#ifdef MSC +#include <tools/svwin.h> +#include <svsys.h> +#endif + +#include <vcl/salgdi.hxx> + +#include <unicode/uchar.h> +#include <unicode/ubidi.h> +#include <unicode/uscript.h> + +// Graphite Libraries (must be after vcl headers on windows) +#include <graphite/GrClient.h> +#include <graphite/Font.h> +#include <graphite/ITextSource.h> +#include <graphite/Segment.h> +#include <graphite/SegmentPainter.h> + +#include <vcl/graphite_layout.hxx> +#include <vcl/graphite_features.hxx> +#include "graphite_textsrc.hxx" + + +// Module private type definitions and forward declarations. +// +// Module private names. +// + +#ifdef GRLAYOUT_DEBUG +FILE * grLogFile = NULL; +FILE * grLog() +{ +#ifdef MSC + std::string logFileName(getenv("TEMP")); + logFileName.append("\\graphitelayout.log"); + if (grLogFile == NULL) grLogFile = fopen(logFileName.c_str(),"w"); + else fflush(grLogFile); + return grLogFile; +#else + return stdout; +#endif +} +#endif + +#ifdef GRCACHE +#include <vcl/graphite_cache.hxx> +#endif + + +namespace +{ + typedef std::pair<gr::GlyphIterator, gr::GlyphIterator> glyph_range_t; + typedef std::pair<gr::GlyphSetIterator, gr::GlyphSetIterator> glyph_set_range_t; + + inline long round(const float n) { + return long(n + (n < 0 ? -0.5 : 0.5)); + } + + + template<typename T> + inline bool in_range(const T i, const T b, const T e) { + return !(b > i) && i < e; + } + + + template<typename T> + inline bool is_subrange(const T sb, const T se, const T b, const T e) { + return !(b > sb || se > e); + } + + + template<typename T> + inline bool is_subrange(const std::pair<T, T> &s, const T b, const T e) { + return is_subrange(s.first, s.second, b, e); + } + + int findSameDirLimit(const xub_Unicode* buffer, int charCount, bool rtl) + { + UErrorCode status = U_ZERO_ERROR; + UBiDi *ubidi = ubidi_openSized(charCount, 0, &status); + int limit = 0; + ubidi_setPara(ubidi, buffer, charCount, + (rtl)?UBIDI_DEFAULT_RTL:UBIDI_DEFAULT_LTR, NULL, &status); + UBiDiLevel level = 0; + ubidi_getLogicalRun(ubidi, 0, &limit, &level); + ubidi_close(ubidi); + if ((rtl && !(level & 1)) || (!rtl && (level & 1))) + { + limit = 0; + } + return limit; + } + +} // namespace + + + +// Impementation of the GraphiteLayout::Glyphs container class. +// This is an extended vector class with methods added to enable +// o Correctly filling with glyphs. +// o Querying clustering relationships. +// o manipulations that affect neighouring glyphs. + +const int GraphiteLayout::EXTRA_CONTEXT_LENGTH = 10; +#ifdef GRCACHE +GraphiteCacheHandler GraphiteCacheHandler::instance; +#endif + +// The Graphite glyph stream is really a sequence of glyph attachment trees +// each rooted at a non-attached base glyph. fill_from walks the glyph stream +// find each non-attached base glyph and calls append to record them as a +// sequence of clusters. +void +GraphiteLayout::Glyphs::fill_from(gr::Segment & rSegment, ImplLayoutArgs &rArgs, + bool bRtl, long &rWidth, float fScaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs) +{ + // Create a glyph item for each of the glyph and append it to the base class glyph list. + typedef std::pair< gr::GlyphSetIterator, gr::GlyphSetIterator > GrGlyphSet; + int nChar = rArgs.mnEndCharPos - rArgs.mnMinCharPos; + glyph_range_t iGlyphs = rSegment.glyphs(); + int nGlyphs = iGlyphs.second - iGlyphs.first; + gr::GlyphIterator prevBase = iGlyphs.second; + float fMinX = rSegment.advanceWidth(); + float fMaxX = 0.0f; + rGlyph2Char.assign(nGlyphs, -1); + long nDxOffset = 0; + int nGlyphIndex = (bRtl)? (nGlyphs - 1) : 0; + // OOo always expects the glyphs in ltr order + int nDelta = (bRtl)? -1 : 1; + + int nLastGlyph = (bRtl)? nGlyphs - 1: 0; + int nNextChar = (bRtl)? (rSegment.stopCharacter() - 1) : rSegment.startCharacter();//rArgs.mnMinCharPos; + // current glyph number (Graphite glyphs) + //int currGlyph = 0; + int nFirstCharInCluster = nNextChar; + int nFirstGlyphInCluster = nLastGlyph; + + // ltr first char in cluster is lowest, same is true for rtl + // ltr first glyph in cluster is lowest, rtl first glyph is highest + + // loop over the glyphs determining which characters are linked to them + gr::GlyphIterator gi; + for (gi = iGlyphs.first + nGlyphIndex; + nGlyphIndex >= 0 && nGlyphIndex < nGlyphs; + nGlyphIndex+= nDelta, gi = iGlyphs.first + nGlyphIndex) + { + gr::GlyphInfo info = (*gi); +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Glyph %d %f,%f\n", (int)info.logicalIndex(), info.origin(), info.yOffset()); +#endif + // the last character associated with this glyph is after + // our current cluster buffer position + if ((bRtl && ((signed)info.firstChar() <= nNextChar)) || + (!bRtl && ((signed)info.lastChar() >= nNextChar))) + { + if ((bRtl && nGlyphIndex < nLastGlyph) || + (!bRtl && nGlyphIndex > nLastGlyph)) + { + // this glyph is after the previous one left->right + // if insertion is allowed before it then we are in a + // new cluster + int nAttachedBase = (*(info.attachedClusterBase())).logicalIndex(); + if (!info.isAttached() || + !in_range(nAttachedBase, nFirstGlyphInCluster, nGlyphIndex)) + { + if (in_range(nFirstCharInCluster, rArgs.mnMinCharPos, rArgs.mnEndCharPos) && + nFirstGlyphInCluster != nGlyphIndex) + { + std::pair <float,float> aBounds = + appendCluster(rSegment, rArgs, bRtl, nFirstCharInCluster, + nNextChar, nFirstGlyphInCluster, nGlyphIndex, fScaling, + rChar2Base, rGlyph2Char, rCharDxs, nDxOffset); + fMinX = std::min(aBounds.first, fMinX); + fMaxX = std::max(aBounds.second, fMaxX); + } + nFirstCharInCluster = (bRtl)? info.lastChar() : info.firstChar(); + nFirstGlyphInCluster = nGlyphIndex; + } + nLastGlyph = (bRtl)? std::min(nGlyphIndex, nAttachedBase) : + std::max(nGlyphIndex, nAttachedBase); + } + // loop over chacters associated with this glyph and characters + // between nextChar and the last character associated with this glyph + // giving them the current cluster id. This allows for character /glyph + // order reversal. + // For each character we do a reverse glyph id look up + // and store the glyph id with the highest logical index in nLastGlyph + while ((bRtl && ((signed)info.firstChar() <= nNextChar)) || + (!bRtl && (signed)info.lastChar() >= nNextChar)) + { + GrGlyphSet charGlyphs = rSegment.charToGlyphs(nNextChar); + nNextChar += nDelta; + gr::GlyphSetIterator gj = charGlyphs.first; + while (gj != charGlyphs.second) + { + nLastGlyph = (bRtl)? min(nLastGlyph, (signed)(*gj).logicalIndex()) : max(nLastGlyph, (signed)(*gj).logicalIndex()); + ++gj; + } + } + // Loop over attached glyphs and make sure they are all in the cluster since you + // can have glyphs attached with another base glyph in between + glyph_set_range_t iAttached = info.attachedClusterGlyphs(); + for (gr::GlyphSetIterator agi = iAttached.first; agi != iAttached.second; ++agi) + { + nLastGlyph = (bRtl)? min(nLastGlyph, (signed)(*agi).logicalIndex()) : max(nLastGlyph, (signed)(*agi).logicalIndex()); + } + + // if this is a rtl attached glyph, then we need to include its + // base in the cluster, which will have a lower graphite index + if (bRtl) + { + if ((signed)info.attachedClusterBase()->logicalIndex() < nLastGlyph) + { + nLastGlyph = info.attachedClusterBase()->logicalIndex(); + } + } + } + + // it is possible for the lastChar to be after nextChar and + // firstChar to be before the nFirstCharInCluster in rare + // circumstances e.g. Myanmar word for cemetery + if ((bRtl && ((signed)info.lastChar() > nFirstCharInCluster)) || + (!bRtl && ((signed)info.firstChar() < nFirstCharInCluster))) + { + nFirstCharInCluster = info.firstChar(); + } + } + // process last cluster + if (in_range(nFirstCharInCluster, rArgs.mnMinCharPos, rArgs.mnEndCharPos) && + nFirstGlyphInCluster != nGlyphIndex) + { + std::pair <float,float> aBounds = + appendCluster(rSegment, rArgs, bRtl, nFirstCharInCluster, nNextChar, + nFirstGlyphInCluster, nGlyphIndex, fScaling, + rChar2Base, rGlyph2Char, rCharDxs, nDxOffset); + fMinX = std::min(aBounds.first, fMinX); + fMaxX = std::max(aBounds.second, fMaxX); + } + long nXOffset = round(fMinX * fScaling); + rWidth = round(fMaxX * fScaling) - nXOffset + nDxOffset; + if (rWidth < 0) + { + // This can happen when there was no base inside the range + rWidth = 0; + } + // fill up non-base char dx with cluster widths from previous base glyph + if (bRtl) + { + if (rCharDxs[nChar-1] == -1) + rCharDxs[nChar-1] = 0; + else + rCharDxs[nChar-1] -= nXOffset; + for (int i = nChar - 2; i >= 0; i--) + { + if (rCharDxs[i] == -1) rCharDxs[i] = rCharDxs[i+1]; + else rCharDxs[i] -= nXOffset; + } + } + else + { + if (rCharDxs[0] == -1) + rCharDxs[0] = 0; + else + rCharDxs[0] -= nXOffset; + for (int i = 1; i < nChar; i++) + { + if (rCharDxs[i] == -1) rCharDxs[i] = rCharDxs[i-1]; + else rCharDxs[i] -= nXOffset; + } + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Glyphs xOff%ld dropDx%ld w%ld\n", nXOffset, nDxOffset, rWidth); +#endif + // remove offset due to context if there is one + if (nXOffset != 0) + { + for (size_t i = 0; i < size(); i++) + (*this)[i].maLinearPos.X() -= nXOffset; + } +} + +std::pair<float,float> GraphiteLayout::Glyphs::appendCluster(gr::Segment & rSeg, + ImplLayoutArgs & rArgs, bool bRtl, int nFirstCharInCluster, int nNextChar, + int nFirstGlyphInCluster, int nNextGlyph, float fScaling, + std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, + std::vector<int> & rCharDxs, long & rDXOffset) +{ + glyph_range_t iGlyphs = rSeg.glyphs(); + int nGlyphs = iGlyphs.second - iGlyphs.first; + int nDelta = (bRtl)? -1 : 1; + gr::GlyphInfo aFirstGlyph = *(iGlyphs.first + nFirstGlyphInCluster); + std::pair <float, float> aBounds; + aBounds.first = aFirstGlyph.origin(); + aBounds.second = aFirstGlyph.origin(); + // before we add the glyphs to this vector, we record the + // glyph's index in the vector (which is not the same as + // the Segment's glyph index!) + assert(size() < rGlyph2Char.size()); + rChar2Base[nFirstCharInCluster-rArgs.mnMinCharPos] = size(); + rGlyph2Char[size()] = nFirstCharInCluster; + bool bBaseGlyph = true; + for (int j = nFirstGlyphInCluster; + j != nNextGlyph; j += nDelta) + { + long nNextOrigin; + float fNextOrigin; + gr::GlyphInfo aGlyph = *(iGlyphs.first + j); + if (j + nDelta >= nGlyphs || j + nDelta < 0) // at rhs ltr,rtl + { + fNextOrigin = rSeg.advanceWidth(); + nNextOrigin = round(rSeg.advanceWidth() * fScaling + rDXOffset); + aBounds.second = std::max(rSeg.advanceWidth(), aBounds.second); + } + else + { + gr::GlyphInfo aNextGlyph = *(iGlyphs.first + j + nDelta); + fNextOrigin = std::max(aNextGlyph.attachedClusterBase()->origin(), aNextGlyph.origin()); + aBounds.second = std::max(fNextOrigin, aBounds.second); + nNextOrigin = round(fNextOrigin * fScaling + rDXOffset); + } + aBounds.first = std::min(aGlyph.origin(), aBounds.first); + if ((signed)aGlyph.firstChar() < rArgs.mnEndCharPos && + (signed)aGlyph.firstChar() >= rArgs.mnMinCharPos) + { + rCharDxs[aGlyph.firstChar()-rArgs.mnMinCharPos] = nNextOrigin; + } + if ((signed)aGlyph.attachedClusterBase()->logicalIndex() == j) + { + append(rSeg, rArgs, aGlyph, fNextOrigin, fScaling, rChar2Base, rGlyph2Char, rCharDxs, rDXOffset, bBaseGlyph); + bBaseGlyph = false; + } + } + // from the point of view of the dx array, the xpos is + // the origin of the first glyph of the next cluster ltr + // rtl it is the origin of the 1st glyph of the cluster + long nXPos = (bRtl)? + round(aFirstGlyph.attachedClusterBase()->origin() * fScaling) + rDXOffset : + round(aBounds.second * fScaling) + rDXOffset; + // force the last char in range to have the width of the cluster + if (bRtl) + { + for (int n = nNextChar + 1; n <= nFirstCharInCluster; n++) + { + if ((n < rArgs.mnEndCharPos) && (n >= rArgs.mnMinCharPos)) + rCharDxs[n-rArgs.mnMinCharPos] = nXPos; + } + } + else + { + for (int n = nNextChar - 1; n >= nFirstCharInCluster; n--) + { + if (n < rArgs.mnEndCharPos && n >= rArgs.mnMinCharPos) + rCharDxs[n-rArgs.mnMinCharPos] = nXPos; + } + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Cluster g[%d-%d) c[%d-%d)%x x%ld y%f\n", nFirstGlyphInCluster, nNextGlyph, nFirstCharInCluster, nNextChar, rArgs.mpStr[nFirstCharInCluster], nXPos, aFirstGlyph.yOffset()); +#endif + return aBounds; +} + +// append walks an attachment tree, flattening it, and converting it into a +// sequence of GlyphItem objects which we can later manipulate. +void +GraphiteLayout::Glyphs::append(gr::Segment &segment, ImplLayoutArgs &args, gr::GlyphInfo & gi, float nextGlyphOrigin, float scaling, std::vector<int> & rChar2Base, std::vector<int> & rGlyph2Char, std::vector<int> & rCharDxs, long & rDXOffset, bool bIsBase) +{ + float nextOrigin = nextGlyphOrigin; + int firstChar = std::min(gi.firstChar(), gi.lastChar()); + assert(size() < rGlyph2Char.size()); + if (!bIsBase) rGlyph2Char[size()] = firstChar; + // is the next glyph attached or in the next cluster? + glyph_set_range_t iAttached = gi.attachedClusterGlyphs(); + if (iAttached.first != iAttached.second) + { + nextOrigin = iAttached.first->origin(); + } + long glyphId = gi.glyphID(); + long deltaOffset = 0; + int glyphWidth = round(nextOrigin * scaling) - round(gi.origin() * scaling); +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"c%d g%d gWidth%d x%f ", firstChar, (int)gi.logicalIndex(), glyphWidth, nextOrigin); +#endif + if (glyphId == 0) + { + args.NeedFallback( + firstChar, + gr::RightToLeftDir(gr::DirCode(gi.directionality()))); + if( (SAL_LAYOUT_FOR_FALLBACK & args.mnFlags )) + { + glyphId = GF_DROPPED; + deltaOffset -= glyphWidth; + glyphWidth = 0; + } + } + else if(args.mnFlags & SAL_LAYOUT_FOR_FALLBACK) + { +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"fallback c%d %x in run %d\n", firstChar, args.mpStr[firstChar], + args.maRuns.PosIsInAnyRun(firstChar)); +#endif + // glyphs that aren't requested for fallback will be taken from base + // layout, so mark them as dropped (should this wait until Simplify(false) is called?) + if (!args.maRuns.PosIsInAnyRun(firstChar) && + in_range(firstChar, args.mnMinCharPos, args.mnEndCharPos)) + { + glyphId = GF_DROPPED; + deltaOffset -= glyphWidth; + glyphWidth = 0; + } + } + // append this glyph. + long nGlyphFlags = bIsBase ? 0 : GlyphItem::IS_IN_CLUSTER; + // directionality seems to be unreliable + //nGlyphFlags |= gr::RightToLeftDir(gr::DirCode(gi.attachedClusterBase()->directionality())) ? GlyphItem::IS_RTL_GLYPH : 0; + nGlyphFlags |= (gi.directionLevel() & 0x1)? GlyphItem::IS_RTL_GLYPH : 0; + GlyphItem aGlyphItem(size(),//gi.logicalIndex(), + glyphId, + Point(round(gi.origin() * scaling + rDXOffset), + round((-gi.yOffset() * scaling) - segment.AscentOffset()* scaling)), + nGlyphFlags, + glyphWidth); + aGlyphItem.mnOrigWidth = round(gi.advanceWidth() * scaling); + push_back(aGlyphItem); + + // update the offset if this glyph was dropped + rDXOffset += deltaOffset; + + // Recursively apply append all the attached glyphs. + for (gr::GlyphSetIterator agi = iAttached.first; agi != iAttached.second; ++agi) + { + if (agi + 1 == iAttached.second) + append(segment, args, *agi, nextGlyphOrigin, scaling, rChar2Base, rGlyph2Char,rCharDxs, rDXOffset, false); + else + append(segment, args, *agi, (agi + 1)->origin(), scaling, rChar2Base, rGlyph2Char, rCharDxs, rDXOffset, false); + } +} + +// +// An implementation of the SalLayout interface to enable Graphite enabled fonts to be used. +// +GraphiteLayout::GraphiteLayout(const gr::Font & font, const grutils::GrFeatureParser * pFeatures) throw() + : mpTextSrc(0), + mrFont(font), + mnWidth(0), + mfScaling(1.0), + mpFeatures(pFeatures) +{ + // Line settings can have subtle affects on space handling + // since we don't really know whether it is the end of a line or just a run + // in the middle, it is hard to know what to set them to. + // If true, it can cause end of line spaces to be hidden e.g. Doulos SIL + maLayout.setStartOfLine(false); + maLayout.setEndOfLine(false); +// maLayout.setDumbFallback(false); + // trailing ws doesn't seem to always take affect if end of line is true + maLayout.setTrailingWs(gr::ktwshAll); +#ifdef GRLAYOUT_DEBUG + gr::ScriptDirCode aDirCode = font.getSupportedScriptDirections(); + fprintf(grLog(),"GraphiteLayout scripts %x %lx\n", aDirCode, long(this)); +#endif +} + + +GraphiteLayout::~GraphiteLayout() throw() +{ + clear(); + // the features are owned by the platform layers + mpFeatures = NULL; +} + +void GraphiteLayout::clear() +{ + // Destroy the segment and text source from any previous invocation of + // LayoutText + mvGlyphs.clear(); + mvCharDxs.clear(); + mvChar2BaseGlyph.clear(); + mvGlyph2Char.clear(); + +#ifndef GRCACHE + delete mpTextSrc; +#endif + + // Reset the state to the empty state. + mpTextSrc=0; + mnWidth = 0; + // Don't reset the scaling, because it is set before LayoutText +} + +// This method shouldn't be called on windows, since it needs the dc reset +bool GraphiteLayout::LayoutText(ImplLayoutArgs & rArgs) +{ +#ifdef GRCACHE + GrSegRecord * pSegRecord = NULL; + gr::Segment * pSegment = CreateSegment(rArgs, &pSegRecord); + if (!pSegment) + return false; + + // layout the glyphs as required by OpenOffice + bool success = LayoutGlyphs(rArgs, pSegment, pSegRecord); + + if (pSegRecord) pSegRecord->unlock(); + else delete pSegment; +#else + gr::Segment * pSegment = CreateSegment(rArgs); + bool success = LayoutGlyphs(rArgs, pSegment); + delete pSegment; +#endif + return success; +} + +#ifdef GRCACHE +class GrFontHasher : public gr::Font +{ +public: + GrFontHasher(const gr::Font & aFont) : gr::Font(aFont), mrRealFont(const_cast<gr::Font&>(aFont)) {}; + ~GrFontHasher(){}; + virtual bool bold() { return mrRealFont.bold(); }; + virtual bool italic() { return mrRealFont.italic(); }; + virtual float ascent() { return mrRealFont.ascent(); }; + virtual float descent() { return mrRealFont.descent(); }; + virtual float height() { return mrRealFont.height(); }; + virtual gr::Font* copyThis() { return mrRealFont.copyThis(); }; + virtual unsigned int getDPIx() { return mrRealFont.getDPIx(); }; + virtual unsigned int getDPIy() { return mrRealFont.getDPIy(); }; + virtual const void* getTable(gr::fontTableId32 nId, size_t* nSize) + { return mrRealFont.getTable(nId,nSize); } + virtual void getFontMetrics(float*pA, float*pB, float*pC) { mrRealFont.getFontMetrics(pA,pB,pC); }; + + sal_Int32 hashCode(const grutils::GrFeatureParser * mpFeatures) + { + // is this sufficient? + std::wstring aFace; + bool bBold; + bool bItalic; + UniqueCacheInfo(aFace, bBold, bItalic); + sal_Unicode uName[32]; // max length used in gr::Font + // Note: graphite stores font names as UTF-16 even if wchar_t is 32bit + // this conversion should be OK. + for (size_t i = 0; i < aFace.size() && i < 32; i++) + { + uName[i] = aFace[i]; + } + size_t iSize = aFace.size(); + if (0 == iSize) return 0; + sal_Int32 hash = rtl_ustr_hashCode_WithLength(uName, iSize); + hash ^= static_cast<sal_Int32>(height()); + hash |= (bBold)? 0x1000000 : 0; + hash |= (bItalic)? 0x2000000 : 0; + if (mpFeatures) + hash ^= mpFeatures->hashCode(); +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(), "font hash %x size %f\n", (int)hash, height()); +#endif + return hash; + }; + +private: + gr::Font & mrRealFont; +}; +#endif + +#ifdef GRCACHE +gr::Segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs, GrSegRecord ** pSegRecord) +#else +gr::Segment * GraphiteLayout::CreateSegment(ImplLayoutArgs& rArgs) +#endif +{ + assert(rArgs.mnLength >= 0); + + gr::Segment * pSegment = NULL; + + // Set the SalLayouts values to be the inital ones. + SalLayout::AdjustLayout(rArgs); + // TODO check if this is needed + if (mnUnitsPerPixel > 1) + mfScaling = 1.0f / mnUnitsPerPixel; + + // Clear out any previous buffers + clear(); + bool bRtl = mnLayoutFlags & SAL_LAYOUT_BIDI_RTL; + try + { + // Don't set RTL if font doesn't support it otherwise it forces rtl on + // everything + if (bRtl && (mrFont.getSupportedScriptDirections() & gr::kfsdcHorizRtl)) + maLayout.setRightToLeft(bRtl); + +#ifdef GRCACHE + GrFontHasher hasher(mrFont); + sal_Int32 aFontHash = hasher.hashCode(mpFeatures); + GraphiteSegmentCache * pCache = + (GraphiteCacheHandler::instance).getCache(aFontHash); + if (pCache) + { + *pSegRecord = pCache->getSegment(rArgs, bRtl); + if (*pSegRecord) + { + pSegment = (*pSegRecord)->getSegment(); + mpTextSrc = (*pSegRecord)->getTextSrc(); + maLayout.setRightToLeft((*pSegRecord)->isRtl()); + if (rArgs.mpStr != mpTextSrc->getLayoutArgs().mpStr || + rArgs.mnMinCharPos != mpTextSrc->getLayoutArgs().mnMinCharPos || + rArgs.mnEndCharPos != mpTextSrc->getLayoutArgs().mnEndCharPos || + (SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags) ) + { + (*pSegRecord)->clearVectors(); + } + mpTextSrc->switchLayoutArgs(rArgs); + return pSegment; + } + } +#endif + + // Context is often needed beyond the specified end, however, we don't + // want it if there has been a direction change, since it is hard + // to tell between reordering within one direction and multi-directional + // text. + const int segCharLimit = min(rArgs.mnLength, mnEndCharPos + EXTRA_CONTEXT_LENGTH); + int limit = rArgs.mnEndCharPos; + if (segCharLimit > limit) + { + limit += findSameDirLimit(rArgs.mpStr + rArgs.mnEndCharPos, + segCharLimit - rArgs.mnEndCharPos, bRtl); + } + + // Create a new TextSource object for the engine. + mpTextSrc = new TextSourceAdaptor(rArgs, limit); + if (mpFeatures) mpTextSrc->setFeatures(mpFeatures); + + pSegment = new gr::RangeSegment((gr::Font *)&mrFont, mpTextSrc, &maLayout, mnMinCharPos, limit); + if (pSegment != NULL) + { +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Gr::LayoutText %d-%d, context %d,len%d rtl%d/%d scaling %f\n", rArgs.mnMinCharPos, + rArgs.mnEndCharPos, limit, rArgs.mnLength, maLayout.rightToLeft(), pSegment->rightToLeft(), mfScaling); +#endif +#ifdef GRCACHE + // on a new segment rightToLeft should be correct + *pSegRecord = pCache->cacheSegment(mpTextSrc, pSegment, pSegment->rightToLeft()); +#endif + } + else + { + clear(); + return NULL; + } + } + catch (...) + { + clear(); // destroy the text source and any partially built segments. + return NULL; + } + return pSegment; +} + +#ifdef GRCACHE +bool GraphiteLayout::LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment, GrSegRecord * pSegRecord) +#else +bool GraphiteLayout::LayoutGlyphs(ImplLayoutArgs& rArgs, gr::Segment * pSegment) +#endif +{ +#ifdef GRCACHE +#ifdef GRCACHE_REUSE_VECTORS + // if we have an exact match, then we can reuse the glyph vectors from before + if (pSegRecord && (pSegRecord->glyphs().size() > 0) && + !(SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags) ) + { + mnWidth = pSegRecord->width(); + mvGlyphs = pSegRecord->glyphs(); + mvCharDxs = pSegRecord->charDxs(); + mvChar2BaseGlyph = pSegRecord->char2BaseGlyph(); + mvGlyph2Char = pSegRecord->glyph2Char(); + return true; + } +#endif +#endif + // Calculate the initial character dxs. + mvCharDxs.assign(mnEndCharPos - mnMinCharPos, -1); + mvChar2BaseGlyph.assign(mnEndCharPos - mnMinCharPos, -1); + mnWidth = 0; + if (mvCharDxs.size() > 0) + { + // Discover all the clusters. + try + { + // Note: we use the layout rightToLeft() because in cached segments + // rightToLeft() may no longer be valid if the engine has been run + // ltr since the segment was created. +#ifdef GRCACHE + bool bRtl = pSegRecord? pSegRecord->isRtl() : pSegment->rightToLeft(); +#else + bool bRtl = pSegment->rightToLeft(); +#endif + mvGlyphs.fill_from(*pSegment, rArgs, bRtl, + mnWidth, mfScaling, mvChar2BaseGlyph, mvGlyph2Char, mvCharDxs); + + if (bRtl) + { + // not needed for adjacent differences, but for mouse clicks to char + std::transform(mvCharDxs.begin(), mvCharDxs.end(), mvCharDxs.begin(), + std::bind1st(std::minus<long>(), mnWidth)); + // fixup last dx to ensure it always equals the width + mvCharDxs[mvCharDxs.size() - 1] = mnWidth; + } +#ifdef GRCACHE +#ifdef GRCACHE_REUSE_VECTORS + if (pSegRecord && rArgs.maReruns.IsEmpty() && + !(SAL_LAYOUT_FOR_FALLBACK & rArgs.mnFlags)) + { + pSegRecord->setGlyphVectors(mnWidth, mvGlyphs, mvCharDxs, + mvChar2BaseGlyph, mvGlyph2Char); + } +#endif +#endif + } + catch (std::exception e) + { +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"LayoutGlyphs failed %s\n", e.what()); +#endif + return false; + } + catch (...) + { +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"LayoutGlyphs failed with exception"); +#endif + return false; + } + } + else + { + mnWidth = 0; + } + return true; +} + +int GraphiteLayout::GetTextBreak(long maxmnWidth, long char_extra, int factor) const +{ + // Adjust maxmnWidth so FindNextBreakPoint returns a sensible answer. + maxmnWidth -= (mnEndCharPos-mnMinCharPos-1)*char_extra; // extra character spacing. + maxmnWidth /= factor; // scaling factor. + + // Ask the segment for the nearest whole letter break for the width. + //float width; + float targetWidth = maxmnWidth/mfScaling; + // return quickly if this segment is narrower than the target width + // (sometimes graphite doesn't seem to realise this!) + if (targetWidth > mnWidth) + return STRING_LEN; + //int nBreak = mpSegment->findNextBreakPoint(mnMinCharPos, + // gr::klbWordBreak, gr::klbLetterBreak, targetWidth, &width); + + // LineFillSegment seems to give better results that findNextBreakPoint + // though it may be slower + gr::LayoutEnvironment aLE; + gr::LineFillSegment lineSeg(const_cast<gr::Font *>(&mrFont), mpTextSrc, &aLE, + mnMinCharPos, mpTextSrc->getContextLength(), + targetWidth); + int nBreak = lineSeg.stopCharacter(); + + if (nBreak > mnEndCharPos) nBreak = STRING_LEN; + else if (nBreak < mnMinCharPos) nBreak = mnMinCharPos; + return nBreak; +} + + +long GraphiteLayout::FillDXArray( sal_Int32* pDXArray ) const +{ + if (mnEndCharPos == mnMinCharPos) + // Then we must be zero width! + return 0; + + if (pDXArray) + { + for (size_t i = 0; i < mvCharDxs.size(); i++) + { + assert((mvChar2BaseGlyph[i] >= -1) && (mvChar2BaseGlyph[i] < (signed)mvGlyphs.size())); + if (mvChar2BaseGlyph[i] != -1 && + mvGlyphs[mvChar2BaseGlyph[i]].mnGlyphIndex == GF_DROPPED) + { + // when used in MultiSalLayout::GetTextBreak dropped glyphs + // must have zero width + pDXArray[i] = 0; + } + else + { + pDXArray[i] = mvCharDxs[i]; + if (i > 0) pDXArray[i] -= mvCharDxs[i-1]; + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"%d,%d,%ld ", (int)i, (int)mvCharDxs[i], pDXArray[i]); +#endif + } + //std::adjacent_difference(mvCharDxs.begin(), mvCharDxs.end(), pDXArray); + //for (size_t i = 0; i < mvCharDxs.size(); i++) + // fprintf(grLog(),"%d,%d,%d ", (int)i, (int)mvCharDxs[i], pDXArray[i]); + //fprintf(grLog(),"FillDX %ld,%d\n", mnWidth, std::accumulate(pDXArray, pDXArray + mvCharDxs.size(), 0)); + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"FillDXArray %d-%d,%d=%ld\n", mnMinCharPos, mnEndCharPos, (int)mpTextSrc->getLength(), mnWidth); +#endif + return mnWidth; +} + + +void GraphiteLayout::AdjustLayout(ImplLayoutArgs& rArgs) +{ + SalLayout::AdjustLayout(rArgs); + + if(rArgs.mpDXArray) + { + std::vector<int> vDeltaWidths(mvGlyphs.size(), 0); + ApplyDXArray(rArgs, vDeltaWidths); + + if( (mnLayoutFlags & SAL_LAYOUT_BIDI_RTL) && + !(rArgs.mnFlags & SAL_LAYOUT_FOR_FALLBACK) ) + { + // check if this is a kashida script + bool bKashidaScript = false; + for (int i = rArgs.mnMinCharPos; i < rArgs.mnEndCharPos; i++) + { + UErrorCode aStatus = U_ZERO_ERROR; + UScriptCode scriptCode = uscript_getScript(rArgs.mpStr[i], &aStatus); + if (scriptCode == USCRIPT_ARABIC || scriptCode == USCRIPT_SYRIAC) + { + bKashidaScript = true; + break; + } + } + int nKashidaWidth = 0; + int nKashidaIndex = getKashidaGlyph(nKashidaWidth); + if( nKashidaIndex != 0 && bKashidaScript) + { + kashidaJustify( vDeltaWidths, nKashidaIndex, nKashidaWidth ); + } + } + } +} + + +void GraphiteLayout::ApplyDXArray(ImplLayoutArgs &args, std::vector<int> & rDeltaWidth) +{ + const size_t nChars = args.mnEndCharPos - args.mnMinCharPos; + if (nChars == 0) return; + +#ifdef GRLAYOUT_DEBUG + for (size_t iDx = 0; iDx < mvCharDxs.size(); iDx++) + fprintf(grLog(),"%d,%d,%ld ", (int)iDx, (int)mvCharDxs[iDx], args.mpDXArray[iDx]); + fprintf(grLog(),"ApplyDx\n"); +#endif + bool bRtl = mnLayoutFlags & SAL_LAYOUT_BIDI_RTL; + int nXOffset = 0; + if (bRtl) + { + nXOffset = args.mpDXArray[nChars - 1] - mvCharDxs[nChars - 1]; + } + int nPrevClusterGlyph = (bRtl)? mvGlyphs.size() : -1; + int nPrevClusterLastChar = -1; + for (size_t i = 0; i < nChars; i++) + { + if (mvChar2BaseGlyph[i] > -1 && mvChar2BaseGlyph[i] != nPrevClusterGlyph) + { + assert((mvChar2BaseGlyph[i] > -1) && (mvChar2BaseGlyph[i] < (signed)mvGlyphs.size())); + GlyphItem & gi = mvGlyphs[mvChar2BaseGlyph[i]]; + if (!gi.IsClusterStart()) + continue; + + // find last glyph of this cluster + size_t j = i + 1; + int nLastChar = i; + int nLastGlyph = mvChar2BaseGlyph[i]; + for (; j < nChars; j++) + { + assert((mvChar2BaseGlyph[j] >= -1) && (mvChar2BaseGlyph[j] < (signed)mvGlyphs.size())); + if (mvChar2BaseGlyph[j] != -1 && mvGlyphs[mvChar2BaseGlyph[j]].IsClusterStart()) + { + nLastGlyph = mvChar2BaseGlyph[j] + ((bRtl)? 1 : -1); + nLastChar = j - 1; + break; + } + } + if (nLastGlyph < 0) + { + nLastGlyph = mvChar2BaseGlyph[i]; + } + // Its harder to find the last glyph rtl, since the first of + // cluster is still on the left so we need to search towards + // the previous cluster to the right + if (bRtl) + { + nLastGlyph = mvChar2BaseGlyph[i]; + while (nLastGlyph + 1 < (signed)mvGlyphs.size() && + !mvGlyphs[nLastGlyph+1].IsClusterStart()) + { + ++nLastGlyph; + } + } + if (j == nChars) + { + nLastChar = nChars - 1; + if (!bRtl) nLastGlyph = mvGlyphs.size() - 1; + } + assert((nLastChar > -1) && (nLastChar < (signed)nChars)); + long nNewClusterWidth = args.mpDXArray[nLastChar]; + long nOrigClusterWidth = mvCharDxs[nLastChar]; + long nDGlyphOrigin = 0; + if (nPrevClusterLastChar > - 1) + { + assert(nPrevClusterLastChar < (signed)nChars); + nNewClusterWidth -= args.mpDXArray[nPrevClusterLastChar]; + nOrigClusterWidth -= mvCharDxs[nPrevClusterLastChar]; + nDGlyphOrigin = args.mpDXArray[nPrevClusterLastChar] - mvCharDxs[nPrevClusterLastChar]; + } + long nDWidth = nNewClusterWidth - nOrigClusterWidth; +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(), "c%d last glyph %d/%d\n", i, nLastGlyph, mvGlyphs.size()); +#endif + assert((nLastGlyph > -1) && (nLastGlyph < (signed)mvGlyphs.size())); + mvGlyphs[nLastGlyph].mnNewWidth += nDWidth; + if (gi.mnGlyphIndex != GF_DROPPED) + mvGlyphs[nLastGlyph].mnNewWidth += nDWidth; + else + nDGlyphOrigin += nDWidth; + // update glyph positions + if (bRtl) + { + for (int n = mvChar2BaseGlyph[i]; n <= nLastGlyph; n++) + { + assert((n > - 1) && (n < (signed)mvGlyphs.size())); + mvGlyphs[n].maLinearPos.X() += -nDGlyphOrigin + nXOffset; + } + } + else + { + for (int n = mvChar2BaseGlyph[i]; n <= nLastGlyph; n++) + { + assert((n > - 1) && (n < (signed)mvGlyphs.size())); + mvGlyphs[n].maLinearPos.X() += nDGlyphOrigin + nXOffset; + } + } + rDeltaWidth[mvChar2BaseGlyph[i]] = nDWidth; +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"c%d g%d-%d dW%ld-%ld=%ld dX%ld x%ld\t", (int)i, mvChar2BaseGlyph[i], nLastGlyph, nNewClusterWidth, nOrigClusterWidth, nDWidth, nDGlyphOrigin, mvGlyphs[mvChar2BaseGlyph[i]].maLinearPos.X()); +#endif + nPrevClusterGlyph = mvChar2BaseGlyph[i]; + nPrevClusterLastChar = nLastChar; + i = nLastChar; + } + } + // Update the dx vector with the new values. + std::copy(args.mpDXArray, args.mpDXArray + nChars, + mvCharDxs.begin() + (args.mnMinCharPos - mnMinCharPos)); +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"ApplyDx %ld(%ld)\n", args.mpDXArray[nChars - 1], mnWidth); +#endif + mnWidth = args.mpDXArray[nChars - 1]; +} + +void GraphiteLayout::kashidaJustify(std::vector<int>& rDeltaWidths, sal_GlyphId nKashidaIndex, int nKashidaWidth) +{ + // skip if the kashida glyph in the font looks suspicious + if( nKashidaWidth <= 0 ) + return; + + // calculate max number of needed kashidas + Glyphs::iterator i = mvGlyphs.begin(); + int nKashidaCount = 0; + int nOrigGlyphIndex = -1; + int nGlyphIndex = -1; + while (i != mvGlyphs.end()) + { + nOrigGlyphIndex++; + nGlyphIndex++; + // only inject kashidas in RTL contexts + if( !(*i).IsRTLGlyph() ) + { + ++i; + continue; + } + // no kashida-injection for blank justified expansion either + if( IsSpacingGlyph( (*i).mnGlyphIndex ) ) + { + ++i; + continue; + } + // calculate gap, ignore if too small + int nGapWidth = rDeltaWidths[nOrigGlyphIndex];; + // worst case is one kashida even for mini-gaps + if( 3 * nGapWidth < nKashidaWidth ) + { + ++i; + continue; + } + nKashidaCount = 1 + (nGapWidth / nKashidaWidth); +#ifdef GRLAYOUT_DEBUG + printf("inserting %d kashidas at %ld\n", nKashidaCount, (*i).mnGlyphIndex); +#endif + GlyphItem glyphItem = *i; + Point aPos(0, 0); + aPos.X() = (*i).maLinearPos.X(); + GlyphItem newGi(glyphItem.mnCharPos, nKashidaIndex, aPos, + GlyphItem::IS_IN_CLUSTER|GlyphItem::IS_RTL_GLYPH, nKashidaWidth); + mvGlyphs.reserve(mvGlyphs.size() + nKashidaCount); + i = mvGlyphs.begin() + nGlyphIndex; + mvGlyphs.insert(i, nKashidaCount, newGi); + i = mvGlyphs.begin() + nGlyphIndex; + nGlyphIndex += nKashidaCount; + // now fix up the kashida positions + for (int j = 0; j < nKashidaCount; j++) + { + (*(i)).maLinearPos.X() -= nGapWidth; + nGapWidth -= nKashidaWidth; + i++; + } + + // fixup rightmost kashida for gap remainder + if( nGapWidth < 0 ) + { + if( nKashidaCount <= 1 ) + nGapWidth /= 2; // for small gap move kashida to middle + (*(i-1)).mnNewWidth += nGapWidth; // adjust kashida width to gap width + (*(i-1)).maLinearPos.X() += nGapWidth; + } + + (*i).mnNewWidth = (*i).mnOrigWidth; + ++i; + } + +} + +void GraphiteLayout::GetCaretPositions( int nArraySize, sal_Int32* pCaretXArray ) const +{ + // For each character except the last discover the caret positions + // immediatly before and after that character. + // This is used for underlines in the GUI amongst other things. + // It may be used from MultiSalLayout, in which case it must take into account + // glyphs that have been moved. + std::fill(pCaretXArray, pCaretXArray + nArraySize, -1); + // the layout method doesn't modify the layout even though it isn't + // const in the interface + bool bRtl = const_cast<GraphiteLayout*>(this)->maLayout.rightToLeft(); + int prevBase = -1; + long prevClusterWidth = 0; + for (int i = 0, nCharSlot = 0; i < nArraySize && nCharSlot < static_cast<int>(mvCharDxs.size()); ++nCharSlot, i+=2) + { + if (mvChar2BaseGlyph[nCharSlot] != -1) + { + assert((mvChar2BaseGlyph[nCharSlot] > -1) && (mvChar2BaseGlyph[nCharSlot] < (signed)mvGlyphs.size())); + GlyphItem gi = mvGlyphs[mvChar2BaseGlyph[nCharSlot]]; + if (gi.mnGlyphIndex == GF_DROPPED) + { + continue; + } + int nCluster = mvChar2BaseGlyph[nCharSlot]; + long origClusterWidth = gi.mnNewWidth; + long nMin = gi.maLinearPos.X(); + long nMax = gi.maLinearPos.X() + gi.mnNewWidth; + // attached glyphs are always stored after their base rtl or ltr + while (++nCluster < static_cast<int>(mvGlyphs.size()) && + !mvGlyphs[nCluster].IsClusterStart()) + { + origClusterWidth += mvGlyphs[nCluster].mnNewWidth; + if (mvGlyph2Char[nCluster] == nCharSlot) + { + nMin = std::min(nMin, mvGlyphs[nCluster].maLinearPos.X()); + nMax = std::min(nMax, mvGlyphs[nCluster].maLinearPos.X() + mvGlyphs[nCluster].mnNewWidth); + } + } + if (bRtl) + { + pCaretXArray[i+1] = nMin; + pCaretXArray[i] = nMax; + } + else + { + pCaretXArray[i] = nMin; + pCaretXArray[i+1] = nMax; + } + prevBase = mvChar2BaseGlyph[nCharSlot]; + prevClusterWidth = origClusterWidth; + } + else if (prevBase > -1) + { + // this could probably be improved + assert((prevBase > -1) && (prevBase < (signed)mvGlyphs.size())); + GlyphItem gi = mvGlyphs[prevBase]; + int nGlyph = prevBase + 1; + // try to find a better match, otherwise default to complete cluster + for (; nGlyph < static_cast<int>(mvGlyphs.size()) && + !mvGlyphs[nGlyph].IsClusterStart(); nGlyph++) + { + if (mvGlyph2Char[nGlyph] == nCharSlot) + { + gi = mvGlyphs[nGlyph]; + break; + } + } + long nGWidth = gi.mnNewWidth; + // if no match position at end of cluster + if (nGlyph == static_cast<int>(mvGlyphs.size()) || + mvGlyphs[nGlyph].IsClusterStart()) + { + nGWidth = prevClusterWidth; + if (bRtl) + { + pCaretXArray[i+1] = gi.maLinearPos.X(); + pCaretXArray[i] = gi.maLinearPos.X(); + } + else + { + pCaretXArray[i] = gi.maLinearPos.X() + prevClusterWidth; + pCaretXArray[i+1] = gi.maLinearPos.X() + prevClusterWidth; + } + } + else + { + if (bRtl) + { + pCaretXArray[i+1] = gi.maLinearPos.X(); + pCaretXArray[i] = gi.maLinearPos.X() + gi.mnNewWidth; + } + else + { + pCaretXArray[i] = gi.maLinearPos.X(); + pCaretXArray[i+1] = gi.maLinearPos.X() + gi.mnNewWidth; + } + } + } + else + { + pCaretXArray[i] = pCaretXArray[i+1] = 0; + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"%d,%ld-%ld\t", nCharSlot, pCaretXArray[i], pCaretXArray[i+1]); +#endif + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"\n"); +#endif +} + + +// GetNextGlyphs returns a contiguous sequence of glyphs that can be +// rendered together. It should never return a dropped glyph. +// The glyph_slot returned should be the index of the next visible +// glyph after the last glyph returned by this call. +// The char_index array should be filled with the characters corresponding +// to each glyph returned. +// glyph_adv array should be a virtual width such that if successive +// glyphs returned by this method are added one after the other they +// have the correct spacing. +// The logic in this method must match that expected in MultiSalLayout which +// is used when glyph fallback is in operation. +int GraphiteLayout::GetNextGlyphs( int length, sal_GlyphId * glyph_out, + ::Point & aPosOut, int &glyph_slot, sal_Int32 * glyph_adv, int *char_index) const +{ + // Sanity check on the slot index. + if (glyph_slot >= signed(mvGlyphs.size())) + { + glyph_slot = mvGlyphs.size(); + return 0; + } + assert(glyph_slot >= 0); + // Find the first glyph in the substring. + for (; glyph_slot < signed(mvGlyphs.size()) && + ((mvGlyphs.begin() + glyph_slot)->mnGlyphIndex == GF_DROPPED); + ++glyph_slot) {}; + + // Update the length + const int nGlyphSlotEnd = std::min(size_t(glyph_slot + length), mvGlyphs.size()); + + // We're all out of glyphs here. + if (glyph_slot == nGlyphSlotEnd) + { + return 0; + } + + // Find as many glyphs as we can which can be drawn in one go. + Glyphs::const_iterator glyph_itr = mvGlyphs.begin() + glyph_slot; + const int glyph_slot_begin = glyph_slot; + const int initial_y_pos = glyph_itr->maLinearPos.Y(); + + // Set the position to the position of the start glyph. + ::Point aStartPos = glyph_itr->maLinearPos; + //aPosOut = glyph_itr->maLinearPos; + aPosOut = GetDrawPosition(aStartPos); + + + for (;;) // Forever + { + // last index of the range from glyph_to_chars does not include this glyph + if (char_index) + { + assert((glyph_slot >= -1) && (glyph_slot < (signed)mvGlyph2Char.size())); + if (mvGlyph2Char[glyph_slot] == -1) + *char_index++ = mvCharDxs.size(); + else + *char_index++ = mvGlyph2Char[glyph_slot]; + } + // Copy out this glyphs data. + ++glyph_slot; + *glyph_out++ = glyph_itr->mnGlyphIndex; + + // Find the actual advance - this must be correct if called from + // MultiSalLayout::AdjustLayout which requests one glyph at a time. + const long nGlyphAdvance = (glyph_slot == static_cast<int>(mvGlyphs.size()))? + glyph_itr->mnNewWidth : + ((glyph_itr+1)->maLinearPos.X() - glyph_itr->maLinearPos.X()); + +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"GetNextGlyphs g%d c%d x%ld,%ld adv%ld, pos %ld,%ld\n", glyph_slot - 1, + mvGlyph2Char[glyph_slot-1], glyph_itr->maLinearPos.X(), glyph_itr->maLinearPos.Y(), nGlyphAdvance, + aPosOut.X(), aPosOut.Y()); +#endif + + if (glyph_adv) // If we are returning advance store it. + *glyph_adv++ = nGlyphAdvance; + else // Stop when next advance is unexpected. + if (glyph_itr->mnOrigWidth != nGlyphAdvance) break; + + // Have fetched all the glyphs we need to + if (glyph_slot == nGlyphSlotEnd) + break; + + ++glyph_itr; + // Stop when next y position is unexpected. + if (initial_y_pos != glyph_itr->maLinearPos.Y()) + break; + + // Stop if glyph dropped + if (glyph_itr->mnGlyphIndex == GF_DROPPED) + break; + } + int numGlyphs = glyph_slot - glyph_slot_begin; + // move the next glyph_slot to a glyph that hasn't been dropped + while (glyph_slot < static_cast<int>(mvGlyphs.size()) && + (mvGlyphs.begin() + glyph_slot)->mnGlyphIndex == GF_DROPPED) + ++glyph_slot; + return numGlyphs; +} + + +void GraphiteLayout::MoveGlyph( int nGlyphIndex, long nNewPos ) +{ + // TODO it might be better to actualy implement simplify properly, but this + // needs to be done carefully so the glyph/char maps are maintained + // If a glyph has been dropped then it wasn't returned by GetNextGlyphs, so + // the index here may be wrong + while ((mvGlyphs[nGlyphIndex].mnGlyphIndex == GF_DROPPED) && + (nGlyphIndex < (signed)mvGlyphs.size())) + { + nGlyphIndex++; + } + const long dx = nNewPos - mvGlyphs[nGlyphIndex].maLinearPos.X(); + + if (dx == 0) return; + // GenericSalLayout only changes maLinearPos, mvCharDxs doesn't change +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Move %d (%ld,%ld) c%d by %ld\n", nGlyphIndex, mvGlyphs[nGlyphIndex].maLinearPos.X(), nNewPos, mvGlyph2Char[nGlyphIndex], dx); +#endif + for (size_t gi = nGlyphIndex; gi < mvGlyphs.size(); gi++) + { + mvGlyphs[gi].maLinearPos.X() += dx; + } + // width does need to be updated for correct fallback + mnWidth += dx; +} + + +void GraphiteLayout::DropGlyph( int nGlyphIndex ) +{ + if(nGlyphIndex >= signed(mvGlyphs.size())) + return; + + GlyphItem & glyph = mvGlyphs[nGlyphIndex]; + glyph.mnGlyphIndex = GF_DROPPED; +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Dropped %d\n", nGlyphIndex); +#endif +} + +void GraphiteLayout::Simplify( bool isBaseLayout ) +{ + const sal_GlyphId dropMarker = isBaseLayout ? GF_DROPPED : 0; + + Glyphs::iterator gi = mvGlyphs.begin(); + // TODO check whether we need to adjust positions here + // MultiSalLayout seems to move the glyphs itself, so it may not be needed. + long deltaX = 0; + while (gi != mvGlyphs.end()) + { + if (gi->mnGlyphIndex == dropMarker) + { + deltaX += gi->mnNewWidth; + gi->mnNewWidth = 0; + } + else + { + deltaX = 0; + } + //mvCharDxs[mvGlyph2Char[gi->mnCharPos]] -= deltaX; + ++gi; + } +#ifdef GRLAYOUT_DEBUG + fprintf(grLog(),"Simplify base%d dx=%ld newW=%ld\n", isBaseLayout, deltaX, mnWidth - deltaX); +#endif + // discard width from trailing dropped glyphs, but not those in the middle + mnWidth -= deltaX; +} diff --git a/vcl/source/glyphs/graphite_serverfont.cxx b/vcl/source/glyphs/graphite_serverfont.cxx new file mode 100644 index 000000000000..e8cd152b43ac --- /dev/null +++ b/vcl/source/glyphs/graphite_serverfont.cxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +// Header files +// + +// Platform +#include <vcl/sallayout.hxx> +// Module +#include "gcach_ftyp.hxx" +#include <vcl/graphite_features.hxx> +#include "graphite_textsrc.hxx" +#include <vcl/graphite_serverfont.hxx> + +#ifndef MSC + +// +// An implementation of the GraphiteLayout interface to enable Graphite enabled fonts to be used. +// + +GraphiteServerFontLayout::GraphiteServerFontLayout(GraphiteFontAdaptor * pFont) throw() + : ServerFontLayout(pFont->font()), mpFont(pFont), + maImpl(*mpFont, mpFont->features(), pFont) +{ + // Nothing needed here +} + +GraphiteServerFontLayout::~GraphiteServerFontLayout() throw() +{ + delete mpFont; + mpFont = NULL; +} + +const sal_Unicode* GraphiteServerFontLayout::getTextPtr() const +{ + return maImpl.textSrc()->getLayoutArgs().mpStr + + maImpl.textSrc()->getLayoutArgs().mnMinCharPos; +} + +sal_GlyphId GraphiteLayoutImpl::getKashidaGlyph(int & width) +{ + int nKashidaIndex = mpFont->font().GetGlyphIndex( 0x0640 ); + if( nKashidaIndex != 0 ) + { + const GlyphMetric& rGM = mpFont->font().GetGlyphMetric( nKashidaIndex ); + width = rGM.GetCharWidth(); + } + else + { + width = 0; + } + return nKashidaIndex; +} + +#endif diff --git a/vcl/source/glyphs/graphite_textsrc.cxx b/vcl/source/glyphs/graphite_textsrc.cxx new file mode 100644 index 000000000000..adc2ae99c4f8 --- /dev/null +++ b/vcl/source/glyphs/graphite_textsrc.cxx @@ -0,0 +1,172 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +// Header files +// +// Standard Library +#include <string> +#include <cassert> +#include "graphite_textsrc.hxx" +#include <vcl/graphite_features.hxx> + +// class TextSourceAdaptor implementation. +// +TextSourceAdaptor::~TextSourceAdaptor() +{ + delete mpFeatures; +} + +gr::UtfType TextSourceAdaptor::utfEncodingForm() { + return gr::kutf16; +} + + +size_t TextSourceAdaptor::getLength() +{ + return maLayoutArgs.mnLength; +} + + +size_t TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf32 *) +{ + assert(false); + return 0; +} + + +size_t TextSourceAdaptor::fetch(gr::toffset offset, size_t char_count, gr::utf16 * char_buffer) +{ + assert(char_buffer); + + size_t copy_count = std::min(size_t(maLayoutArgs.mnLength), char_count); + std::copy(maLayoutArgs.mpStr + offset, maLayoutArgs.mpStr + offset + copy_count, char_buffer); + + return copy_count; +} + + +size_t TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf8 *) +{ + assert(false); + return 0; +} + + +inline void TextSourceAdaptor::getCharProperties(const int nCharIdx, int & min, int & lim, size_t & depth) +{ + maLayoutArgs.ResetPos(); + bool rtl = maLayoutArgs.mnFlags & SAL_LAYOUT_BIDI_RTL; + for(depth = ((rtl)? 1:0); maLayoutArgs.maRuns.GetRun(&min, &lim, &rtl); maLayoutArgs.maRuns.NextRun()) + { + if (min > nCharIdx) + break; + // Only increase the depth when a change of direction occurs. + depth += int(rtl ^ bool(depth & 0x1)); + if (min <= nCharIdx && nCharIdx < lim) + break; + } + // If there is no run for this position increment the depth, but don't + // change if this is out of bounds context + if (lim > 0 && nCharIdx >= lim && nCharIdx < maLayoutArgs.mnEndCharPos) + depth++; +} + + +bool TextSourceAdaptor::getRightToLeft(gr::toffset nCharIdx) +{ + size_t depth; + int min, lim = 0; + getCharProperties(nCharIdx, min, lim, depth); + //printf("getRtl %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth & 0x1); + return depth & 0x1; +} + + +unsigned int TextSourceAdaptor::getDirectionDepth(gr::toffset nCharIdx) +{ + size_t depth; + int min, lim; + getCharProperties(nCharIdx, min, lim, depth); + //printf("getDirectionDepth %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth); + return depth; +} + + +float TextSourceAdaptor::getVerticalOffset(gr::toffset) +{ + return 0.0f; //TODO: Implement correctly +} + +gr::isocode TextSourceAdaptor::getLanguage(gr::toffset) +{ + if (mpFeatures && mpFeatures->hasLanguage()) + return mpFeatures->getLanguage(); + gr::isocode unknown = {{0,0,0,0}}; + return unknown; +} + +std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx) +{ + + if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos)) + return std::make_pair(0, maLayoutArgs.mnMinCharPos); + + if (nCharIdx < mnEnd) + return std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd); + + return std::make_pair(mnEnd, maLayoutArgs.mnLength); +} + +size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings) +{ + if (mpFeatures) return mpFeatures->getFontFeatures(settings); + return 0; +} + + +bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2) +{ + const std::pair<gr::toffset, gr::toffset> + range1 = propertyRange(char_idx1), + range2 = propertyRange(char_idx2); + + return range1 == range2; +} + +void TextSourceAdaptor::setFeatures(const grutils::GrFeatureParser * pFeatures) +{ + mpFeatures = new grutils::GrFeatureParser(*pFeatures); +} diff --git a/vcl/source/glyphs/graphite_textsrc.hxx b/vcl/source/glyphs/graphite_textsrc.hxx new file mode 100644 index 000000000000..6f701988bb01 --- /dev/null +++ b/vcl/source/glyphs/graphite_textsrc.hxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: $ + * $Revision: $ + * + * 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. + * + ************************************************************************/ + +#ifndef _SV_GRAPHITETEXTSRC_HXX +#define _SV_GRAPHITETEXTSRC_HXX +// Description: Implements the Graphite interfaces IGrTextSource and +// IGrGraphics which provide Graphite with access to the +// app's text storage system and the platform's font and +// graphics systems. + +// We need this to enable namespace support in libgrengine headers. +#define GR_NAMESPACE + +// Standard Library +#include <stdexcept> +// Platform + +#ifndef _SVWIN_H +#include <tools/svwin.h> +#endif + +#ifndef _SV_SVSYS_HXX +#include <svsys.h> +#endif + +#ifndef _SV_SALGDI_HXX +#include <vcl/salgdi.hxx> +#endif + +#ifndef _SV_SALLAYOUT_HXX +#include <vcl/sallayout.hxx> +#endif + +// Module +#include "vcl/dllapi.h" + +// Libraries +#include <graphite/GrClient.h> +#include <graphite/Font.h> +#include <graphite/ITextSource.h> + +// Module type definitions and forward declarations. +// +namespace grutils +{ + class GrFeatureParser; +} +// Implements the Adaptor pattern to adapt the LayoutArgs and the ServerFont interfaces to the +// gr::IGrTextSource interface. +// @author tse +// +class TextSourceAdaptor : public gr::ITextSource +{ +public: + TextSourceAdaptor(ImplLayoutArgs &layout_args, const int nContextLen) throw(); + ~TextSourceAdaptor(); + virtual gr::UtfType utfEncodingForm(); + virtual size_t getLength(); + virtual size_t fetch(gr::toffset ichMin, size_t cch, gr::utf32 * prgchBuffer); + virtual size_t fetch(gr::toffset ichMin, size_t cch, gr::utf16 * prgchwBuffer); + virtual size_t fetch(gr::toffset ichMin, size_t cch, gr::utf8 * prgchsBuffer); + virtual bool getRightToLeft(gr::toffset ich); + virtual unsigned int getDirectionDepth(gr::toffset ich); + virtual float getVerticalOffset(gr::toffset ich); + virtual gr::isocode getLanguage(gr::toffset ich); + + virtual std::pair<gr::toffset, gr::toffset> propertyRange(gr::toffset ich); + virtual size_t getFontFeatures(gr::toffset ich, gr::FeatureSetting * prgfset); + virtual bool sameSegment(gr::toffset ich1, gr::toffset ich2); + + operator ImplLayoutArgs & () throw(); + void setFeatures(const grutils::GrFeatureParser * pFeatures); + const ImplLayoutArgs & getLayoutArgs() const { return maLayoutArgs; } + size_t getContextLength() const { return mnEnd; }; + inline void switchLayoutArgs(ImplLayoutArgs & newArgs); +private: + // Prevent the generation of a default assignment operator. + TextSourceAdaptor & operator=(const TextSourceAdaptor &); + + void getCharProperties(const int, int &, int &, size_t &); + + ImplLayoutArgs maLayoutArgs; + size_t mnEnd; + const grutils::GrFeatureParser * mpFeatures; +}; + +inline TextSourceAdaptor::TextSourceAdaptor(ImplLayoutArgs &la, const int nContextLen) throw() + : maLayoutArgs(la), + mnEnd(std::min(la.mnLength, nContextLen)), + mpFeatures(NULL) +{ +} + +inline TextSourceAdaptor::operator ImplLayoutArgs & () throw() { + return maLayoutArgs; +} + +inline void TextSourceAdaptor::switchLayoutArgs(ImplLayoutArgs & aNewArgs) +{ + mnEnd += aNewArgs.mnMinCharPos - maLayoutArgs.mnMinCharPos; + maLayoutArgs = aNewArgs; +} + +#endif diff --git a/vcl/source/glyphs/makefile.mk b/vcl/source/glyphs/makefile.mk index b08777d7020f..3e79cdc63da2 100644 --- a/vcl/source/glyphs/makefile.mk +++ b/vcl/source/glyphs/makefile.mk @@ -49,11 +49,36 @@ CFLAGS+=-DUSE_FT_EMBOLDEN # --- Files -------------------------------------------------------- .IF "$(USE_BUILTIN_RASTERIZER)" != "" +# GlyphCache + FreeType support (only on UNX platforms currently) SLOFILES=\ $(SLO)$/glyphcache.obj \ $(SLO)$/gcach_rbmp.obj \ $(SLO)$/gcach_layout.obj \ $(SLO)$/gcach_ftyp.obj + +.IF "$(ENABLE_GRAPHITE)" != "" +# Graphite support using the glyphcache infrastructure +CFLAGS+=-DENABLE_GRAPHITE +SLOFILES+= $(SLO)$/graphite_adaptors.obj \ + $(SLO)$/graphite_features.obj \ + $(SLO)$/graphite_cache.obj \ + $(SLO)$/graphite_textsrc.obj \ + $(SLO)$/graphite_serverfont.obj \ + $(SLO)$/graphite_layout.obj +.ENDIF + +.ELSE + +.IF "$(ENABLE_GRAPHITE)" == "TRUE" +# Graphite support on non-UNX platforms +# make use of stlport headerfiles +EXT_USE_STLPORT=TRUE +SLOFILES=\ + $(SLO)$/graphite_textsrc.obj \ + $(SLO)$/graphite_cache.obj \ + $(SLO)$/graphite_features.obj \ + $(SLO)$/graphite_layout.obj +.ENDIF .ENDIF # --- Targets ------------------------------------------------------ diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index c827905e94e6..ccf75dbd59b3 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -3480,11 +3480,6 @@ USHORT PopupMenu::Execute( Window* pExecWindow, const Rectangle& rRect, USHORT n USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupModeFlags, Menu* pSFrom, BOOL bPreSelectFirst ) { - - // #59614# Mit TH abgesprochen dass die ASSERTION raus kommt, - // weil es evtl. legitim ist... -// DBG_ASSERT( !PopupMenu::IsInExecute() || pSFrom, "PopupMenu::Execute() called in PopupMenu::Execute()" ); - if ( !pSFrom && ( PopupMenu::IsInExecute() || !GetItemCount() ) ) return 0; @@ -3660,8 +3655,16 @@ USHORT PopupMenu::ImplExecute( Window* pW, const Rectangle& rRect, ULONG nPopupM { pWin->ImplAddDel( &aDelData ); + ImplDelData aModalWinDel; + pW->ImplAddDel( &aModalWinDel ); + pW->ImplIncModalCount(); + pWin->Execute(); + DBG_ASSERT( ! aModalWinDel.IsDead(), "window for popup died, modal count incorrect !" ); + if( ! aModalWinDel.IsDead() ) + pW->ImplDecModalCount(); + if ( !aDelData.IsDelete() ) pWin->ImplRemoveDel( &aDelData ); else diff --git a/vcl/source/window/tabpage.cxx b/vcl/source/window/tabpage.cxx index 57eec66e705a..e28026876fad 100644 --- a/vcl/source/window/tabpage.cxx +++ b/vcl/source/window/tabpage.cxx @@ -121,6 +121,8 @@ void TabPage::StateChanged( StateChangedType nType ) { if ( GetSettings().GetStyleSettings().GetAutoMnemonic() ) ImplWindowAutoMnemonic( this ); + // FIXME: no layouting, workaround some clipping issues + ImplAdjustNWFSizes(); } else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) { diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx index e4285482e3b7..f8fe3b36447d 100644 --- a/vcl/source/window/window.cxx +++ b/vcl/source/window/window.cxx @@ -5862,18 +5862,15 @@ void Window::UpdateSettings( const AllSettings& rSettings, BOOL bChild ) ImplInitResolutionSettings(); /* #i73785# - * do not overwrite a NoWheelActionWithoutFocus with false - * this looks kind of a hack, but NoWheelActionWithoutFocus + * do not overwrite a WheelBehavior with false + * this looks kind of a hack, but WheelBehavior * is always a local change, not a system property, - * so we can spare all our users the hassel of reacting on + * so we can spare all our users the hassle of reacting on * this in their respective DataChanged. */ - if( aOldSettings.GetMouseSettings().GetNoWheelActionWithoutFocus() ) - { - MouseSettings aSet( maSettings.GetMouseSettings() ); - aSet.SetNoWheelActionWithoutFocus( TRUE ); - maSettings.SetMouseSettings( aSet ); - } + MouseSettings aSet( maSettings.GetMouseSettings() ); + aSet.SetWheelBehavior( aOldSettings.GetMouseSettings().GetWheelBehavior() ); + maSettings.SetMouseSettings( aSet ); if( (nChangeFlags & SETTINGS_STYLE) && IsBackground() ) { @@ -6242,6 +6239,15 @@ void Window::SetParent( Window* pNewParent ) pSysWin->GetTaskPaneList()->RemoveWindow( this ); } } + // remove ownerdraw decorated windows from list in the top-most frame window + if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame ) + { + ::std::vector< Window* >& rList = ImplGetOwnerDrawList(); + ::std::vector< Window* >::iterator p; + p = ::std::find( rList.begin(), rList.end(), this ); + if( p != rList.end() ) + rList.erase( p ); + } ImplSetFrameParent( pNewParent ); @@ -6371,6 +6377,9 @@ void Window::SetParent( Window* pNewParent ) if( bChangeTaskPaneList ) pNewSysWin->GetTaskPaneList()->AddWindow( this ); + if( (GetStyle() & WB_OWNERDRAWDECORATION) && mpWindowImpl->mbFrame ) + ImplGetOwnerDrawList().push_back( this ); + if ( bVisible ) Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); } diff --git a/vcl/unx/gtk/app/gtkdata.cxx b/vcl/unx/gtk/app/gtkdata.cxx index bb08477e82e9..b55798608b37 100644 --- a/vcl/unx/gtk/app/gtkdata.cxx +++ b/vcl/unx/gtk/app/gtkdata.cxx @@ -138,8 +138,6 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event, GdkEvent*, gpointer data ) { - GTK_YIELD_GRAB(); - GdkFilterReturn aFilterReturn = GDK_FILTER_CONTINUE; XEvent *pEvent = (XEvent *)sys_event; @@ -150,6 +148,8 @@ GdkFilterReturn GtkSalDisplay::filterGdkEvent( GdkXEvent* sys_event, CallEventCallback( pEvent, sizeof( XEvent ) ) ) aFilterReturn = GDK_FILTER_REMOVE; + GTK_YIELD_GRAB(); + if (pDisplay->GetDisplay() == pEvent->xany.display ) { // #i53471# gtk has no callback mechanism that lets us be notified diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index 9dbb218403d0..fdaa102c614b 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -454,6 +454,10 @@ void GtkData::deInitNWF( void ) gtk_widget_destroy( gWidgetData[i].gMenuWidget ); if( gWidgetData[i].gTooltipPopup ) gtk_widget_destroy( gWidgetData[i].gTooltipPopup ); + delete gWidgetData[i].gCacheTabPages; + gWidgetData[i].gCacheTabPages = NULL; + delete gWidgetData[i].gCacheTabItems; + gWidgetData[i].gCacheTabItems = NULL; delete gWidgetData[i].gNWPixmapCacheList; gWidgetData[i].gNWPixmapCacheList = NULL; } diff --git a/vcl/unx/gtk/window/gtkframe.cxx b/vcl/unx/gtk/window/gtkframe.cxx index 57f48df66c3c..b6770ca1a77e 100644 --- a/vcl/unx/gtk/window/gtkframe.cxx +++ b/vcl/unx/gtk/window/gtkframe.cxx @@ -834,7 +834,7 @@ void GtkSalFrame::Init( SalFrame* pParent, ULONG nStyle ) } if( (nStyle & SAL_FRAME_STYLE_PARTIAL_FULLSCREEN ) ) { - eType = GDK_WINDOW_TYPE_HINT_DOCK; + eType = GDK_WINDOW_TYPE_HINT_TOOLBAR; gtk_window_set_keep_above( GTK_WINDOW(m_pWindow), true ); } diff --git a/vcl/unx/headless/svpgdi.cxx b/vcl/unx/headless/svpgdi.cxx index cd3e286d167a..bd317c883b0b 100644 --- a/vcl/unx/headless/svpgdi.cxx +++ b/vcl/unx/headless/svpgdi.cxx @@ -429,7 +429,7 @@ void SvpSalGraphics::copyArea( long nDestX, { B2IRange aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight ); B2IRange aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight ); - m_aDevice->drawBitmap( m_aDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); + m_aDevice->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); dbgOut( m_aDevice ); } @@ -444,7 +444,7 @@ void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry, B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, pPosAry->mnDestX+pPosAry->mnDestWidth, pPosAry->mnDestY+pPosAry->mnDestHeight ); - m_aDevice->drawBitmap( pSrc->m_aDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); + m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); dbgOut( m_aDevice ); } @@ -519,7 +519,7 @@ SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeigh m_aDevice ); B2IRange aSrcRect( nX, nY, nX+nWidth, nY+nHeight ); B2IRange aDestRect( 0, 0, nWidth, nHeight ); - aCopy->drawBitmap( m_aDevice, aSrcRect, aDestRect, DrawMode_PAINT ); + aCopy->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT ); SvpSalBitmap* pBitmap = new SvpSalBitmap(); pBitmap->setBitmap( aCopy ); diff --git a/vcl/unx/headless/svpprn.cxx b/vcl/unx/headless/svpprn.cxx index 862eb99ab18d..c3253ed163e8 100644 --- a/vcl/unx/headless/svpprn.cxx +++ b/vcl/unx/headless/svpprn.cxx @@ -73,37 +73,6 @@ inline int PtTo10Mu( int nPoints ) { return (int)((((double)nPoints)*35.27777778 inline int TenMuToPt( int nUnits ) { return (int)((((double)nUnits)/35.27777778)+0.5); } -static struct -{ - int width; - int height; - const char* name; - int namelength; - Paper paper; -} aPaperTab[] = -{ - { 29700, 42000, "A3", 2, PAPER_A3 }, - { 21000, 29700, "A4", 2, PAPER_A4 }, - { 14800, 21000, "A5", 2, PAPER_A5 }, - { 25000, 35300, "B4", 2, PAPER_B4 }, - { 17600, 25000, "B5", 2, PAPER_B5 }, - { 21600, 27900, "Letter", 6, PAPER_LETTER }, - { 21600, 35600, "Legal", 5, PAPER_LEGAL }, - { 27900, 43100, "Tabloid", 7, PAPER_TABLOID }, - { 0, 0, "USER", 4, PAPER_USER } -}; - -static Paper getPaperType( const String& rPaperName ) -{ - ByteString aPaper( rPaperName, RTL_TEXTENCODING_ISO_8859_1 ); - for( unsigned int i = 0; i < sizeof( aPaperTab )/sizeof( aPaperTab[0] ); i++ ) - { - if( ! strcmp( aPaper.GetBuffer(), aPaperTab[i].name ) ) - return aPaperTab[i].paper; - } - return PAPER_USER; -} - static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData ) { pJobSetup->meOrientation = (Orientation)(rData.m_eOrientation == orientation::Landscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT); @@ -113,7 +82,7 @@ static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData ) int width, height; rData.m_aContext.getPageSize( aPaper, width, height ); - pJobSetup->mePaperFormat = getPaperType( aPaper ); + pJobSetup->mePaperFormat = PaperInfo::fromPSName(OUStringToOString( aPaper, RTL_TEXTENCODING_ISO_8859_1 )); pJobSetup->mnPaperWidth = 0; pJobSetup->mnPaperHeight = 0; if( pJobSetup->mePaperFormat == PAPER_USER ) @@ -475,14 +444,9 @@ void PspSalInfoPrinter::InitPaperFormats( const ImplJobSetup* ) for( int i = 0; i < nValues; i++ ) { const PPDValue* pValue = pKey->getValue( i ); - vcl::PaperInfo aInfo; - aInfo.m_aPaperName = pValue->m_aOptionTranslation; - if( ! aInfo.m_aPaperName.Len() ) - aInfo.m_aPaperName = pValue->m_aOption; int nWidth = 0, nHeight = 0; m_aJobData.m_pParser->getPaperDimension( pValue->m_aOption, nWidth, nHeight ); - aInfo.m_nPaperWidth = (unsigned long)((PtTo10Mu( nWidth )+50)/100); - aInfo.m_nPaperHeight = (unsigned long)((PtTo10Mu( nHeight )+50)/100); + PaperInfo aInfo(PtTo10Mu( nWidth ), PtTo10Mu( nHeight )); m_aPaperFormats.push_back( aInfo ); } } @@ -628,7 +592,7 @@ BOOL PspSalInfoPrinter::SetData( TenMuToPt( pJobSetup->mnPaperWidth ), TenMuToPt( pJobSetup->mnPaperHeight ) ); else - aPaper = String( ByteString( aPaperTab[ pJobSetup->mePaperFormat ].name ), RTL_TEXTENCODING_ISO_8859_1 ); + aPaper = rtl::OStringToOUString(PaperInfo::toPSName(pJobSetup->mePaperFormat), RTL_TEXTENCODING_ISO_8859_1); pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); pValue = pKey ? pKey->getValue( aPaper ) : NULL; diff --git a/vcl/unx/headless/svpvd.cxx b/vcl/unx/headless/svpvd.cxx index 2d7342093e47..6220af0b28b8 100644 --- a/vcl/unx/headless/svpvd.cxx +++ b/vcl/unx/headless/svpvd.cxx @@ -34,6 +34,8 @@ #include <basegfx/vector/b2ivector.hxx> #include <basebmp/scanlineformats.hxx> +#include "stdio.h" + using namespace basegfx; using namespace basebmp; @@ -65,9 +67,14 @@ BOOL SvpSalVirtualDevice::SetSize( long nNewDX, long nNewDY ) if( ! m_aDevice.get() || m_aDevice->getSize() != aDevSize ) { sal_uInt32 nFormat = SVP_DEFAULT_BITMAP_FORMAT; + std::vector< basebmp::Color > aDevPal; switch( m_nBitCount ) { - case 1: nFormat = Format::ONE_BIT_MSB_PAL; break; + case 1: nFormat = Format::ONE_BIT_MSB_PAL; + aDevPal.reserve(2); + aDevPal.push_back( basebmp::Color( 0, 0, 0 ) ); + aDevPal.push_back( basebmp::Color( 0xff, 0xff, 0xff ) ); + break; case 4: nFormat = Format::FOUR_BIT_MSB_PAL; break; case 8: nFormat = Format::EIGHT_BIT_PAL; break; #ifdef OSL_BIGENDIAN @@ -75,14 +82,19 @@ BOOL SvpSalVirtualDevice::SetSize( long nNewDX, long nNewDY ) #else case 16: nFormat = Format::SIXTEEN_BIT_LSB_TC_MASK; break; #endif + case 0: case 24: nFormat = Format::TWENTYFOUR_BIT_TC_MASK; break; case 32: nFormat = Format::THIRTYTWO_BIT_TC_MASK; break; } - m_aDevice = createBitmapDevice( aDevSize, false, nFormat ); + m_aDevice = aDevPal.empty() + ? createBitmapDevice( aDevSize, false, nFormat ) + : createBitmapDevice( aDevSize, false, nFormat, PaletteMemorySharedVector( new std::vector< basebmp::Color >(aDevPal) ) ); + // update device in existing graphics for( std::list< SvpSalGraphics* >::iterator it = m_aGraphics.begin(); it != m_aGraphics.end(); ++it ) (*it)->setDevice( m_aDevice ); + } return true; } diff --git a/vcl/unx/inc/salgdi.h b/vcl/unx/inc/salgdi.h index 16276cdeb5c9..f893b547e847 100644 --- a/vcl/unx/inc/salgdi.h +++ b/vcl/unx/inc/salgdi.h @@ -106,6 +106,8 @@ protected: Pixel nTextPixel_; BOOL bFontVertical_; + BOOL bDisableGraphite_; + GC pBrushGC_; // Brush attributes SalColor nBrushColor_; Pixel nBrushPixel_; diff --git a/vcl/unx/kde4/KDEData.cxx b/vcl/unx/kde4/KDEData.cxx new file mode 100644 index 000000000000..07a10c60d933 --- /dev/null +++ b/vcl/unx/kde4/KDEData.cxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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 "KDEData.hxx" + +#include "KDEXLib.hxx" + +KDEData::~KDEData() +{ +} + +void KDEData::Init() +{ + pXLib_ = new KDEXLib(); + pXLib_->Init(); +} + +void KDEData::initNWF() +{ + ImplSVData *pSVData = ImplGetSVData(); + + // draw toolbars on separate lines + pSVData->maNWFData.mbDockingAreaSeparateTB = true; +} + +void KDEData::deInitNWF() +{ +}
\ No newline at end of file diff --git a/vcl/unx/kde4/KDEData.hxx b/vcl/unx/kde4/KDEData.hxx new file mode 100644 index 000000000000..68645abc28d3 --- /dev/null +++ b/vcl/unx/kde4/KDEData.hxx @@ -0,0 +1,42 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#include <saldisp.hxx> +#include <saldata.hxx> + +class KDEData : public X11SalData +{ + public: + KDEData() {} + virtual ~KDEData(); + + virtual void Init(); + virtual void initNWF(); + virtual void deInitNWF(); +};
\ No newline at end of file diff --git a/vcl/unx/kde4/KDESalDisplay.cxx b/vcl/unx/kde4/KDESalDisplay.cxx new file mode 100644 index 000000000000..61044c3de71b --- /dev/null +++ b/vcl/unx/kde4/KDESalDisplay.cxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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 "KDESalDisplay.hxx" + +#include "KDEXLib.hxx" + +SalKDEDisplay::SalKDEDisplay( Display* pDisp ) + : SalX11Display( pDisp ) +{ +} + +SalKDEDisplay::~SalKDEDisplay() +{ + // in case never a frame opened + static_cast<KDEXLib*>(GetXLib())->doStartup(); + // clean up own members + doDestruct(); + // prevent SalDisplay from closing KApplication's display + pDisp_ = NULL; +}
\ No newline at end of file diff --git a/vcl/unx/kde4/KDESalDisplay.hxx b/vcl/unx/kde4/KDESalDisplay.hxx new file mode 100644 index 000000000000..ce294f45087d --- /dev/null +++ b/vcl/unx/kde4/KDESalDisplay.hxx @@ -0,0 +1,37 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#include <saldisp.hxx> + +class SalKDEDisplay : public SalX11Display +{ + public: + SalKDEDisplay( Display* pDisp ); + virtual ~SalKDEDisplay(); +}; diff --git a/vcl/unx/kde4/KDESalFrame.cxx b/vcl/unx/kde4/KDESalFrame.cxx new file mode 100644 index 000000000000..ad8f467ee960 --- /dev/null +++ b/vcl/unx/kde4/KDESalFrame.cxx @@ -0,0 +1,409 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#define Region QtXRegion + +#include <QColor> +#include <QStyle> + +#include <kconfig.h> +#include <kglobal.h> +#include <kmenubar.h> +#include <kconfiggroup.h> +#include <kmainwindow.h> +#include <kapplication.h> +#include <ktoolbar.h> + +#undef Region + +#include "KDESalFrame.hxx" +#include "KDEXLib.hxx" +#include "KDESalGraphics.hxx" + +#include <vcl/settings.hxx> +#include <vcl/font.hxx> +#include <tools/color.hxx> + +#include <vcl/svdata.hxx> + +#include <pspgraphics.h> + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +KDESalFrame::KDESalFrame( SalFrame* pParent, ULONG nState ) : + X11SalFrame( pParent, nState ) +{ +} + +void KDESalFrame::Show( BOOL bVisible, BOOL bNoActivate ) +{ + if ( !GetParent() && ! (GetStyle() & SAL_FRAME_STYLE_INTRO) ) + { + KDEXLib* pXLib = static_cast<KDEXLib*>(GetDisplay()->GetXLib()); + pXLib->doStartup(); + } + + X11SalFrame::Show( bVisible, bNoActivate ); +} + +/** Helper function to convert colors. +*/ +static Color toColor( const QColor &rColor ) +{ + return Color( rColor.red(), rColor.green(), rColor.blue() ); +} + +/** Helper function to read untranslated text entry from KConfig configuration repository. +*/ +static OUString readEntryUntranslated( KConfigGroup *pGroup, const char *pKey ) +{ + return OUString::createFromAscii( (const char *) pGroup->readEntryUntranslated( pKey ).toAscii() ); +} + +/** Helper function to read color from KConfig configuration repository. +*/ +static Color readColor( KConfigGroup *pGroup, const char *pKey ) +{ + return toColor( pGroup->readEntry( pKey, QColor(Qt::white) ) ); +} + +/** Helper function to add information to Font from QFont. + + Mostly grabbed from the Gtk+ vclplug (salnativewidgets-gtk.cxx). +*/ +static Font toFont( const QFont &rQFont, const ::com::sun::star::lang::Locale& rLocale ) +{ + psp::FastPrintFontInfo aInfo; + QFontInfo qFontInfo( rQFont ); + + // set family name + aInfo.m_aFamilyName = String( (const char *) rQFont.family().toUtf8(), RTL_TEXTENCODING_UTF8 ); + + // set italic + aInfo.m_eItalic = ( qFontInfo.italic()? psp::italic::Italic: psp::italic::Upright ); + + // set weight + int nWeight = qFontInfo.weight(); + if ( nWeight <= QFont::Light ) + aInfo.m_eWeight = psp::weight::Light; + else if ( nWeight <= QFont::Normal ) + aInfo.m_eWeight = psp::weight::Normal; + else if ( nWeight <= QFont::DemiBold ) + aInfo.m_eWeight = psp::weight::SemiBold; + else if ( nWeight <= QFont::Bold ) + aInfo.m_eWeight = psp::weight::Bold; + else + aInfo.m_eWeight = psp::weight::UltraBold; + + // set width + int nStretch = rQFont.stretch(); + if ( nStretch <= QFont::UltraCondensed ) + aInfo.m_eWidth = psp::width::UltraCondensed; + else if ( nStretch <= QFont::ExtraCondensed ) + aInfo.m_eWidth = psp::width::ExtraCondensed; + else if ( nStretch <= QFont::Condensed ) + aInfo.m_eWidth = psp::width::Condensed; + else if ( nStretch <= QFont::SemiCondensed ) + aInfo.m_eWidth = psp::width::SemiCondensed; + else if ( nStretch <= QFont::Unstretched ) + aInfo.m_eWidth = psp::width::Normal; + else if ( nStretch <= QFont::SemiExpanded ) + aInfo.m_eWidth = psp::width::SemiExpanded; + else if ( nStretch <= QFont::Expanded ) + aInfo.m_eWidth = psp::width::Expanded; + else if ( nStretch <= QFont::ExtraExpanded ) + aInfo.m_eWidth = psp::width::ExtraExpanded; + else + aInfo.m_eWidth = psp::width::UltraExpanded; + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "font name BEFORE system match: \"%s\"\n", OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() ); +#endif + + // match font to e.g. resolve "Sans" + psp::PrintFontManager::get().matchFont( aInfo, rLocale ); + +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "font match %s, name AFTER: \"%s\"\n", + aInfo.m_nID != 0 ? "succeeded" : "failed", + OUStringToOString( aInfo.m_aFamilyName, RTL_TEXTENCODING_ISO_8859_1 ).getStr() ); +#endif + + // font height + int nPointHeight = qFontInfo.pointSize(); + if ( nPointHeight <= 0 ) + nPointHeight = rQFont.pointSize(); + + // Create the font + Font aFont( aInfo.m_aFamilyName, Size( 0, nPointHeight ) ); + if( aInfo.m_eWeight != psp::weight::Unknown ) + aFont.SetWeight( PspGraphics::ToFontWeight( aInfo.m_eWeight ) ); + if( aInfo.m_eWidth != psp::width::Unknown ) + aFont.SetWidthType( PspGraphics::ToFontWidth( aInfo.m_eWidth ) ); + if( aInfo.m_eItalic != psp::italic::Unknown ) + aFont.SetItalic( PspGraphics::ToFontItalic( aInfo.m_eItalic ) ); + if( aInfo.m_ePitch != psp::pitch::Unknown ) + aFont.SetPitch( PspGraphics::ToFontPitch( aInfo.m_ePitch ) ); + + return aFont; +} + +/** Implementation of KDE integration's main method. +*/ +void KDESalFrame::UpdateSettings( AllSettings& rSettings ) +{ + StyleSettings style( rSettings.GetStyleSettings() ); + BOOL bSetTitleFont = false; + + + // General settings + QPalette pal = kapp->palette(); + + style.SetActiveColor(toColor(pal.color(QPalette::Active, QPalette::Window))); + style.SetDeactiveColor(toColor(pal.color(QPalette::Inactive, QPalette::Window))); + + style.SetActiveColor2(toColor(pal.color(QPalette::Active, QPalette::Window))); + style.SetDeactiveColor2(toColor(pal.color(QPalette::Inactive, QPalette::Window))); + + style.SetActiveTextColor(toColor(pal.color(QPalette::Active, QPalette::WindowText))); + style.SetDeactiveTextColor(toColor(pal.color(QPalette::Inactive, QPalette::WindowText))); + + // WM settings + KConfig *pConfig = KGlobal::config().data(); + if ( pConfig ) + { + KConfigGroup aGroup = pConfig->group( "WM" ); + const char *pKey; + + pKey = "titleFont"; + if ( aGroup.hasKey( pKey ) ) + { + Font aFont = toFont( aGroup.readEntry( pKey, QFont() ), rSettings.GetUILocale() ); + style.SetTitleFont( aFont ); + bSetTitleFont = true; + } + + aGroup = pConfig->group( "Icons" ); + + pKey = "Theme"; + if ( aGroup.hasKey( pKey ) ) + style.SetPreferredSymbolsStyleName( readEntryUntranslated( &aGroup, pKey ) ); + } + + Color aFore = toColor( pal.color( QPalette::Active, QPalette::WindowText ) ); + Color aBack = toColor( pal.color( QPalette::Active, QPalette::Window ) ); + Color aText = toColor( pal.color( QPalette::Active, QPalette::Text ) ); + Color aBase = toColor( pal.color( QPalette::Active, QPalette::Base ) ); + Color aButn = toColor( pal.color( QPalette::Active, QPalette::ButtonText ) ); + Color aMid = toColor( pal.color( QPalette::Active, QPalette::Mid ) ); + Color aHigh = toColor( pal.color( QPalette::Active, QPalette::Highlight ) ); + + // Foreground + style.SetRadioCheckTextColor( aFore ); + style.SetLabelTextColor( aFore ); + style.SetInfoTextColor( aFore ); + style.SetDialogTextColor( aFore ); + style.SetGroupTextColor( aFore ); + + // Text + style.SetFieldTextColor( aText ); + style.SetFieldRolloverTextColor( aText ); + style.SetWindowTextColor( aText ); + style.SetHelpTextColor( aText ); + + // Base + style.SetFieldColor( aBase ); + style.SetHelpColor( aBase ); + style.SetWindowColor( aBase ); + style.SetActiveTabColor( aBase ); + + // Buttons + style.SetButtonTextColor( aButn ); + style.SetButtonRolloverTextColor( aButn ); + + // Disable color + style.SetDisableColor( aMid ); + + // Workspace + style.SetWorkspaceColor( aMid ); + + // Background + style.Set3DColors( aBack ); + style.SetFaceColor( aBack ); + style.SetInactiveTabColor( aBack ); + style.SetDialogColor( aBack ); + + if( aBack == COL_LIGHTGRAY ) + style.SetCheckedColor( Color( 0xCC, 0xCC, 0xCC ) ); + else + { + Color aColor2 = style.GetLightColor(); + style. + SetCheckedColor( Color( (BYTE)(((USHORT)aBack.GetRed()+(USHORT)aColor2.GetRed())/2), + (BYTE)(((USHORT)aBack.GetGreen()+(USHORT)aColor2.GetGreen())/2), + (BYTE)(((USHORT)aBack.GetBlue()+(USHORT)aColor2.GetBlue())/2) + ) ); + } + + // Selection + style.SetHighlightColor( aHigh ); + style.SetHighlightTextColor( toColor(pal.color( QPalette::HighlightedText)) ); + + // Font + Font aFont = toFont( kapp->font(), rSettings.GetUILocale() ); + + style.SetAppFont( aFont ); + style.SetHelpFont( aFont ); + + if( !bSetTitleFont ) + { + style.SetTitleFont( aFont ); + } + + style.SetFloatTitleFont( aFont ); + style.SetMenuFont( aFont ); // will be changed according to pMenuBar + style.SetToolFont( aFont ); // will be changed according to pToolBar + style.SetLabelFont( aFont ); + style.SetInfoFont( aFont ); + style.SetRadioCheckFont( aFont ); + style.SetPushButtonFont( aFont ); + style.SetFieldFont( aFont ); + style.SetIconFont( aFont ); + style.SetGroupFont( aFont ); + + int flash_time = QApplication::cursorFlashTime(); + style.SetCursorBlinkTime( flash_time != 0 ? flash_time/2 : STYLE_CURSOR_NOBLINKTIME ); + + KMainWindow qMainWindow; + + // Menu + style.SetSkipDisabledInMenus( TRUE ); + KMenuBar *pMenuBar = qMainWindow.menuBar(); + if ( pMenuBar ) + { + // Color + QPalette qMenuCG = pMenuBar->palette(); + + // Menu text and background color, theme specific + Color aMenuFore = toColor( qMenuCG.color( QPalette::WindowText ) ); + Color aMenuBack = toColor( qMenuCG.color( QPalette::Window ) ); + + aMenuFore = toColor( qMenuCG.color( QPalette::ButtonText ) ); + aMenuBack = toColor( qMenuCG.color( QPalette::Button ) ); + + style.SetMenuTextColor( aMenuFore ); + style.SetMenuColor( aMenuBack ); + style.SetMenuBarColor( aMenuBack ); + + style.SetMenuHighlightColor( toColor ( qMenuCG.color( QPalette::Highlight ) ) ); + + style.SetMenuHighlightTextColor( aMenuFore ); + + // set special menubar higlight text color + if ( kapp->style()->inherits( "HighContrastStyle" ) ) + ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = toColor( qMenuCG.color( QPalette::HighlightedText ) ); + else + ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = aMenuFore; + + // Font + aFont = toFont( pMenuBar->font(), rSettings.GetUILocale() ); + style.SetMenuFont( aFont ); + } + + // Tool bar + KToolBar *pToolBar = qMainWindow.toolBar(); + if ( pToolBar ) + { + aFont = toFont( pToolBar->font(), rSettings.GetUILocale() ); + style.SetToolFont( aFont ); + } + + // Scroll bar size + style.SetScrollBarSize( kapp->style()->pixelMetric( QStyle::PM_ScrollBarExtent ) ); + + // #i59364# high contrast mode + BOOL bHC = ( style.GetFaceColor().IsDark() || + style.GetWindowColor().IsDark() ); + style.SetHighContrastMode( bHC ); + + rSettings.SetStyleSettings( style ); +} + + +void KDESalFrame::ReleaseGraphics( SalGraphics *pGraphics ) +{ + for( int i = 0; i < nMaxGraphics; i++ ) + { + if( m_aGraphics[i].pGraphics == pGraphics ) + { + m_aGraphics[i].bInUse = false; + break; + } + } +} + +void KDESalFrame::updateGraphics() +{ + for( int i = 0; i < nMaxGraphics; i++ ) + { + if( m_aGraphics[i].bInUse ) + m_aGraphics[i].pGraphics->SetDrawable( GetWindow(), GetScreenNumber() ); + } +} + +KDESalFrame::~KDESalFrame() +{ +} + +KDESalFrame::GraphicsHolder::~GraphicsHolder() +{ + delete pGraphics; +} + +SalGraphics* KDESalFrame::GetGraphics() +{ + if( GetWindow() ) + { + for( int i = 0; i < nMaxGraphics; i++ ) + { + if( ! m_aGraphics[i].bInUse ) + { + m_aGraphics[i].bInUse = true; + if( ! m_aGraphics[i].pGraphics ) + { + m_aGraphics[i].pGraphics = new KDESalGraphics(); + m_aGraphics[i].pGraphics->Init( this, GetWindow(), GetScreenNumber() ); + } + return m_aGraphics[i].pGraphics; + } + } + } + + return NULL; +}
\ No newline at end of file diff --git a/vcl/unx/kde4/KDESalFrame.hxx b/vcl/unx/kde4/KDESalFrame.hxx new file mode 100644 index 000000000000..11a22bd93ba5 --- /dev/null +++ b/vcl/unx/kde4/KDESalFrame.hxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#include <saldisp.hxx> +#include <salframe.h> + +class KDESalFrame : public X11SalFrame +{ + private: + static const int nMaxGraphics = 2; + + struct GraphicsHolder + { + X11SalGraphics* pGraphics; + bool bInUse; + + GraphicsHolder() : pGraphics(0),bInUse( false ) {} + ~GraphicsHolder(); + }; + + GraphicsHolder m_aGraphics[ nMaxGraphics ]; + + public: + KDESalFrame( SalFrame* pParent, ULONG nStyle ); + virtual ~KDESalFrame(); + + virtual SalGraphics* GetGraphics(); + virtual void ReleaseGraphics( SalGraphics *pGraphics ); + virtual void updateGraphics(); + virtual void UpdateSettings( AllSettings& rSettings ); + virtual void Show( BOOL bVisible, BOOL bNoActivate ); +};
\ No newline at end of file diff --git a/vcl/unx/kde4/KDESalGraphics.cxx b/vcl/unx/kde4/KDESalGraphics.cxx new file mode 100644 index 000000000000..ae917f252b11 --- /dev/null +++ b/vcl/unx/kde4/KDESalGraphics.cxx @@ -0,0 +1,819 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#define _SV_SALNATIVEWIDGETS_KDE_CXX + +#define Region QtXRegion + +#include <QStyle> +#include <QStyleOption> +#include <QPainter> + +#include <kapplication.h> + +#undef Region + +#include "KDESalGraphics.hxx" + +#include <vcl/settings.hxx> +#include <rtl/ustrbuf.hxx> + +#include <stdio.h> + +using namespace ::rtl; + +/** + Conversion function between VCL ControlState together with + ImplControlValue and Qt state flags. + @param nControlState State of the widget (default, focused, ...) in Native Widget Framework. + @param aValue Value held by the widget (on, off, ...) +*/ +QStyle::State vclStateValue2StateFlag( ControlState nControlState, + const ImplControlValue& aValue ) +{ + QStyle::State nState = + ( (nControlState & CTRL_STATE_DEFAULT)? QStyle::State_None: QStyle::State_None ) | + ( (nControlState & CTRL_STATE_ENABLED)? QStyle::State_Enabled: QStyle::State_None ) | + ( (nControlState & CTRL_STATE_FOCUSED)? QStyle::State_HasFocus: QStyle::State_None ) | + ( (nControlState & CTRL_STATE_PRESSED)? QStyle::State_Sunken: QStyle::State_None ) | + ( (nControlState & CTRL_STATE_SELECTED)? QStyle::State_Selected : QStyle::State_None ) | + ( (nControlState & CTRL_STATE_ROLLOVER)? QStyle::State_MouseOver: QStyle::State_None ); + //TODO ( (nControlState & CTRL_STATE_HIDDEN)? QStyle::State_: QStyle::State_None ) | + + switch ( aValue.getTristateVal() ) + { + case BUTTONVALUE_ON: nState |= QStyle::State_On; break; + case BUTTONVALUE_OFF: nState |= QStyle::State_Off; break; + case BUTTONVALUE_MIXED: nState |= QStyle::State_NoChange; break; + default: break; + } + + return nState; +} + +/** + Convert VCL Region to QRect. + @param rControlRegion The region to convert. + @return The bounding box of the region. +*/ +QRect region2QRect( const Region& rControlRegion ) +{ + Rectangle aRect = rControlRegion.GetBoundRect(); + + return QRect( QPoint( aRect.Left(), aRect.Top() ), + QPoint( aRect.Right(), aRect.Bottom() ) ); +} + +BOOL KDESalGraphics::IsNativeControlSupported( ControlType type, ControlPart part ) +{ + if (type == CTRL_PUSHBUTTON) return true; + + if (type == CTRL_MENUBAR) return true; + + if (type == CTRL_MENU_POPUP) return true; + + if (type == CTRL_EDITBOX) return true; + + if (type == CTRL_COMBOBOX) return true; + + if (type == CTRL_TOOLBAR) return true; + + if (type == CTRL_CHECKBOX) return true; + + if (type == CTRL_LISTBOX) return true; + + if (type == CTRL_LISTNODE) return true; + + if (type == CTRL_FRAME) return true; + + if (type == CTRL_SCROLLBAR) return true; + + if (type == CTRL_WINDOW_BACKGROUND) return true; + + if (type == CTRL_SPINBOX && (part == PART_ENTIRE_CONTROL || part == HAS_BACKGROUND_TEXTURE) ) return true; + + // no spinbuttons for KDE, paint spinbox complete + //if (type == CTRL_SPINBUTTONS) return true; + + if (type == CTRL_GROUPBOX) return true; + + if (type == CTRL_FIXEDLINE) return true; + + if (type == CTRL_FIXEDBORDER) return true; + + if (type == CTRL_TOOLTIP) return true; + + if (type == CTRL_RADIOBUTTON) return true; + + return false; + + if ( (type == CTRL_TAB_ITEM) && (part == PART_ENTIRE_CONTROL) ) return true; + if ( (type == CTRL_TAB_PANE) && (part == PART_ENTIRE_CONTROL) ) return true; + // no CTRL_TAB_BODY for KDE + if ( (type == CTRL_PROGRESS) && (part == PART_ENTIRE_CONTROL) ) return true; + + return false; +} + + +BOOL KDESalGraphics::hitTestNativeControl( ControlType, ControlPart, + const Region&, const Point&, + SalControlHandle&, BOOL& ) +{ + return FALSE; +} + +BOOL KDESalGraphics::drawNativeControl( ControlType type, ControlPart part, + const Region& rControlRegion, ControlState nControlState, + const ImplControlValue& value, SalControlHandle&, + const OUString& ) +{ + // put not implemented types here + if (type == CTRL_SPINBUTTONS) + { + return false; + } + + BOOL returnVal = true; + + Display* dpy = GetXDisplay(); + XLIB_Window drawable = GetDrawable(); + GC gc = SelectPen(); + + QRect widgetRect = region2QRect(rControlRegion); + if( type == CTRL_SPINBOX && part == PART_ALL_BUTTONS ) + type = CTRL_SPINBUTTONS; + if( type == CTRL_SPINBUTTONS ) + { + SpinbuttonValue* pSpinVal = (SpinbuttonValue *)(value.getOptionalVal()); + Rectangle aButtonRect( pSpinVal->maUpperRect); + aButtonRect.Union( pSpinVal->maLowerRect );; + widgetRect = QRect( aButtonRect.Left(), aButtonRect.Top(), + aButtonRect.Right(), aButtonRect.Bottom() ); + } + + //draw right onto the window + QPixmap pixmap(widgetRect.width(), widgetRect.height()); + + if (pixmap.isNull()) + { + return false; + } + + QPainter painter(&pixmap); + // painter.setBackgroundMode(Qt::OpaqueMode); + + //copy previous screen contents for proper blending + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + QPixmap screen = QPixmap::fromX11Pixmap(drawable); + painter.drawPixmap(0,0, screen, widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height()); + #else + const QX11Info& rX11Info( pixmap.x11Info() ); + X11SalGraphics::CopyScreenArea( dpy, + drawable, GetScreenNumber(), GetBitCount(), + pixmap.handle(), rX11Info.screen(), rX11Info.depth(), + GetDisplay()->GetCopyGC( GetScreenNumber() ), + widgetRect.left(), widgetRect.top(), widgetRect.width(), widgetRect.height(), + 0, 0 ); + #endif + + if (type == CTRL_PUSHBUTTON) + { + QStyleOptionButton styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state =vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawControl( QStyle::CE_PushButton, &styleOption, &painter); + } + else if ( (type == CTRL_MENUBAR)) + { + if (part == PART_MENU_ITEM) + { + QStyleOptionMenuItem styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawControl( QStyle::CE_MenuBarItem, &styleOption, &painter); + } + else + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + } + } + else if (type == CTRL_MENU_POPUP) + { + if (part == PART_MENU_ITEM) + { + QStyleOptionMenuItem styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawControl( QStyle::CE_MenuItem, &styleOption, &painter); + } + else if (part == PART_MENU_ITEM_CHECK_MARK) + { + QStyleOptionButton styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + if (nControlState & CTRL_STATE_PRESSED) + { + kapp->style()->drawPrimitive( QStyle::PE_IndicatorMenuCheckMark, &styleOption, &painter); + } + } + else if (part == PART_MENU_ITEM_RADIO_MARK) + { + QStyleOptionButton styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + if (nControlState & CTRL_STATE_PRESSED) + { + kapp->style()->drawPrimitive( QStyle::PE_IndicatorRadioButton, &styleOption, &painter); + } + } + else + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + QStyleOptionFrameV3 styleOption; + #else + QStyleOptionFrameV2 styleOption; + #endif + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + styleOption.frameShape = QFrame::StyledPanel; + #endif + + kapp->style()->drawPrimitive( QStyle::PE_FrameMenu, &styleOption, &painter); + } + } + else if ( (type == CTRL_TOOLBAR) && (part == PART_BUTTON) ) + { + QStyleOptionToolButton styleOption; + + styleOption.arrowType = Qt::NoArrow; + styleOption.subControls = QStyle::SC_ToolButton; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + styleOption.state |= QStyle::State_Raised | QStyle::State_Enabled | QStyle::State_AutoRaise; + + kapp->style()->drawComplexControl( QStyle::CC_ToolButton, &styleOption, &painter); + } + else if ( (type == CTRL_TOOLBAR) && (part == PART_ENTIRE_CONTROL) ) + { + QStyleOptionToolBar styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawControl( QStyle::CE_ToolBar, &styleOption, &painter); + } + else if ( (type == CTRL_TOOLBAR) && (part == PART_THUMB_VERT) ) + { + QStyleOption styleOption; + + int width = kapp->style()->pixelMetric(QStyle::PM_ToolBarHandleExtent); + + styleOption.rect = QRect(0, 0, width, widgetRect.height()); + styleOption.state = QStyle::State_Horizontal; + + kapp->style()->drawPrimitive( QStyle::PE_IndicatorToolBarHandle, &styleOption, &painter); + } + else if (type == CTRL_EDITBOX) + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + + //TODO hover?? OO does not seem to do this for line edits + + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + QStyleOptionFrameV3 styleOption; + #else + QStyleOptionFrameV2 styleOption; + #endif + + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + //TODO...how does the line edit draw itself internally?? + styleOption.rect = QRect(2, 2, widgetRect.width()-4, widgetRect.height()-4); + kapp->style()->drawPrimitive( QStyle::PE_PanelLineEdit, &styleOption, &painter); + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + kapp->style()->drawPrimitive( QStyle::PE_FrameLineEdit, &styleOption, &painter); + } + else if (type == CTRL_COMBOBOX) + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + + QStyleOptionComboBox styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + styleOption.editable = true; + + kapp->style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, &painter); + } + else if (type == CTRL_LISTBOX) + { + QStyleOptionComboBox styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + if (part == PART_SUB_EDIT) + { + kapp->style()->drawControl(QStyle::CE_ComboBoxLabel, &styleOption, &painter); + } + else + { + kapp->style()->drawComplexControl(QStyle::CC_ComboBox, &styleOption, &painter); + } + } + else if (type == CTRL_LISTNODE) + { + QStyleOption styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + styleOption.state |= QStyle::State_Item; + styleOption.state |= QStyle::State_Children; + + if (nControlState & CTRL_STATE_PRESSED) + { + styleOption.state |= QStyle::State_Open; + } + + kapp->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &styleOption, &painter); + } + else if (type == CTRL_CHECKBOX) + { + QStyleOptionButton styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawControl(QStyle::CE_CheckBox, &styleOption, &painter); + } + else if (type == CTRL_SCROLLBAR) + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + + if ((part == PART_DRAW_BACKGROUND_VERT) || (part == PART_DRAW_BACKGROUND_HORZ)) + { + ScrollbarValue* sbVal = static_cast<ScrollbarValue *> ( value.getOptionalVal() ); + + QStyleOptionSlider styleOption; + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + + //if the scroll bar is active (aka not degenrate...allow for hover events + if (sbVal->mnVisibleSize < sbVal->mnMax) + { + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + styleOption.state |= QStyle::State_MouseOver; + } + + //horizontal or vertical + if (part == PART_DRAW_BACKGROUND_VERT) + { + styleOption.orientation = Qt::Vertical; + } + else + { + styleOption.state |= QStyle::State_Horizontal; + } + + //setup parameters from the OO values + styleOption.minimum = sbVal->mnMin; + styleOption.maximum = sbVal->mnMax - sbVal->mnVisibleSize; + styleOption.sliderValue = sbVal->mnCur; + styleOption.sliderPosition = sbVal->mnCur; + styleOption.pageStep = sbVal->mnVisibleSize; + + //setup the active control...always the slider + if (sbVal->mnThumbState & CTRL_STATE_ROLLOVER) + { + styleOption.activeSubControls = QStyle::SC_ScrollBarSlider; + } + + kapp->style()->drawComplexControl(QStyle::CC_ScrollBar, &styleOption, &painter); + } + } + else if (type == CTRL_SPINBOX) + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + + QStyleOptionSpinBox styleOption; + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + // determine active control + SpinbuttonValue* pSpinVal = (SpinbuttonValue *)(value.getOptionalVal()); + if( pSpinVal ) + { + if( (pSpinVal->mnUpperState & CTRL_STATE_PRESSED) ) + styleOption.activeSubControls |= QStyle::SC_SpinBoxUp; + if( (pSpinVal->mnLowerState & CTRL_STATE_PRESSED) ) + styleOption.activeSubControls |= QStyle::SC_SpinBoxDown; + } + + kapp->style()->drawComplexControl(QStyle::CC_SpinBox, &styleOption, &painter); + } + else if (type == CTRL_GROUPBOX) + { + QStyleOptionGroupBox styleOption; + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawComplexControl(QStyle::CC_GroupBox, &styleOption, &painter); + } + else if (type == CTRL_RADIOBUTTON) + { + QStyleOptionButton styleOption; + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawControl(QStyle::CE_RadioButton, &styleOption, &painter); + } + else if (type == CTRL_TOOLTIP) + { + QStyleOption styleOption; + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + + kapp->style()->drawPrimitive(QStyle::PE_PanelTipLabel, &styleOption, &painter); + } + else if (type == CTRL_FRAME) + { + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + QStyleOptionFrameV3 styleOption; + #else + QStyleOptionFrameV2 styleOption; + #endif + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + styleOption.frameShape = QFrame::StyledPanel; + #endif + + kapp->style()->drawPrimitive(QStyle::PE_FrameWindow, &styleOption, &painter); + } + else if (type == CTRL_FIXEDBORDER) + { + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + QStyleOptionFrameV3 styleOption; + #else + QStyleOptionFrameV2 styleOption; + #endif + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + #if ( QT_VERSION >= QT_VERSION_CHECK( 4, 5, 0 ) ) + styleOption.frameShape = QFrame::StyledPanel; + #endif + + kapp->style()->drawPrimitive(QStyle::PE_FrameWindow, &styleOption, &painter); + } + else if (type == CTRL_WINDOW_BACKGROUND) + { + pixmap.fill(KApplication::palette().color(QPalette::Window)); + } + else if (type == CTRL_FIXEDLINE) + { + QStyleOptionMenuItem styleOption; + + styleOption.rect = QRect(0, 0, widgetRect.width(), widgetRect.height()); + styleOption.state = vclStateValue2StateFlag( nControlState, value ); + styleOption.menuItemType = QStyleOptionMenuItem::Separator; + styleOption.state |= QStyle::State_Item; + + kapp->style()->drawControl( QStyle::CE_MenuItem, &styleOption, &painter); + } + else + { + returnVal = false; + } + + if (returnVal) + { + X11SalGraphics::CopyScreenArea( dpy, + pixmap.handle(), pixmap.x11Info().screen(), pixmap.x11Info().depth(), + drawable, GetScreenNumber(), GetVisual().GetDepth(), gc, + 0, 0, widgetRect.width(), widgetRect.height(), widgetRect.left(), widgetRect.top() ); + } + + return returnVal; +} + +BOOL KDESalGraphics::getNativeControlRegion( ControlType type, ControlPart part, + const Region& controlRegion, ControlState controlState, + const ImplControlValue& val, SalControlHandle&, + const OUString&, + Region &nativeBoundingRegion, Region &nativeContentRegion ) +{ + bool retVal = false; + + QRect boundingRect = region2QRect( controlRegion ); + QRect contentRect = boundingRect; + QStyleOptionComplex styleOption; + + switch ( type ) + { + // Metrics of the push button + case CTRL_PUSHBUTTON: + if (part == PART_ENTIRE_CONTROL) + { + styleOption.state = vclStateValue2StateFlag(controlState, val); + + if ( controlState & CTRL_STATE_DEFAULT ) + { + int size = kapp->style()->pixelMetric( + QStyle::PM_ButtonDefaultIndicator, &styleOption ); + + boundingRect.adjust( -size, -size, size, size ); + + retVal = true; + } + } + break; + case CTRL_EDITBOX: + { + styleOption.rect = QRect(0, 0, contentRect.width(), contentRect.height()); + styleOption.state = vclStateValue2StateFlag(controlState, val); + + int size = kapp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) - 1; + + contentRect.adjust( -size, -size, size, size); + boundingRect = contentRect; + + retVal = true; + + break; + } + case CTRL_CHECKBOX: + if (part == PART_ENTIRE_CONTROL) + { + styleOption.state = vclStateValue2StateFlag(controlState, val); + + contentRect.setWidth(kapp->style()->pixelMetric( + QStyle::PM_IndicatorWidth, &styleOption)); + contentRect.setHeight(kapp->style()->pixelMetric( + QStyle::PM_IndicatorHeight, &styleOption)); + + contentRect.adjust(0, 0, + 2 * kapp->style()->pixelMetric( + QStyle::PM_FocusFrameHMargin, &styleOption), + 2 * kapp->style()->pixelMetric( + QStyle::PM_FocusFrameVMargin, &styleOption) + ); + + boundingRect = contentRect; + + retVal = true; + + break; + } + case CTRL_COMBOBOX: + case CTRL_LISTBOX: + { + QStyleOptionComboBox cbo; + + cbo.rect = QRect(0, 0, contentRect.width(), contentRect.height()); + cbo.state = vclStateValue2StateFlag(controlState, val); + + switch ( part ) + { + case PART_ENTIRE_CONTROL: + { + int size = kapp->style()->pixelMetric(QStyle::PM_ComboBoxFrameWidth) - 2; + contentRect.adjust(-size,-size,size,size); + + // find out the minimum size that should be used + // assume contents is a text ling + int nHeight = kapp->fontMetrics().height(); + QSize aContentSize( contentRect.width(), nHeight ); + QSize aMinSize = kapp->style()-> + sizeFromContents( QStyle::CT_ComboBox, &cbo, aContentSize ); + if( aMinSize.height() > contentRect.height() ) + contentRect.adjust( 0, 0, 0, aMinSize.height() - contentRect.height() ); + boundingRect = contentRect; + retVal = true; + break; + } + case PART_BUTTON_DOWN: + //the entire control can be used as the "down" button + retVal = true; + break; + case PART_SUB_EDIT: + contentRect = kapp->style()->subControlRect( + QStyle::CC_ComboBox, &cbo, QStyle::SC_ComboBoxEditField ); + + contentRect.translate( boundingRect.left(), boundingRect.top() ); + + retVal = true; + break; + } + break; + } + case CTRL_SPINBOX: + { + QStyleOptionSpinBox sbo; + + sbo.rect = QRect(0, 0, contentRect.width(), contentRect.height()); + sbo.state = vclStateValue2StateFlag(controlState, val); + + switch ( part ) + { + case PART_BUTTON_UP: + contentRect = kapp->style()->subControlRect( + QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxUp ); + contentRect.translate( boundingRect.left(), boundingRect.top() ); + retVal = true; + boundingRect = QRect(); + break; + + case PART_BUTTON_DOWN: + contentRect = kapp->style()->subControlRect( + QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxDown ); + retVal = true; + contentRect.translate( boundingRect.left(), boundingRect.top() ); + boundingRect = QRect(); + break; + + case PART_SUB_EDIT: + contentRect = kapp->style()->subControlRect( + QStyle::CC_SpinBox, &sbo, QStyle::SC_SpinBoxEditField ); + retVal = true; + contentRect.translate( boundingRect.left(), boundingRect.top() ); + break; + default: + retVal = true; + } + break; + } + case CTRL_MENU_POPUP: + //just limit the widget of the menu items + //OO isn't very flexible in all reguards with the menu + //so we do the best we can + if (part == PART_MENU_ITEM_CHECK_MARK) + { + contentRect.setWidth(contentRect.height()); + retVal = true; + } + else if (part == PART_MENU_ITEM_RADIO_MARK) + { + contentRect.setWidth(contentRect.height()); + retVal = true; + } + break; + case CTRL_FRAME: + { + if (part == PART_BORDER) + { + int size = kapp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + //contentRect.adjust(size, size, size, size); + boundingRect.adjust(-size, -size, size, size); + retVal = true; + } + + break; + } + case CTRL_RADIOBUTTON: + { + const int h = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorHeight); + const int w = kapp->style()->pixelMetric(QStyle::PM_ExclusiveIndicatorWidth); + + contentRect = QRect(boundingRect.left(), boundingRect.top(), w, h); + contentRect.adjust(0, 0, + 2 * kapp->style()->pixelMetric( + QStyle::PM_FocusFrameHMargin, &styleOption), + 2 * kapp->style()->pixelMetric( + QStyle::PM_FocusFrameVMargin, &styleOption) + ); + boundingRect = contentRect; + + retVal = true; + } + default: + break; + } +#if 0 + + + // Metrics of the scroll bar + case CTRL_SCROLLBAR: + //pWidget = pWidgetPainter->scrollBar( rControlRegion, + //( part == PART_BUTTON_LEFT || part == PART_BUTTON_RIGHT ), + //ImplControlValue() ); + //aStyleOption.initFrom( pWidget ); + + switch ( part ) + { + case PART_BUTTON_LEFT: + case PART_BUTTON_UP: + qRect = kapp->style()->subControlRect( + QStyle::CC_ScrollBar, &aStyleOption, QStyle::SC_ScrollBarSubLine ); + + // Workaround for Platinum style scroll bars. It makes the + // left/up button invisible. + if ( part == PART_BUTTON_LEFT ) + { + if ( qRect.left() > kapp->style()->subControlRect( + QStyle::CC_ScrollBar, &aStyleOption, + QStyle::SC_ScrollBarSubPage ).left() ) + { + qRect.setLeft( 0 ); + qRect.setRight( 0 ); + } + } + else + { + if ( qRect.top() > kapp->style()->subControlRect( + QStyle::CC_ScrollBar, &aStyleOption, + QStyle::SC_ScrollBarSubPage ).top() ) + { + qRect.setTop( 0 ); + qRect.setBottom( 0 ); + } + } + + qRect.translate( qBoundingRect.left(), qBoundingRect.top() ); + + bReturn = TRUE; + break; + + case PART_BUTTON_RIGHT: + case PART_BUTTON_DOWN: + qRect = kapp->style()->subControlRect( + QStyle::CC_ScrollBar, &aStyleOption, QStyle::SC_ScrollBarAddLine ); + + // Workaround for Platinum and 3 button style scroll bars. + // It makes the right/down button bigger. + if ( part == PART_BUTTON_RIGHT ) + qRect.setLeft( kapp->style()->subControlRect( + QStyle::CC_ScrollBar, &aStyleOption, + QStyle::SC_ScrollBarAddPage ).right() + 1 ); + else + qRect.setTop( kapp->style()->subControlRect( + QStyle::CC_ScrollBar, &aStyleOption, + QStyle::SC_ScrollBarAddPage ).bottom() + 1 ); + + qRect.translate( qBoundingRect.left(), qBoundingRect.top() ); + + bReturn = TRUE; + break; + } + break; + } +#endif + + if (retVal) + { + // Bounding region + Point aBPoint( boundingRect.x(), boundingRect.y() ); + Size aBSize( boundingRect.width(), boundingRect.height() ); + nativeBoundingRegion = Region( Rectangle( aBPoint, aBSize ) ); + + // Region of the content + Point aPoint( contentRect.x(), contentRect.y() ); + Size aSize( contentRect.width(), contentRect.height() ); + nativeContentRegion = Region( Rectangle( aPoint, aSize ) ); + } + + return retVal; +} diff --git a/vcl/unx/kde4/KDESalGraphics.hxx b/vcl/unx/kde4/KDESalGraphics.hxx new file mode 100644 index 000000000000..e598f75be75f --- /dev/null +++ b/vcl/unx/kde4/KDESalGraphics.hxx @@ -0,0 +1,114 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#include <rtl/string.hxx> +#include <saldisp.hxx> +#include <salgdi.h> + +/** handles graphics drawings requests and performs the needed drawing operations */ +class KDESalGraphics : public X11SalGraphics +{ + public: + KDESalGraphics() {} + virtual ~KDESalGraphics() {} + + /** + What widgets can be drawn the native way. + @param type Type of the widget. + @param part Specification of the widget's part if it consists of more than one. + @return true if the platform supports native drawing of the widget type defined by part. + */ + virtual BOOL IsNativeControlSupported( ControlType type, ControlPart part ); + + /** Test whether the position is in the native widget. + If the return value is TRUE, bIsInside contains information whether + aPos was or was not inside the native widget specified by the + type/part combination. + */ + virtual BOOL hitTestNativeControl( ControlType type, ControlPart part, + const Region& rControlRegion, const Point& aPos, + SalControlHandle& rControlHandle, BOOL& rIsInside ); + /** Draw the requested control described by part/nControlState. + + @param rControlRegion + The bounding region of the complete control in VCL frame coordinates. + + @param aValue + An optional value (tristate/numerical/string). + + @param rControlHandle + Carries platform dependent data and is maintained by the SalFrame implementation. + + @param aCaption + A caption or title string (like button text etc.) + */ + virtual BOOL drawNativeControl( ControlType type, ControlPart part, + const Region& rControlRegion, ControlState nControlState, + const ImplControlValue& aValue, SalControlHandle& rControlHandle, + const rtl::OUString& aCaption ); + + /** Draw text on the widget. + OPTIONAL. Draws the requested text for the control described by part/nControlState. + Used if text is not drawn by DrawNativeControl(). + + @param rControlRegion The bounding region of the complete control in VCL frame coordinates. + @param aValue An optional value (tristate/numerical/string) + @param rControlHandle Carries platform dependent data and is maintained by the SalFrame implementation. + @param aCaption A caption or title string (like button text etc.) + */ + virtual BOOL drawNativeControlText( ControlType, ControlPart, + const Region&, ControlState, + const ImplControlValue&, SalControlHandle&, + const rtl::OUString& ) { return false; } + /** Check if the bounding regions match. + + If the return value is TRUE, rNativeBoundingRegion + contains the true bounding region covered by the control + including any adornment, while rNativeContentRegion contains the area + within the control that can be safely drawn into without drawing over + the borders of the control. + + @param rControlRegion + The bounding region of the control in VCL frame coordinates. + + @param aValue + An optional value (tristate/numerical/string) + + @param rControlHandle + Carries platform dependent data and is maintained by the SalFrame implementation. + + @param aCaption + A caption or title string (like button text etc.) + */ + virtual BOOL getNativeControlRegion( ControlType type, ControlPart part, + const Region& rControlRegion, ControlState nControlState, + const ImplControlValue& aValue, SalControlHandle& rControlHandle, + const rtl::OUString& aCaption, + Region &rNativeBoundingRegion, Region &rNativeContentRegion ); +};
\ No newline at end of file diff --git a/vcl/unx/kde4/KDESalInstance.cxx b/vcl/unx/kde4/KDESalInstance.cxx new file mode 100644 index 000000000000..b9aab9a0184a --- /dev/null +++ b/vcl/unx/kde4/KDESalInstance.cxx @@ -0,0 +1,35 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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 "KDESalInstance.hxx" + +#include "KDESalFrame.hxx" + +SalFrame* KDESalInstance::CreateFrame( SalFrame *pParent, ULONG nState ) +{ + return new KDESalFrame( pParent, nState ); +}
\ No newline at end of file diff --git a/vcl/unx/kde4/KDESalInstance.hxx b/vcl/unx/kde4/KDESalInstance.hxx new file mode 100644 index 000000000000..6f0b268cc397 --- /dev/null +++ b/vcl/unx/kde4/KDESalInstance.hxx @@ -0,0 +1,41 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#include <salinst.h> + +class SalYieldMutex; +class SalFrame; + +class KDESalInstance : public X11SalInstance +{ + public: + KDESalInstance( SalYieldMutex* pMutex ) : X11SalInstance( pMutex ) {} + virtual ~KDESalInstance() {} + virtual SalFrame* CreateFrame( SalFrame* pParent, ULONG nStyle ); +};
\ No newline at end of file diff --git a/vcl/unx/kde4/KDEXLib.cxx b/vcl/unx/kde4/KDEXLib.cxx new file mode 100644 index 000000000000..70b1796df7f0 --- /dev/null +++ b/vcl/unx/kde4/KDEXLib.cxx @@ -0,0 +1,171 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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 "VCLKDEApplication.hxx" + +#define Region QtXRegion + +#include <kapplication.h> +#include <klocale.h> +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <kstartupinfo.h> + +#undef Region + +#include "KDEXLib.hxx" + +#include <i18n_im.hxx> +#include <i18n_xkb.hxx> + +#include <saldata.hxx> +#include <vos/process.hxx> + +#include "KDESalDisplay.hxx" + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +KDEXLib::KDEXLib() : + SalXLib(), m_bStartupDone(false), m_pApplication(0), + m_pFreeCmdLineArgs(0), m_pAppCmdLineArgs(0), m_nFakeCmdLineArgs( 0 ) +{ +} + +KDEXLib::~KDEXLib() +{ + delete (VCLKDEApplication*)m_pApplication; + + // free the faked cmdline arguments no longer needed by KApplication + for( int i = 0; i < m_nFakeCmdLineArgs; i++ ) + { + free( m_pFreeCmdLineArgs[i] ); + } + + delete [] m_pFreeCmdLineArgs; + delete [] m_pAppCmdLineArgs; +} + +void KDEXLib::Init() +{ + SalI18N_InputMethod* pInputMethod = new SalI18N_InputMethod; + pInputMethod->SetLocale(); + XrmInitialize(); + + KAboutData *kAboutData = new KAboutData( "OpenOffice.org", + "OpenOffice.org", + ki18n( "OpenOffice.org" ), + "3.0.0", + ki18n( "OpenOffice.org with KDE Native Widget Support." ), + KAboutData::License_LGPL, + ki18n( "Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 Novell, Inc"), + ki18n( "OpenOffice.org is an office suite.\n" ), + "http://kde.openoffice.org/index.html", + "dev@kde.openoffice.org" ); + kAboutData->addAuthor( ki18n( "Jan Holesovsky" ), + ki18n( "Original author and maintainer of the KDE NWF." ), + "kendy@artax.karlin.mff.cuni.cz", + "http://artax.karlin.mff.cuni.cz/~kendy" ); + kAboutData->addAuthor( ki18n("Eric Bischoff"), + ki18n( "Accessibility fixes, porting to KDE 4." ), + "bischoff@kde.org" ); + + m_nFakeCmdLineArgs = 1; + USHORT nIdx; + vos::OExtCommandLine aCommandLine; + int nParams = aCommandLine.getCommandArgCount(); + rtl::OString aDisplay; + rtl::OUString aParam, aBin; + + for ( nIdx = 0; nIdx < nParams; ++nIdx ) + { + aCommandLine.getCommandArg( nIdx, aParam ); + if ( !m_pFreeCmdLineArgs && aParam.equalsAscii( "-display" ) && nIdx + 1 < nParams ) + { + aCommandLine.getCommandArg( nIdx + 1, aParam ); + aDisplay = rtl::OUStringToOString( aParam, osl_getThreadTextEncoding() ); + + m_nFakeCmdLineArgs = 3; + m_pFreeCmdLineArgs = new char*[ m_nFakeCmdLineArgs ]; + m_pFreeCmdLineArgs[ 1 ] = strdup( "-display" ); + m_pFreeCmdLineArgs[ 2 ] = strdup( aDisplay.getStr() ); + } + } + if ( !m_pFreeCmdLineArgs ) + m_pFreeCmdLineArgs = new char*[ m_nFakeCmdLineArgs ]; + + osl_getExecutableFile( &aParam.pData ); + osl_getSystemPathFromFileURL( aParam.pData, &aBin.pData ); + rtl::OString aExec = rtl::OUStringToOString( aBin, osl_getThreadTextEncoding() ); + m_pFreeCmdLineArgs[0] = strdup( aExec.getStr() ); + + // make a copy of the string list for freeing it since + // KApplication manipulates the pointers inside the argument vector + // note: KApplication bad ! + m_pAppCmdLineArgs = new char*[ m_nFakeCmdLineArgs ]; + for( int i = 0; i < m_nFakeCmdLineArgs; i++ ) + m_pAppCmdLineArgs[i] = m_pFreeCmdLineArgs[i]; + + KCmdLineArgs::init( m_nFakeCmdLineArgs, m_pAppCmdLineArgs, kAboutData ); + + m_pApplication = new VCLKDEApplication(); + kapp->disableSessionManagement(); + + Display* pDisp = QX11Info::display(); + SalKDEDisplay *pSalDisplay = new SalKDEDisplay(pDisp); + + ((VCLKDEApplication*)m_pApplication)->disp = pSalDisplay; + + XSetIOErrorHandler ( (XIOErrorHandler)X11SalData::XIOErrorHdl ); + XSetErrorHandler ( (XErrorHandler)X11SalData::XErrorHdl ); + + pInputMethod->CreateMethod( pDisp ); + pInputMethod->AddConnectionWatch( pDisp, (void*)this ); + pSalDisplay->SetInputMethod( pInputMethod ); + + PushXErrorLevel( true ); + SalI18N_KeyboardExtension *pKbdExtension = new SalI18N_KeyboardExtension( pDisp ); + XSync( pDisp, False ); + + pKbdExtension->UseExtension( ! HasXErrorOccured() ); + PopXErrorLevel(); + + pSalDisplay->SetKbdExtension( pKbdExtension ); +} + +void KDEXLib::doStartup() +{ + if( ! m_bStartupDone ) + { + KStartupInfo::appStarted(); + m_bStartupDone = true; + #if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "called KStartupInfo::appStarted()\n" ); + #endif + } +}
\ No newline at end of file diff --git a/vcl/unx/kde4/KDEXLib.hxx b/vcl/unx/kde4/KDEXLib.hxx new file mode 100644 index 000000000000..0380db7212ef --- /dev/null +++ b/vcl/unx/kde4/KDEXLib.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#include <saldisp.hxx> + +class KDEXLib : public SalXLib +{ + private: + bool m_bStartupDone; + void* m_pApplication; + char** m_pFreeCmdLineArgs; + char** m_pAppCmdLineArgs; + int m_nFakeCmdLineArgs; + + public: + KDEXLib(); + + virtual ~KDEXLib(); + virtual void Init(); + + void doStartup(); +}; diff --git a/vcl/unx/kde4/VCLKDEApplication.cxx b/vcl/unx/kde4/VCLKDEApplication.cxx new file mode 100644 index 000000000000..29adcae6ceff --- /dev/null +++ b/vcl/unx/kde4/VCLKDEApplication.cxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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 "VCLKDEApplication.hxx" + +#define Region QtXRegion +#include <QEvent> +#undef Region + +#include "KDESalDisplay.hxx" + +VCLKDEApplication::VCLKDEApplication() : + KApplication() +{ + disp = 0; +} + +bool VCLKDEApplication::x11EventFilter(XEvent* event) +{ + //if we have a display and the display consumes the event + //do not process the event in qt + if (disp && disp->Dispatch(event) > 0) + { + return true; + } + + return false; +}
\ No newline at end of file diff --git a/vcl/unx/kde4/VCLKDEApplication.hxx b/vcl/unx/kde4/VCLKDEApplication.hxx new file mode 100644 index 000000000000..839b664ea8d2 --- /dev/null +++ b/vcl/unx/kde4/VCLKDEApplication.hxx @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +#pragma once + +#define Region QtXRegion + +#include <QSessionManager> + +#include <kapplication.h> + +#undef Region + +class SalKDEDisplay; + +/* #i59042# override KApplications method for session management + * since it will interfere badly with our own. + */ +class VCLKDEApplication : public KApplication +{ + public: + VCLKDEApplication(); + + virtual void commitData(QSessionManager&) {}; + + virtual bool x11EventFilter(XEvent* event); + + SalKDEDisplay* disp; +};
\ No newline at end of file diff --git a/vcl/unx/kde4/main.cxx b/vcl/unx/kde4/main.cxx new file mode 100644 index 000000000000..2a48624d9d14 --- /dev/null +++ b/vcl/unx/kde4/main.cxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2009 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#define Region QtXRegion +#include <QApplication> +#undef Region + +#include "KDEData.hxx" +#include "KDESalInstance.hxx" + +#if OSL_DEBUG_LEVEL > 1 +#include <stdio.h> +#endif + +#include <rtl/string.hxx> + +/// entry point for the KDE4 VCL plugin +extern "C" { + VCL_DLLPUBLIC SalInstance* create_SalInstance( oslModule ) + { +#if QT_VERSION < 0x050000 + // Qt 4.x support needs >= 4.1.0 + rtl::OString aVersion( qVersion() ); +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "qt version string is \"%s\"\n", aVersion.getStr() ); +#endif + sal_Int32 nIndex = 0, nMajor = 0, nMinor = 0, nMicro = 0; + nMajor = aVersion.getToken( 0, '.', nIndex ).toInt32(); + if( nIndex > 0 ) + nMinor = aVersion.getToken( 0, '.', nIndex ).toInt32(); + if( nIndex > 0 ) + nMicro = aVersion.getToken( 0, '.', nIndex ).toInt32(); + if( nMajor != 4 || nMinor < 1 ) + { +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "unsuitable qt version %d.%d.%d\n", nMajor, nMinor, nMicro ); +#endif + return NULL; + } +#endif + + KDESalInstance* pInstance = new KDESalInstance( new SalYieldMutex() ); +#if OSL_DEBUG_LEVEL > 1 + fprintf( stderr, "created KDESalInstance 0x%p\n", pInstance ); +#endif + + // initialize SalData + KDEData *salData = new KDEData(); + SetSalData(salData); + salData->m_pInstance = pInstance; + salData->Init(); + salData->initNWF(); + + return pInstance; + } +} diff --git a/vcl/unx/kde4/makefile.mk b/vcl/unx/kde4/makefile.mk new file mode 100644 index 000000000000..48a2dc87c3a6 --- /dev/null +++ b/vcl/unx/kde4/makefile.mk @@ -0,0 +1,92 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.10 $ +# +# 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. +# +#************************************************************************* + +PRJ=..$/.. + +PRJNAME=vcl +TARGET=kde4plug +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# workaround for makedepend hang +MKDEPENDSOLVER= + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile2.pmk + +# For some of the included external KDE headers, GCC complains about shadowed +# symbols in instantiated template code only at the end of a compilation unit, +# so the only solution is to disable that warning here: +.IF "$(COM)" == "GCC" +CFLAGSCXX+=-Wno-shadow +.ENDIF + +# --- Files -------------------------------------------------------- + +.IF "$(GUIBASE)"!="unx" + +dummy: + @echo "Nothing to build for GUIBASE $(GUIBASE)" + +.ELSE # "$(GUIBASE)"!="unx" + +.IF "$(ENABLE_KDE4)" != "" + +CFLAGS+=$(KDE4_CFLAGS) + +.IF "$(ENABLE_RANDR)" != "" +CDEFS+=-DUSE_RANDR +.ENDIF + +SLOFILES=\ + $(SLO)$/main.obj \ + $(SLO)$/VCLKDEApplication.obj \ + $(SLO)$/KDEXLib.obj \ + $(SLO)$/KDESalDisplay.obj \ + $(SLO)$/KDESalFrame.obj \ + $(SLO)$/KDESalGraphics.obj \ + $(SLO)$/KDESalInstance.obj \ + $(SLO)$/KDEData.obj + + +.ELSE # "$(ENABLE_KDE4)" != "" + +dummy: + @echo KDE disabled - nothing to build +.ENDIF +.ENDIF # "$(GUIBASE)"!="unx" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +.INCLUDE : $(PRJ)$/util$/target.pmk diff --git a/vcl/unx/source/gdi/makefile.mk b/vcl/unx/source/gdi/makefile.mk index 8f0faf863af2..bdd400baa8ad 100644 --- a/vcl/unx/source/gdi/makefile.mk +++ b/vcl/unx/source/gdi/makefile.mk @@ -90,6 +90,10 @@ ENVCFLAGS+=-DUSE_CDE CFLAGS+=-DXRENDER_LINK .ENDIF +.IF "$(ENABLE_GRAPHITE)" == "TRUE" +CFLAGS+=-DENABLE_GRAPHITE +.ENDIF + .ENDIF # "$(GUIBASE)"!="unx" # --- Targets ------------------------------------------------------ diff --git a/vcl/unx/source/gdi/pspgraphics.cxx b/vcl/unx/source/gdi/pspgraphics.cxx index e8dfe391dc86..18a54ef0d770 100644 --- a/vcl/unx/source/gdi/pspgraphics.cxx +++ b/vcl/unx/source/gdi/pspgraphics.cxx @@ -51,6 +51,11 @@ #include <sys/stat.h> #include <sys/types.h> +#ifdef ENABLE_GRAPHITE +#include <vcl/graphite_layout.hxx> +#include <vcl/graphite_serverfont.hxx> +#endif + using namespace psp; using namespace rtl; @@ -699,9 +704,30 @@ static void DrawPrinterLayout( const SalLayout& rLayout, ::psp::PrinterGfx& rGfx Point aPos; long nUnitsPerPixel = rLayout.GetUnitsPerPixel(); - const sal_Unicode* pText = bIsPspServerFontLayout ? static_cast<const PspServerFontLayout&>(rLayout).getTextPtr() : NULL; - int nMinCharPos = bIsPspServerFontLayout ? static_cast<const PspServerFontLayout&>(rLayout).getMinCharPos() : 0; - int nMaxCharPos = bIsPspServerFontLayout ? static_cast<const PspServerFontLayout&>(rLayout).getMaxCharPos() : 0; + const sal_Unicode* pText = NULL; + int nMinCharPos = 0; + int nMaxCharPos = 0; + if (bIsPspServerFontLayout) + { + const PspServerFontLayout * pPspLayout = dynamic_cast<const PspServerFontLayout*>(&rLayout); +#ifdef ENABLE_GRAPHITE + const GraphiteServerFontLayout * pGrLayout = dynamic_cast<const GraphiteServerFontLayout*>(&rLayout); +#endif + if (pPspLayout) + { + pText = pPspLayout->getTextPtr(); + nMinCharPos = pPspLayout->getMinCharPos(); + nMaxCharPos = pPspLayout->getMaxCharPos(); + } +#ifdef ENABLE_GRAPHITE + else if (pGrLayout) + { + pText = pGrLayout->getTextPtr(); + nMinCharPos = pGrLayout->getMinCharPos(); + nMaxCharPos = pGrLayout->getMaxCharPos(); + } +#endif + } for( int nStart = 0;; ) { int nGlyphCount = rLayout.GetNextGlyphs( nMaxGlyphs, aGlyphAry, aPos, nStart, aWidthAry, bIsPspServerFontLayout ? aCharPosAry : NULL ); @@ -961,7 +987,21 @@ SalLayout* PspGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel if( m_pServerFont[ nFallbackLevel ] && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) ) - pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs ); + { +#ifdef ENABLE_GRAPHITE + // Is this a Graphite font? + if (GraphiteFontAdaptor::IsGraphiteEnabledFont(*m_pServerFont[nFallbackLevel])) + { + sal_Int32 xdpi, ydpi; + GetResolution(xdpi, ydpi); + GraphiteFontAdaptor * pGrfont = new GraphiteFontAdaptor( *m_pServerFont[nFallbackLevel], xdpi, ydpi); + if (!pGrfont) return NULL; + pLayout = new GraphiteServerFontLayout(pGrfont); + } + else +#endif + pLayout = new PspServerFontLayout( *m_pPrinterGfx, *m_pServerFont[nFallbackLevel], rArgs ); + } else pLayout = new PspFontLayout( *m_pPrinterGfx ); diff --git a/vcl/unx/source/gdi/salgdi.cxx b/vcl/unx/source/gdi/salgdi.cxx index db49c97de00c..4d3e40840a7b 100644 --- a/vcl/unx/source/gdi/salgdi.cxx +++ b/vcl/unx/source/gdi/salgdi.cxx @@ -1,1539 +1,1553 @@ -/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2008 by Sun Microsystems, Inc.
- *
- * 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.
- *
- ************************************************************************/
-
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_vcl.hxx"
-
-#include "Xproto.h"
-
-#include "salunx.h"
-#include "saldata.hxx"
-#include "saldisp.hxx"
-#include "salgdi.h"
-#include "salframe.h"
-#include "salvd.h"
-#include "xrender_peer.hxx"
-
-#include "vcl/printergfx.hxx"
-#include "vcl/jobdata.hxx"
-
-#include "tools/debug.hxx"
-
-#include "basegfx/polygon/b2dpolygon.hxx"
-#include "basegfx/polygon/b2dpolypolygon.hxx"
-#include "basegfx/polygon/b2dpolypolygontools.hxx"
-#include "basegfx/polygon/b2dpolygontools.hxx"
-#include "basegfx/polygon/b2dpolygonclipper.hxx"
-#include "basegfx/polygon/b2dlinegeometry.hxx"
-#include "basegfx/matrix/b2dhommatrix.hxx"
-#include "basegfx/polygon/b2dpolypolygoncutter.hxx"
-
-#include <vector>
-#include <queue>
-#include <set>
-
-// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#define STATIC_POINTS 64
-
-class SalPolyLine
-{
- XPoint Points_[STATIC_POINTS];
- XPoint *pFirst_;
-public:
- inline SalPolyLine( ULONG nPoints );
- inline SalPolyLine( ULONG nPoints, const SalPoint *p );
- inline ~SalPolyLine();
- inline XPoint &operator [] ( ULONG n ) const
- { return pFirst_[n]; }
-};
-
-inline SalPolyLine::SalPolyLine( ULONG nPoints )
- : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
-{}
-
-inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p )
- : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ )
-{
- for( ULONG i = 0; i < nPoints; i++ )
- {
- pFirst_[i].x = (short)p[i].mnX;
- pFirst_[i].y = (short)p[i].mnY;
- }
- pFirst_[nPoints] = pFirst_[0]; // close polyline
-}
-
-inline SalPolyLine::~SalPolyLine()
-{ if( pFirst_ != Points_ ) delete [] pFirst_; }
-
-#undef STATIC_POINTS
-// -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-X11SalGraphics::X11SalGraphics()
-{
- m_pFrame = NULL;
- m_pVDev = NULL;
- m_pDeleteColormap = NULL;
- hDrawable_ = None;
- m_aRenderPicture = 0;
- m_pRenderFormat = NULL;
-
- pClipRegion_ = NULL;
- pPaintRegion_ = NULL;
-
- pPenGC_ = NULL;
- nPenPixel_ = 0;
- nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
- pFontGC_ = NULL;
- for( int i = 0; i < MAX_FALLBACK; ++i )
- {
- mXFont[i] = NULL;
- mpServerFont[i] = NULL;
- }
-
- nTextPixel_ = 0;
- nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black
-
- pBrushGC_ = NULL;
- nBrushPixel_ = 0;
- nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White
- hBrush_ = None;
-
- pMonoGC_ = NULL;
- pCopyGC_ = NULL;
- pMaskGC_ = NULL;
- pInvertGC_ = NULL;
- pInvert50GC_ = NULL;
- pStippleGC_ = NULL;
- pTrackingGC_ = NULL;
-
- bWindow_ = FALSE;
- bPrinter_ = FALSE;
- bVirDev_ = FALSE;
- bPenGC_ = FALSE;
- bFontGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
- bXORMode_ = FALSE;
- bDitherBrush_ = FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-X11SalGraphics::~X11SalGraphics()
-{
- ReleaseFonts();
- freeResources();
-}
-
-// -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-void X11SalGraphics::freeResources()
-{
- Display *pDisplay = GetXDisplay();
-
- DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" );
- if( pClipRegion_ ) XDestroyRegion( pClipRegion_ ), pClipRegion_ = None;
-
- if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None;
- if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None;
- if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None;
- if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None;
- if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None;
- if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None;
- if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None;
- if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None;
- if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None;
- if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None;
- if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None;
- if( m_pDeleteColormap )
- delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL;
-
- if( m_aRenderPicture )
- XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0;
-
- bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false;
-}
-
-void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen )
-{
- // shortcut if nothing changed
- if( hDrawable_ == aDrawable )
- return;
-
- // free screen specific resources if needed
- if( nScreen != m_nScreen )
- {
- freeResources();
- m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen );
- m_nScreen = nScreen;
- }
-
- hDrawable_ = aDrawable;
- SetXRenderFormat( NULL );
- if( m_aRenderPicture )
- {
- XRenderPeer::GetInstance().FreePicture( m_aRenderPicture );
- m_aRenderPicture = 0;
- }
-
- if( hDrawable_ )
- {
- nPenPixel_ = GetPixel( nPenColor_ );
- nTextPixel_ = GetPixel( nTextColor_ );
- nBrushPixel_ = GetPixel( nBrushColor_ );
- }
-}
-
-void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen )
-{
-#if 0 // TODO: use SetDrawable() instead
- m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen);
- hDrawable_ = aTarget;
- m_nScreen = nScreen;
- SetXRenderFormat( NULL );
- if( m_aRenderPicture )
- XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0;
-
- nPenPixel_ = GetPixel( nPenColor_ );
- nTextPixel_ = GetPixel( nTextColor_ );
- nBrushPixel_ = GetPixel( nBrushColor_ );
-#else
- m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen);
- m_nScreen = nScreen;
- SetDrawable( aTarget, nScreen );
-#endif
-
- bWindow_ = TRUE;
- m_pFrame = pFrame;
- m_pVDev = NULL;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::DeInit()
-{
- SetDrawable( None, m_nScreen );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const
-{
- Display *pDisplay = GetXDisplay();
-
- int n = 0;
- XLIB_Region Regions[3];
-
- if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ )
- Regions[n++] = pClipRegion_;
-// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ )
-// Regions[n++] = pPaintRegion_;
-
- if( pXReg && !XEmptyRegion( pXReg ) )
- Regions[n++] = pXReg;
-
- if( 0 == n )
- XSetClipMask( pDisplay, pGC, None );
- else if( 1 == n )
- XSetRegion( pDisplay, pGC, Regions[0] );
- else
- {
- XLIB_Region pTmpRegion = XCreateRegion();
- XIntersectRegion( Regions[0], Regions[1], pTmpRegion );
-// if( 3 == n )
-// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion );
- XSetRegion( pDisplay, pGC, pTmpRegion );
- XDestroyRegion( pTmpRegion );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-GC X11SalGraphics::SelectPen()
-{
- Display *pDisplay = GetXDisplay();
-
- if( !pPenGC_ )
- {
- XGCValues values;
- values.subwindow_mode = ClipByChildren;
- values.fill_rule = EvenOddRule; // Pict import/ Gradient
- values.graphics_exposures = False;
-
- pPenGC_ = XCreateGC( pDisplay, hDrawable_,
- GCSubwindowMode | GCFillRule | GCGraphicsExposures,
- &values );
- }
-
- if( !bPenGC_ )
- {
- if( nPenColor_ != SALCOLOR_NONE )
- XSetForeground( pDisplay, pPenGC_, nPenPixel_ );
- XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pPenGC_ );
- bPenGC_ = TRUE;
- }
-
- return pPenGC_;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-GC X11SalGraphics::SelectBrush()
-{
- Display *pDisplay = GetXDisplay();
-
- DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" );
-
- if( !pBrushGC_ )
- {
- XGCValues values;
- // values.subwindow_mode = IncludeInferiors;
- values.subwindow_mode = ClipByChildren;
- values.fill_rule = EvenOddRule; // Pict import/ Gradient
- values.graphics_exposures = False;
-
- pBrushGC_ = XCreateGC( pDisplay, hDrawable_,
- GCSubwindowMode | GCFillRule | GCGraphicsExposures,
- &values );
- }
-
- if( !bBrushGC_ )
- {
- if( !bDitherBrush_ )
- {
- XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
- XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ );
- #if defined(_USE_PRINT_EXTENSION_)
- XSetBackground( pDisplay, pBrushGC_,
- WhitePixel(pDisplay, DefaultScreen(pDisplay)) );
- #else
- if( bPrinter_ )
- XSetTile( pDisplay, pBrushGC_, None );
- #endif
- }
- else
- {
- // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect
- // changes of the tile. PROPERTY_BUG_Tile doesn't fix this !
- if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile)
- XSetFillStyle ( pDisplay, pBrushGC_, FillSolid );
-
- XSetFillStyle ( pDisplay, pBrushGC_, FillTiled );
- XSetTile ( pDisplay, pBrushGC_, hBrush_ );
- }
- XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy );
- SetClipRegion( pBrushGC_ );
-
- bBrushGC_ = TRUE;
- }
-
- return pBrushGC_;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-GC X11SalGraphics::GetTrackingGC()
-{
- const char dash_list[2] = {2, 2};
-
- if( !pTrackingGC_ )
- {
- XGCValues values;
-
- values.graphics_exposures = False;
- values.foreground = m_pColormap->GetBlackPixel()
- ^ m_pColormap->GetWhitePixel();
- values.function = GXxor;
- values.line_width = 1;
- values.line_style = LineOnOffDash;
-
- pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(),
- GCGraphicsExposures | GCForeground | GCFunction
- | GCLineWidth | GCLineStyle,
- &values );
- XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 );
- }
-
- if( !bTrackingGC_ )
- {
- SetClipRegion( pTrackingGC_ );
- bTrackingGC_ = TRUE;
- }
-
- return pTrackingGC_;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::DrawLines( ULONG nPoints,
- const SalPolyLine &rPoints,
- GC pGC,
- bool bClose
- )
-{
- // errechne wie viele Linien XWindow auf einmal zeichnen kann
- ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq))
- / sizeof(xPoint);
- if( nMaxLines > nPoints ) nMaxLines = nPoints;
-
- // gebe alle Linien aus, die XWindows zeichnen kann.
- ULONG n;
- for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 )
- XDrawLines( GetXDisplay(),
- GetDrawable(),
- pGC,
- &rPoints[n],
- nMaxLines,
- CoordModeOrigin );
-
- if( n < nPoints )
- XDrawLines( GetXDisplay(),
- GetDrawable(),
- pGC,
- &rPoints[n],
- nPoints - n,
- CoordModeOrigin );
- if( bClose )
- {
- if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y )
- drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-// Dithern: Calculate a dither-pixmap and make a brush of it
-#define P_DELTA 51
-#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA))
-
-BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor )
-{
- static const short nOrdDither8Bit[ 8 ][ 8 ] =
- {
- { 0, 38, 9, 48, 2, 40, 12, 50},
- {25, 12, 35, 22, 28, 15, 37, 24},
- { 6, 44, 3, 41, 8, 47, 5, 44},
- {32, 19, 28, 16, 34, 21, 31, 18},
- { 1, 40, 11, 49, 0, 39, 10, 48},
- {27, 14, 36, 24, 26, 13, 36, 23},
- { 8, 46, 4, 43, 7, 45, 4, 42},
- {33, 20, 30, 17, 32, 20, 29, 16}
- };
-
- // test for correct depth (8bit)
- if( GetColormap().GetVisual().GetDepth() != 8 )
- return FALSE;
-
- char pBits[64];
- char *pBitsPtr = pBits;
-
- // Set the pallette-entries for the dithering tile
- UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor );
- UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor );
- UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor );
-
- for( int nY = 0; nY < 8; nY++ )
- {
- for( int nX = 0; nX < 8; nX++ )
- {
- short nMagic = nOrdDither8Bit[nY][nX];
- UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic );
- UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic );
- UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic );
-
- *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) );
- }
- }
-
- // create the tile as ximage and an according pixmap -> caching
- XImage *pImage = XCreateImage( GetXDisplay(),
- GetColormap().GetXVisual(),
- 8,
- ZPixmap,
- 0, // offset
- pBits, // data
- 8, 8, // width & height
- 8, // bitmap_pad
- 0 ); // (default) bytes_per_line
-
- if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile )
- {
- if (hBrush_)
- XFreePixmap (GetXDisplay(), hBrush_);
- hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
- }
- else
- if( !hBrush_ )
- hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 );
-
- // put the ximage to the pixmap
- XPutImage( GetXDisplay(),
- hBrush_,
- GetDisplay()->GetCopyGC( m_nScreen ),
- pImage,
- 0, 0, // Source
- 0, 0, // Destination
- 8, 8 ); // width & height
-
- // destroy image-frame but not palette-data
- pImage->data = NULL;
- XDestroyImage( pImage );
-
- return TRUE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const
-{
- const SalDisplay *pDisplay = GetDisplay();
-
- rDPIX = pDisplay->GetResolution().A();
- rDPIY = pDisplay->GetResolution().B();
- if( !pDisplay->GetExactResolution() && rDPIY < 96 )
- {
- rDPIX = Divide( rDPIX * 96, rDPIY );
- rDPIY = 96;
- }
- else if ( rDPIY > 200 )
- {
- rDPIX = Divide( rDPIX * 200, rDPIY );
- rDPIY = 200;
- }
-
- // #i12705# equalize x- and y-resolution if they are close enough
- if( rDPIX != rDPIY )
- {
- // different x- and y- resolutions are usually artifacts of
- // a wrongly calculated screen size.
- //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30%
- {
-#ifdef DEBUG
- printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n",
- rDPIX,rDPIY,rDPIY,rDPIY);
-#endif
- rDPIX = rDPIY; // y-resolution is more trustworthy
- }
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-USHORT X11SalGraphics::GetBitCount() // const
-{
- return GetVisual().GetDepth();
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-long X11SalGraphics::GetGraphicsWidth() const
-{
- if( m_pFrame )
- return m_pFrame->maGeometry.nWidth;
- else if( m_pVDev )
- return m_pVDev->GetWidth();
- else
- return 0;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-long X11SalGraphics::GetGraphicsHeight() const
-{
- if( m_pFrame )
- return m_pFrame->maGeometry.nHeight;
- else if( m_pVDev )
- return m_pVDev->GetHeight();
- else
- return 0;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::ResetClipRegion()
-{
- if( pClipRegion_ )
- {
- bPenGC_ = FALSE;
- bFontGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
-
- XDestroyRegion( pClipRegion_ );
- pClipRegion_ = NULL;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::BeginSetClipRegion( ULONG )
-{
- if( pClipRegion_ )
- XDestroyRegion( pClipRegion_ );
- pClipRegion_ = XCreateRegion();
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-BOOL X11SalGraphics::unionClipRegion( long nX, long nY, long nDX, long nDY )
-{
- if (!nDX || !nDY)
- return TRUE;
-
- XRectangle aRect;
- aRect.x = (short)nX;
- aRect.y = (short)nY;
- aRect.width = (unsigned short)nDX;
- aRect.height = (unsigned short)nDY;
-
- XUnionRectWithRegion( &aRect, pClipRegion_, pClipRegion_ );
-
- return TRUE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-bool X11SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& )
-{
- // TODO: implement and advertise OutDevSupport_B2DClip support
- return false;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::EndSetClipRegion()
-{
- bPenGC_ = FALSE;
- bFontGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
-
- if( XEmptyRegion( pClipRegion_ ) )
- {
- XDestroyRegion( pClipRegion_ );
- pClipRegion_= NULL;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetLineColor()
-{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetLineColor( SalColor nSalColor )
-{
- if( nPenColor_ != nSalColor )
- {
- nPenColor_ = nSalColor;
- nPenPixel_ = GetPixel( nSalColor );
- bPenGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetFillColor()
-{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- bDitherBrush_ = FALSE;
- nBrushColor_ = SALCOLOR_NONE;
- bBrushGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetFillColor( SalColor nSalColor )
-{
- if( nBrushColor_ != nSalColor )
- {
- bDitherBrush_ = FALSE;
- nBrushColor_ = nSalColor;
- nBrushPixel_ = GetPixel( nSalColor );
- if( TrueColor != GetColormap().GetVisual().GetClass()
- && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown
- && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray
- && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray
- && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue
- && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green
- && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown
- && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) )
- bDitherBrush_ = GetDitherPixmap(nSalColor);
- bBrushGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor )
-{
- switch( nROPColor )
- {
- case SAL_ROP_0 : // 0
- nPenPixel_ = (Pixel)0;
- break;
- case SAL_ROP_1 : // 1
- nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- case SAL_ROP_INVERT : // 2
- nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- }
- nPenColor_ = GetColormap().GetColor( nPenPixel_ );
- bPenGC_ = FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor )
-{
- switch( nROPColor )
- {
- case SAL_ROP_0 : // 0
- nBrushPixel_ = (Pixel)0;
- break;
- case SAL_ROP_1 : // 1
- nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- case SAL_ROP_INVERT : // 2
- nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1;
- break;
- }
- bDitherBrush_ = FALSE;
- nBrushColor_ = GetColormap().GetColor( nBrushPixel_ );
- bBrushGC_ = FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::SetXORMode( bool bSet, bool )
-{
- if( !bXORMode_ == bSet )
- {
- bXORMode_ = bSet;
- bPenGC_ = FALSE;
- bBrushGC_ = FALSE;
- bMonoGC_ = FALSE;
- bCopyGC_ = FALSE;
- bInvertGC_ = FALSE;
- bInvert50GC_ = FALSE;
- bStippleGC_ = FALSE;
- bTrackingGC_ = FALSE;
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPixel( long nX, long nY )
-{
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY );
-}
-
-void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
-{
- if( nSalColor != SALCOLOR_NONE )
- {
- Display *pDisplay = GetXDisplay();
-
- if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ )
- {
- SetLineColor( nSalColor );
- XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY );
- nPenColor_ = SALCOLOR_NONE;
- bPenGC_ = False;
- }
- else
- {
- GC pGC = SelectPen();
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) );
-
- XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY );
-
- if( nSalColor != nPenColor_ )
- XSetForeground( pDisplay, pGC, nPenPixel_ );
- }
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
-{
- if( nPenColor_ != SALCOLOR_NONE )
- {
- if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine )
- {
- GC aGC = SelectPen();
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1);
- XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2);
- XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 );
- }
- else
- XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(),
- nX1, nY1, nX2, nY2 );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY )
-{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- nX, nY, nDX, nDY );
- }
- // Beschreibung DrawRect verkehrt, deshalb -1
- if( nPenColor_ != SALCOLOR_NONE )
- XDrawRectangle( GetXDisplay(),
- GetDrawable(),
- SelectPen(),
- nX, nY, nDX-1, nDY-1 );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry )
-{
- drawPolyLine( nPoints, pPtAry, false );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry, bool bClose )
-{
- if( nPenColor_ != 0xFFFFFFFF )
- {
- SalPolyLine Points( nPoints, pPtAry );
-
- DrawLines( nPoints, Points, SelectPen(), bClose );
- }
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry )
-{
- if( nPoints == 0 )
- return;
-
- if( nPoints < 3 )
- {
- if( !bXORMode_ )
- {
- if( 1 == nPoints )
- drawPixel( pPtAry[0].mnX, pPtAry[0].mnY );
- else
- drawLine( pPtAry[0].mnX, pPtAry[0].mnY,
- pPtAry[1].mnX, pPtAry[1].mnY );
- }
- return;
- }
-
- SalPolyLine Points( nPoints, pPtAry );
-
- nPoints++;
-
- /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case)
- * do not draw the visible part of a polygon
- * if it overlaps to the left of screen 0,y.
- * This happens to be the case in the gradient drawn in the
- * menubar background. workaround for the special case of
- * of a rectangle overlapping to the left.
- */
- if( nPoints == 5 &&
- Points[ 0 ].x == Points[ 1 ].x &&
- Points[ 1 ].y == Points[ 2 ].y &&
- Points[ 2 ].x == Points[ 3 ].x &&
- Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y
- )
- {
- bool bLeft = false;
- bool bRight = false;
- for(unsigned int i = 0; i < nPoints; i++ )
- {
- if( Points[i].x < 0 )
- bLeft = true;
- else
- bRight= true;
- }
- if( bLeft && ! bRight )
- return;
- if( bLeft && bRight )
- {
- for( unsigned int i = 0; i < nPoints; i++ )
- if( Points[i].x < 0 )
- Points[i].x = 0;
- }
- }
-
- if( nBrushColor_ != SALCOLOR_NONE )
- XFillPolygon( GetXDisplay(),
- GetDrawable(),
- SelectBrush(),
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-
- if( nPenColor_ != 0xFFFFFFFF )
- DrawLines( nPoints, Points, SelectPen(), true );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
- const sal_uInt32 *pPoints,
- PCONSTSALPOINT *pPtAry )
-{
- if( nBrushColor_ != SALCOLOR_NONE )
- {
- ULONG i, n;
- XLIB_Region pXRegA = NULL;
-
- for( i = 0; i < nPoly; i++ ) {
- n = pPoints[i];
- SalPolyLine Points( n, pPtAry[i] );
- if( n > 2 )
- {
- XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule );
- if( !pXRegA )
- pXRegA = pXRegB;
- else
- {
- XXorRegion( pXRegA, pXRegB, pXRegA );
- XDestroyRegion( pXRegB );
- }
- }
- }
-
- if( pXRegA )
- {
- XRectangle aXRect;
- XClipBox( pXRegA, &aXRect );
-
- GC pGC = SelectBrush();
- SetClipRegion( pGC, pXRegA ); // ??? doppelt
- XDestroyRegion( pXRegA );
- bBrushGC_ = FALSE;
-
- XFillRectangle( GetXDisplay(),
- GetDrawable(),
- pGC,
- aXRect.x, aXRect.y, aXRect.width, aXRect.height );
- }
- }
-
- if( nPenColor_ != SALCOLOR_NONE )
- for( ULONG i = 0; i < nPoly; i++ )
- drawPolyLine( pPoints[i], pPtAry[i], true );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-sal_Bool X11SalGraphics::drawPolyLineBezier( ULONG, const SalPoint*, const BYTE* )
-{
- return sal_False;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-sal_Bool X11SalGraphics::drawPolygonBezier( ULONG, const SalPoint*, const BYTE* )
-{
- return sal_False;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*,
- const SalPoint* const*, const BYTE* const* )
-{
- return sal_False;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-void X11SalGraphics::invert( ULONG nPoints,
- const SalPoint* pPtAry,
- SalInvert nFlags )
-{
- SalPolyLine Points ( nPoints, pPtAry );
-
- GC pGC;
- if( SAL_INVERT_50 & nFlags )
- pGC = GetInvert50GC();
- else
- if ( SAL_INVERT_TRACKFRAME & nFlags )
- pGC = GetTrackingGC();
- else
- pGC = GetInvertGC();
-
- if( SAL_INVERT_TRACKFRAME & nFlags )
- DrawLines ( nPoints, Points, pGC, true );
- else
- XFillPolygon( GetXDisplay(),
- GetDrawable(),
- pGC,
- &Points[0], nPoints,
- Complex, CoordModeOrigin );
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG )
-{
- return FALSE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-XID X11SalGraphics::GetXRenderPicture()
-{
- if( !m_aRenderPicture )
- {
- // check xrender support for matching visual
- // find a XRenderPictFormat compatible with the Drawable
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- XRenderPictFormat* pVisualFormat = static_cast<XRenderPictFormat*>(GetXRenderFormat());
- if( !pVisualFormat )
- {
- Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual();
- pVisualFormat = rRenderPeer.FindVisualFormat( pVisual );
- if( !pVisualFormat )
- return 0;
- // cache the XRenderPictFormat
- SetXRenderFormat( static_cast<void*>(pVisualFormat) );
- }
-
- // get the matching xrender target for drawable
- m_aRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL );
- }
-
-#if 0
- // setup clipping so the callers don't have to do it themselves
- // TODO: avoid clipping if already set correctly
- if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
- rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
-#endif
-
- return m_aRenderPicture;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-SystemGraphicsData X11SalGraphics::GetGraphicsData() const
-{
- SystemGraphicsData aRes;
-
- aRes.nSize = sizeof(aRes);
- aRes.pDisplay = GetXDisplay();
- aRes.hDrawable = hDrawable_;
- aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual();
- aRes.nScreen = m_nScreen;
- aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth();
- aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap();
- aRes.pRenderFormat = m_pRenderFormat;
- return aRes;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-// B2DPolygon support methods
-
-namespace { // anonymous namespace to prevent export
-// the methods and structures here are used by the
-// B2DPolyPolygon->RenderTrapezoid conversion algorithm
-
-// compare two line segments
-// assumption: both segments point downward
-// assumption: they must have at least some y-overlap
-// assumption: rA.p1.y <= rB.p1.y
-bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB )
-{
- bool bAbove = (rA.p1.y <= rB.p1.y);
- const XLineFixed& rU = bAbove ? rA : rB;
- const XLineFixed& rL = bAbove ? rB : rA;
-
- const XFixed aXDiff = rU.p2.x - rU.p1.x;
- const XFixed aYDiff = rU.p2.y - rU.p1.y;
-
- if( (rU.p1.y != rL.p1.y) || (rU.p1.x != rL.p1.x) )
- {
- const sal_Int64 n1 = (sal_Int64)aXDiff * (rL.p1.y - rU.p1.y);
- const sal_Int64 n2 = (sal_Int64)aYDiff * (rL.p1.x - rU.p1.x);
- if( n1 != n2 )
- return ((n1 < n2) == bAbove);
- }
-
- if( (rU.p2.y != rL.p2.y) || (rU.p2.x != rL.p2.x) )
- {
- const sal_Int64 n3 = (sal_Int64)aXDiff * (rL.p2.y - rU.p1.y);
- const sal_Int64 n4 = (sal_Int64)aYDiff * (rL.p2.x - rU.p1.x);
- if( n3 != n4 )
- return ((n3 < n4) == bAbove);
- }
-
- // both segments overlap
- return false;
-}
-
-struct HalfTrapezoid
-{
- // assumptions:
- // maLine.p1.y <= mnY < maLine.p2.y
- XLineFixed maLine;
- XFixed mnY;
-};
-
-struct HalfTrapCompare
-{
- bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const
- {
- bool bIsTopLeft = false;
- if( rA.mnY != rB.mnY ) // sort top-first if possible
- bIsTopLeft = (rA.mnY < rB.mnY);
- else // else sort left-first
- bIsTopLeft = IsLeftOf( rA.maLine, rB.maLine );
- // adjust to priority_queue sorting convention
- return !bIsTopLeft;
- }
-};
-
-typedef std::priority_queue< HalfTrapezoid, std::vector<HalfTrapezoid>, HalfTrapCompare > HTQueueBase;
-// we need a priority queue with a reserve() to prevent countless reallocations
-class HTQueue
-: public HTQueueBase
-{
-public:
- void reserve( size_t n ) { c.reserve( n ); }
- int capacity() { return c.capacity(); }
-};
-
-typedef std::vector<XTrapezoid> TrapezoidVector;
-
-class TrapezoidXCompare
-{
- const TrapezoidVector& mrVector;
-public:
- TrapezoidXCompare( const TrapezoidVector& rVector )
- : mrVector( rVector ) {}
- bool operator()( int nA, int nB ) const
- { return IsLeftOf( mrVector[nA].left, mrVector[nB].left ); }
-};
-
-typedef std::multiset< int, TrapezoidXCompare > ActiveTrapSet;
-
-class TrapezoidYCompare
-{
- const TrapezoidVector& mrVector;
-public:
- TrapezoidYCompare( const TrapezoidVector& rVector )
- : mrVector( rVector ) {}
- bool operator()( int nA, int nB ) const
- { return (mrVector[nA].bottom < mrVector[nB].bottom); }
-};
-
-typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet;
-} // end of anonymous namespace
-
-// draw a poly-polygon
-bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency)
-{
- // nothing to do for empty polypolygons
- const int nPolygonCount = rPolyPoly.count();
- if( nPolygonCount <= 0 )
- return TRUE;
-
- // nothing to do if everything is transparent
- if( (nBrushColor_ == SALCOLOR_NONE)
- && (nPenColor_ == SALCOLOR_NONE) )
- return TRUE;
-
- // cannot handle pencolor!=brushcolor yet
- if( (nPenColor_ != SALCOLOR_NONE)
- && (nPenColor_ != nBrushColor_) )
- return FALSE;
-
- // TODO: remove the env-variable when no longer needed
- static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" );
- if( pRenderEnv )
- return FALSE;
-
- // check xrender support for trapezoids
- XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- if( !rRenderPeer.AreTrapezoidsSupported() )
- return FALSE;
- Picture aDstPic = GetXRenderPicture();
- // check xrender support for this drawable
- if( !aDstPic )
- return FALSE;
-
- // don't bother with polygons outside of visible area
- const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() );
- const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rPolyPoly );
- const bool bNeedViewClip = !aPolyRange.isInside( aViewRange );
- if( !aPolyRange.overlaps( aViewRange ) )
- return true;
-
- // convert the polypolygon to trapezoids
-
- // first convert the B2DPolyPolygon to HalfTrapezoids
- // #i100922# try to prevent priority-queue reallocations by reservering enough
- int nHTQueueReserve = 0;
- for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx )
- {
- const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx );
- const int nPointCount = aOuterPolygon.count();
- nHTQueueReserve += aOuterPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount;
- }
- nHTQueueReserve = ((4*nHTQueueReserve) | 0x1FFF) + 1;
- HTQueue aHTQueue;
- aHTQueue.reserve( nHTQueueReserve );
- for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx )
- {
- const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx );
-
- // render-trapezoids should be inside the view => clip polygon against view range
- basegfx::B2DPolyPolygon aClippedPolygon( aOuterPolygon );
- if( bNeedViewClip )
- {
- aClippedPolygon = basegfx::tools::clipPolygonOnRange( aOuterPolygon, aViewRange, true, false );
- DBG_ASSERT( aClippedPolygon.count(), "polygon confirmed to overlap with view should not get here" );
- if( !aClippedPolygon.count() )
- continue;
- }
-
- // render-trapezoids have linear edges => get rid of bezier segments
- if( aClippedPolygon.areControlPointsUsed() )
- aClippedPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aClippedPolygon, 0.125 );
-
- // test and remove self intersections
- // TODO: make code intersection save, then remove this test
- basegfx::B2DPolyPolygon aInnerPolyPoly(basegfx::tools::solveCrossovers( aClippedPolygon));
- const int nInnerPolyCount = aInnerPolyPoly.count();
- for( int nInnerPolyIdx = 0; nInnerPolyIdx < nInnerPolyCount; ++nInnerPolyIdx )
- {
- ::basegfx::B2DPolygon aInnerPolygon = aInnerPolyPoly.getB2DPolygon( nInnerPolyIdx );
- const int nPointCount = aInnerPolygon.count();
- if( !nPointCount )
- continue;
-
- aHTQueue.reserve( aHTQueue.size() + 8 * nPointCount );
-
- // convert polygon point pairs to HalfTrapezoids
- // connect the polygon point with the first one if needed
- XPointFixed aOldXPF = { 0, 0 };
- XPointFixed aNewXPF;
- for( int nPointIdx = 0; nPointIdx <= nPointCount; ++nPointIdx, aOldXPF = aNewXPF )
- {
- const int k = (nPointIdx < nPointCount) ? nPointIdx : 0;
- const ::basegfx::B2DPoint& aPoint = aInnerPolygon.getB2DPoint( k );
-
- // convert the B2DPoint into XRENDER units
- if(getAntiAliasB2DDraw())
- {
- aNewXPF.x = XDoubleToFixed( aPoint.getX() );
- aNewXPF.y = XDoubleToFixed( aPoint.getY() );
- }
- else
- {
- aNewXPF.x = XDoubleToFixed( basegfx::fround( aPoint.getX() ) );
- aNewXPF.y = XDoubleToFixed( basegfx::fround( aPoint.getY() ) );
- }
-
- // check if enough data is available for a new HalfTrapezoid
- if( nPointIdx == 0 )
- continue;
- // ignore vertical segments
- if( aNewXPF.y == aOldXPF.y )
- continue;
-
- // construct HalfTrapezoid as topdown segment
- HalfTrapezoid aHT;
- if( aNewXPF.y < aOldXPF.y )
- {
- aHT.maLine.p1 = aNewXPF;
- aHT.maLine.p2 = aOldXPF;
- }
- else
- {
- aHT.maLine.p2 = aNewXPF;
- aHT.maLine.p1 = aOldXPF;
- }
-
- aHT.mnY = aHT.maLine.p1.y;
-
-#if 0 // ignore clipped HalfTrapezoids
- if( aHT.mnY < 0 )
- aHT.mnY = 0;
- else if( aHT.mnY > 10000 )
- continue;
-#endif
-
- // queue up the HalfTrapezoid
- aHTQueue.push( aHT );
- }
- }
- }
-
- if( aHTQueue.empty() )
- return TRUE;
-
- // then convert the HalfTrapezoids into full Trapezoids
- TrapezoidVector aTrapVector;
- aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess
-
- TrapezoidXCompare aTrapXCompare( aTrapVector );
- ActiveTrapSet aActiveTraps( aTrapXCompare );
-
- TrapezoidYCompare aTrapYCompare( aTrapVector );
- VerticalTrapSet aVerticalTraps( aTrapYCompare );
-
- while( !aHTQueue.empty() )
- {
- XTrapezoid aTrapezoid;
-
- // convert a HalfTrapezoid pair
- const HalfTrapezoid& rLeft = aHTQueue.top();
- aTrapezoid.top = rLeft.mnY;
- aTrapezoid.bottom = rLeft.maLine.p2.y;
- aTrapezoid.left = rLeft.maLine;
-
-#if 0
- // ignore empty trapezoids
- if( aTrapezoid.bottom <= aTrapezoid.top )
- continue;
-#endif
-
- aHTQueue.pop();
- if( aHTQueue.empty() ) // TODO: assert
- break;
- const HalfTrapezoid& rRight = aHTQueue.top();
- aTrapezoid.right = rRight.maLine;
- aHTQueue.pop();
-
- aTrapezoid.bottom = aTrapezoid.left.p2.y;
- if( aTrapezoid.bottom > aTrapezoid.right.p2.y )
- aTrapezoid.bottom = aTrapezoid.right.p2.y;
-
- // keep the full Trapezoid candidate
- aTrapVector.push_back( aTrapezoid );
-
- // unless it splits an older trapezoid
- bool bSplit = false;
- for(;;)
- {
- // check if the new trapezoid overlaps with an old trapezoid
- ActiveTrapSet::iterator aActiveTrapsIt
- = aActiveTraps.upper_bound( aTrapVector.size()-1 );
- if( aActiveTrapsIt == aActiveTraps.begin() )
- break;
- --aActiveTrapsIt;
-
- XTrapezoid& rLeftTrap = aTrapVector[ *aActiveTrapsIt ];
-
- // in the ActiveTrapSet there are still trapezoids where
- // a vertical overlap with new trapezoids is no longer possible
- // they could have been removed in the verticaltraps loop below
- // but this would have been expensive and is not needed as we can
- // simply ignore them now and remove them from the ActiveTrapSet
- // so they won't bother us in the future
- if( rLeftTrap.bottom <= aTrapezoid.top )
- {
- aActiveTraps.erase( aActiveTrapsIt );
- continue;
- }
-
- // check if there is horizontal overlap
- // aTrapezoid.left==rLeftTrap.right is allowed though
- if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) )
- break;
-
- // split the old trapezoid and keep its upper part
- // find the old trapezoids entry in the VerticalTrapSet and remove it
- typedef std::pair<VerticalTrapSet::iterator, VerticalTrapSet::iterator> VTSPair;
- VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt );
- VerticalTrapSet::iterator aVTSit = aVTSPair.first;
- for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ;
- if( aVTSit != aVTSPair.second )
- aVerticalTraps.erase( aVTSit );
- // then update the old trapezoid's bottom
- rLeftTrap.bottom = aTrapezoid.top;
- // enter the updated old trapzoid in VerticalTrapSet
- aVerticalTraps.insert( aVerticalTraps.begin(), *aActiveTrapsIt );
- // the old trapezoid is no longer active
- aActiveTraps.erase( aActiveTrapsIt );
-
- // the trapezoid causing the split has become obsolete
- // so its both sides have to be re-queued
- HalfTrapezoid aHT;
- aHT.mnY = aTrapezoid.top;
- aHT.maLine = aTrapezoid.left;
- aHTQueue.push( aHT );
- aHT.maLine = aTrapezoid.right;
- aHTQueue.push( aHT );
-
- bSplit = true;
- break;
- }
-
- // keep or forget the resulting full Trapezoid
- if( bSplit )
- aTrapVector.pop_back();
- else
- {
- aActiveTraps.insert( aTrapVector.size()-1 );
- aVerticalTraps.insert( aTrapVector.size()-1 );
- }
-
- // mark trapezoids that can no longer be split as inactive
- // and recycle their sides which were not fully resolved
- static const XFixed nMaxTop = +0x7FFFFFFF;
- XFixed nNewTop = aHTQueue.empty() ? nMaxTop : aHTQueue.top().mnY;
- while( !aVerticalTraps.empty() )
- {
- const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ];
- if( nNewTop < rOldTrap.bottom )
- break;
- // the reference Trapezoid can no longer be split
- aVerticalTraps.erase( aVerticalTraps.begin() );
-
- // recycle its sides that were not fully resolved
- HalfTrapezoid aHT;
- aHT.mnY = rOldTrap.bottom;
- if( rOldTrap.left.p2.y > rOldTrap.bottom )
- {
- aHT.maLine = rOldTrap.left;
- aHTQueue.push( aHT );
- }
- if( rOldTrap.right.p2.y > rOldTrap.bottom )
- {
- aHT.maLine = rOldTrap.right;
- aHTQueue.push( aHT );
- }
- }
- }
-
- // create xrender Picture for polygon foreground
- SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ];
- if( !rEntry.m_aPicture )
- {
- Display* pXDisplay = GetXDisplay();
-
- rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 );
- XRenderPictureAttributes aAttr;
- aAttr.repeat = true;
-
- XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 );
- rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr );
- }
-
- // set polygon foreground color and opacity
- XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency );
- rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 );
-
- // set clipping
- // TODO: move into GetXRenderPicture?
- if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) )
- rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ );
-
- // render the trapezoids
- const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8();
- rRenderPeer.CompositeTrapezoids( PictOpOver,
- rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() );
-
- return TRUE;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin)
-{
- const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance();
- if( !rRenderPeer.AreTrapezoidsSupported() )
- return false;
-
- // get the area polygon for the line polygon
- basegfx::B2DPolygon aPolygon = rPolygon;
- if( (rLineWidth.getX() != rLineWidth.getY())
- && !basegfx::fTools::equalZero( rLineWidth.getY() ) )
- {
- // prepare for createAreaGeometry() with anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() );
- aPolygon.transform( aAnisoMatrix );
- }
-
- // AW: reSegment no longer needed; new createAreaGeometry will remove exteme positions
- // and create bezier polygons
- //if( aPolygon.areControlPointsUsed() )
- // aPolygon = basegfx::tools::reSegmentPolygonEdges( aPolygon, 8, true, false );
- //const basegfx::B2DPolyPolygon aAreaPolyPoly = basegfx::tools::createAreaGeometryForSimplePolygon(
- // aPolygon, 0.5*rLineWidth.getX(), eLineJoin );
- const basegfx::B2DPolyPolygon aAreaPolyPoly(basegfx::tools::createAreaGeometry(aPolygon, 0.5*rLineWidth.getX(), eLineJoin));
-
- if( (rLineWidth.getX() != rLineWidth.getY())
- && !basegfx::fTools::equalZero( rLineWidth.getX() ) )
- {
- // postprocess createAreaGeometry() for anisotropic linewidth
- basegfx::B2DHomMatrix aAnisoMatrix;
- aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() );
- aPolygon.transform( aAnisoMatrix );
- }
-
- // temporarily adjust brush color to pen color
- // since the line is drawn as an area-polygon
- const SalColor aKeepBrushColor = nBrushColor_;
- nBrushColor_ = nPenColor_;
-
- // draw each area polypolygon component individually
- // to emulate the polypolygon winding rule "non-zero"
- bool bDrawOk = true;
- const int nPolyCount = aAreaPolyPoly.count();
- for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx )
- {
- const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) );
- bDrawOk = drawPolyPolygon( aOnePoly, 0.0);
- if( !bDrawOk )
- break;
- }
-
- // restore the original brush GC
- nBrushColor_ = aKeepBrushColor;
- return bDrawOk;
-}
-
-// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * 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. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include "Xproto.h" + +#include "salunx.h" +#include "saldata.hxx" +#include "saldisp.hxx" +#include "salgdi.h" +#include "salframe.h" +#include "salvd.h" +#include "xrender_peer.hxx" + +#include "vcl/printergfx.hxx" +#include "vcl/jobdata.hxx" + +#include "tools/debug.hxx" + +#include "basegfx/polygon/b2dpolygon.hxx" +#include "basegfx/polygon/b2dpolypolygon.hxx" +#include "basegfx/polygon/b2dpolypolygontools.hxx" +#include "basegfx/polygon/b2dpolygontools.hxx" +#include "basegfx/polygon/b2dpolygonclipper.hxx" +#include "basegfx/polygon/b2dlinegeometry.hxx" +#include "basegfx/matrix/b2dhommatrix.hxx" +#include "basegfx/polygon/b2dpolypolygoncutter.hxx" + +#include <vector> +#include <queue> +#include <set> + +// -=-= SalPolyLine =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#define STATIC_POINTS 64 + +class SalPolyLine +{ + XPoint Points_[STATIC_POINTS]; + XPoint *pFirst_; +public: + inline SalPolyLine( ULONG nPoints ); + inline SalPolyLine( ULONG nPoints, const SalPoint *p ); + inline ~SalPolyLine(); + inline XPoint &operator [] ( ULONG n ) const + { return pFirst_[n]; } +}; + +inline SalPolyLine::SalPolyLine( ULONG nPoints ) + : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) +{} + +inline SalPolyLine::SalPolyLine( ULONG nPoints, const SalPoint *p ) + : pFirst_( nPoints+1 > STATIC_POINTS ? new XPoint[nPoints+1] : Points_ ) +{ + for( ULONG i = 0; i < nPoints; i++ ) + { + pFirst_[i].x = (short)p[i].mnX; + pFirst_[i].y = (short)p[i].mnY; + } + pFirst_[nPoints] = pFirst_[0]; // close polyline +} + +inline SalPolyLine::~SalPolyLine() +{ if( pFirst_ != Points_ ) delete [] pFirst_; } + +#undef STATIC_POINTS +// -=-= X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +X11SalGraphics::X11SalGraphics() +{ + m_pFrame = NULL; + m_pVDev = NULL; + m_pDeleteColormap = NULL; + hDrawable_ = None; + m_aRenderPicture = 0; + m_pRenderFormat = NULL; + + pClipRegion_ = NULL; + pPaintRegion_ = NULL; + + pPenGC_ = NULL; + nPenPixel_ = 0; + nPenColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black + + pFontGC_ = NULL; + for( int i = 0; i < MAX_FALLBACK; ++i ) + { + mXFont[i] = NULL; + mpServerFont[i] = NULL; + } + + nTextPixel_ = 0; + nTextColor_ = MAKE_SALCOLOR( 0x00, 0x00, 0x00 ); // Black + +#ifdef ENABLE_GRAPHITE + // check if graphite fonts have been disabled + static const char* pDisableGraphiteStr = getenv( "SAL_DISABLE_GRAPHITE" ); + bDisableGraphite_ = pDisableGraphiteStr ? (pDisableGraphiteStr[0]!='0') : FALSE; +#endif + + pBrushGC_ = NULL; + nBrushPixel_ = 0; + nBrushColor_ = MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ); // White + hBrush_ = None; + + pMonoGC_ = NULL; + pCopyGC_ = NULL; + pMaskGC_ = NULL; + pInvertGC_ = NULL; + pInvert50GC_ = NULL; + pStippleGC_ = NULL; + pTrackingGC_ = NULL; + + bWindow_ = FALSE; + bPrinter_ = FALSE; + bVirDev_ = FALSE; + bPenGC_ = FALSE; + bFontGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + bXORMode_ = FALSE; + bDitherBrush_ = FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +X11SalGraphics::~X11SalGraphics() +{ + ReleaseFonts(); + freeResources(); +} + +// -=-= SalGraphics / X11SalGraphics =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void X11SalGraphics::freeResources() +{ + Display *pDisplay = GetXDisplay(); + + DBG_ASSERT( !pPaintRegion_, "pPaintRegion_" ); + if( pClipRegion_ ) XDestroyRegion( pClipRegion_ ), pClipRegion_ = None; + + if( hBrush_ ) XFreePixmap( pDisplay, hBrush_ ), hBrush_ = None; + if( pPenGC_ ) XFreeGC( pDisplay, pPenGC_ ), pPenGC_ = None; + if( pFontGC_ ) XFreeGC( pDisplay, pFontGC_ ), pFontGC_ = None; + if( pBrushGC_ ) XFreeGC( pDisplay, pBrushGC_ ), pBrushGC_ = None; + if( pMonoGC_ ) XFreeGC( pDisplay, pMonoGC_ ), pMonoGC_ = None; + if( pCopyGC_ ) XFreeGC( pDisplay, pCopyGC_ ), pCopyGC_ = None; + if( pMaskGC_ ) XFreeGC( pDisplay, pMaskGC_ ), pMaskGC_ = None; + if( pInvertGC_ ) XFreeGC( pDisplay, pInvertGC_ ), pInvertGC_ = None; + if( pInvert50GC_ ) XFreeGC( pDisplay, pInvert50GC_ ), pInvert50GC_ = None; + if( pStippleGC_ ) XFreeGC( pDisplay, pStippleGC_ ), pStippleGC_ = None; + if( pTrackingGC_ ) XFreeGC( pDisplay, pTrackingGC_ ), pTrackingGC_ = None; + if( m_pDeleteColormap ) + delete m_pDeleteColormap, m_pColormap = m_pDeleteColormap = NULL; + + if( m_aRenderPicture ) + XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0; + + bPenGC_ = bFontGC_ = bBrushGC_ = bMonoGC_ = bCopyGC_ = bInvertGC_ = bInvert50GC_ = bStippleGC_ = bTrackingGC_ = false; +} + +void X11SalGraphics::SetDrawable( Drawable aDrawable, int nScreen ) +{ + // shortcut if nothing changed + if( hDrawable_ == aDrawable ) + return; + + // free screen specific resources if needed + if( nScreen != m_nScreen ) + { + freeResources(); + m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap( nScreen ); + m_nScreen = nScreen; + } + + hDrawable_ = aDrawable; + SetXRenderFormat( NULL ); + if( m_aRenderPicture ) + { + XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ); + m_aRenderPicture = 0; + } + + if( hDrawable_ ) + { + nPenPixel_ = GetPixel( nPenColor_ ); + nTextPixel_ = GetPixel( nTextColor_ ); + nBrushPixel_ = GetPixel( nBrushColor_ ); + } +} + +void X11SalGraphics::Init( SalFrame *pFrame, Drawable aTarget, int nScreen ) +{ +#if 0 // TODO: use SetDrawable() instead + m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); + hDrawable_ = aTarget; + m_nScreen = nScreen; + SetXRenderFormat( NULL ); + if( m_aRenderPicture ) + XRenderPeer::GetInstance().FreePicture( m_aRenderPicture ), m_aRenderPicture = 0; + + nPenPixel_ = GetPixel( nPenColor_ ); + nTextPixel_ = GetPixel( nTextColor_ ); + nBrushPixel_ = GetPixel( nBrushColor_ ); +#else + m_pColormap = &GetX11SalData()->GetDisplay()->GetColormap(nScreen); + m_nScreen = nScreen; + SetDrawable( aTarget, nScreen ); +#endif + + bWindow_ = TRUE; + m_pFrame = pFrame; + m_pVDev = NULL; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::DeInit() +{ + SetDrawable( None, m_nScreen ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetClipRegion( GC pGC, XLIB_Region pXReg ) const +{ + Display *pDisplay = GetXDisplay(); + + int n = 0; + XLIB_Region Regions[3]; + + if( pClipRegion_ /* && !XEmptyRegion( pClipRegion_ ) */ ) + Regions[n++] = pClipRegion_; +// if( pPaintRegion_ /* && !XEmptyRegion( pPaintRegion_ ) */ ) +// Regions[n++] = pPaintRegion_; + + if( pXReg && !XEmptyRegion( pXReg ) ) + Regions[n++] = pXReg; + + if( 0 == n ) + XSetClipMask( pDisplay, pGC, None ); + else if( 1 == n ) + XSetRegion( pDisplay, pGC, Regions[0] ); + else + { + XLIB_Region pTmpRegion = XCreateRegion(); + XIntersectRegion( Regions[0], Regions[1], pTmpRegion ); +// if( 3 == n ) +// XIntersectRegion( Regions[2], pTmpRegion, pTmpRegion ); + XSetRegion( pDisplay, pGC, pTmpRegion ); + XDestroyRegion( pTmpRegion ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +GC X11SalGraphics::SelectPen() +{ + Display *pDisplay = GetXDisplay(); + + if( !pPenGC_ ) + { + XGCValues values; + values.subwindow_mode = ClipByChildren; + values.fill_rule = EvenOddRule; // Pict import/ Gradient + values.graphics_exposures = False; + + pPenGC_ = XCreateGC( pDisplay, hDrawable_, + GCSubwindowMode | GCFillRule | GCGraphicsExposures, + &values ); + } + + if( !bPenGC_ ) + { + if( nPenColor_ != SALCOLOR_NONE ) + XSetForeground( pDisplay, pPenGC_, nPenPixel_ ); + XSetFunction ( pDisplay, pPenGC_, bXORMode_ ? GXxor : GXcopy ); + SetClipRegion( pPenGC_ ); + bPenGC_ = TRUE; + } + + return pPenGC_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +GC X11SalGraphics::SelectBrush() +{ + Display *pDisplay = GetXDisplay(); + + DBG_ASSERT( nBrushColor_ != SALCOLOR_NONE, "Brush Transparent" ); + + if( !pBrushGC_ ) + { + XGCValues values; + // values.subwindow_mode = IncludeInferiors; + values.subwindow_mode = ClipByChildren; + values.fill_rule = EvenOddRule; // Pict import/ Gradient + values.graphics_exposures = False; + + pBrushGC_ = XCreateGC( pDisplay, hDrawable_, + GCSubwindowMode | GCFillRule | GCGraphicsExposures, + &values ); + } + + if( !bBrushGC_ ) + { + if( !bDitherBrush_ ) + { + XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); + XSetForeground( pDisplay, pBrushGC_, nBrushPixel_ ); + #if defined(_USE_PRINT_EXTENSION_) + XSetBackground( pDisplay, pBrushGC_, + WhitePixel(pDisplay, DefaultScreen(pDisplay)) ); + #else + if( bPrinter_ ) + XSetTile( pDisplay, pBrushGC_, None ); + #endif + } + else + { + // Bug in Sun Solaris 2.5.1, XFillPolygon doesn't allways reflect + // changes of the tile. PROPERTY_BUG_Tile doesn't fix this ! + if (GetDisplay()->GetProperties() & PROPERTY_BUG_FillPolygon_Tile) + XSetFillStyle ( pDisplay, pBrushGC_, FillSolid ); + + XSetFillStyle ( pDisplay, pBrushGC_, FillTiled ); + XSetTile ( pDisplay, pBrushGC_, hBrush_ ); + } + XSetFunction ( pDisplay, pBrushGC_, bXORMode_ ? GXxor : GXcopy ); + SetClipRegion( pBrushGC_ ); + + bBrushGC_ = TRUE; + } + + return pBrushGC_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +GC X11SalGraphics::GetTrackingGC() +{ + const char dash_list[2] = {2, 2}; + + if( !pTrackingGC_ ) + { + XGCValues values; + + values.graphics_exposures = False; + values.foreground = m_pColormap->GetBlackPixel() + ^ m_pColormap->GetWhitePixel(); + values.function = GXxor; + values.line_width = 1; + values.line_style = LineOnOffDash; + + pTrackingGC_ = XCreateGC( GetXDisplay(), GetDrawable(), + GCGraphicsExposures | GCForeground | GCFunction + | GCLineWidth | GCLineStyle, + &values ); + XSetDashes( GetXDisplay(), pTrackingGC_, 0, dash_list, 2 ); + } + + if( !bTrackingGC_ ) + { + SetClipRegion( pTrackingGC_ ); + bTrackingGC_ = TRUE; + } + + return pTrackingGC_; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::DrawLines( ULONG nPoints, + const SalPolyLine &rPoints, + GC pGC, + bool bClose + ) +{ + // errechne wie viele Linien XWindow auf einmal zeichnen kann + ULONG nMaxLines = (GetDisplay()->GetMaxRequestSize() - sizeof(xPolyPointReq)) + / sizeof(xPoint); + if( nMaxLines > nPoints ) nMaxLines = nPoints; + + // gebe alle Linien aus, die XWindows zeichnen kann. + ULONG n; + for( n = 0; nPoints - n > nMaxLines; n += nMaxLines - 1 ) + XDrawLines( GetXDisplay(), + GetDrawable(), + pGC, + &rPoints[n], + nMaxLines, + CoordModeOrigin ); + + if( n < nPoints ) + XDrawLines( GetXDisplay(), + GetDrawable(), + pGC, + &rPoints[n], + nPoints - n, + CoordModeOrigin ); + if( bClose ) + { + if( rPoints[nPoints-1].x != rPoints[0].x || rPoints[nPoints-1].y != rPoints[0].y ) + drawLine( rPoints[nPoints-1].x, rPoints[nPoints-1].y, rPoints[0].x, rPoints[0].y ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +// Dithern: Calculate a dither-pixmap and make a brush of it +#define P_DELTA 51 +#define DMAP( v, m ) ((v % P_DELTA) > m ? (v / P_DELTA) + 1 : (v / P_DELTA)) + +BOOL X11SalGraphics::GetDitherPixmap( SalColor nSalColor ) +{ + static const short nOrdDither8Bit[ 8 ][ 8 ] = + { + { 0, 38, 9, 48, 2, 40, 12, 50}, + {25, 12, 35, 22, 28, 15, 37, 24}, + { 6, 44, 3, 41, 8, 47, 5, 44}, + {32, 19, 28, 16, 34, 21, 31, 18}, + { 1, 40, 11, 49, 0, 39, 10, 48}, + {27, 14, 36, 24, 26, 13, 36, 23}, + { 8, 46, 4, 43, 7, 45, 4, 42}, + {33, 20, 30, 17, 32, 20, 29, 16} + }; + + // test for correct depth (8bit) + if( GetColormap().GetVisual().GetDepth() != 8 ) + return FALSE; + + char pBits[64]; + char *pBitsPtr = pBits; + + // Set the pallette-entries for the dithering tile + UINT8 nSalColorRed = SALCOLOR_RED ( nSalColor ); + UINT8 nSalColorGreen = SALCOLOR_GREEN ( nSalColor ); + UINT8 nSalColorBlue = SALCOLOR_BLUE ( nSalColor ); + + for( int nY = 0; nY < 8; nY++ ) + { + for( int nX = 0; nX < 8; nX++ ) + { + short nMagic = nOrdDither8Bit[nY][nX]; + UINT8 nR = P_DELTA * DMAP( nSalColorRed, nMagic ); + UINT8 nG = P_DELTA * DMAP( nSalColorGreen, nMagic ); + UINT8 nB = P_DELTA * DMAP( nSalColorBlue, nMagic ); + + *pBitsPtr++ = GetColormap().GetPixel( MAKE_SALCOLOR( nR, nG, nB ) ); + } + } + + // create the tile as ximage and an according pixmap -> caching + XImage *pImage = XCreateImage( GetXDisplay(), + GetColormap().GetXVisual(), + 8, + ZPixmap, + 0, // offset + pBits, // data + 8, 8, // width & height + 8, // bitmap_pad + 0 ); // (default) bytes_per_line + + if ( GetDisplay()->GetProperties() & PROPERTY_BUG_Tile ) + { + if (hBrush_) + XFreePixmap (GetXDisplay(), hBrush_); + hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); + } + else + if( !hBrush_ ) + hBrush_ = XCreatePixmap( GetXDisplay(), GetDrawable(), 8, 8, 8 ); + + // put the ximage to the pixmap + XPutImage( GetXDisplay(), + hBrush_, + GetDisplay()->GetCopyGC( m_nScreen ), + pImage, + 0, 0, // Source + 0, 0, // Destination + 8, 8 ); // width & height + + // destroy image-frame but not palette-data + pImage->data = NULL; + XDestroyImage( pImage ); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::GetResolution( sal_Int32 &rDPIX, sal_Int32 &rDPIY ) // const +{ + const SalDisplay *pDisplay = GetDisplay(); + + rDPIX = pDisplay->GetResolution().A(); + rDPIY = pDisplay->GetResolution().B(); + if( !pDisplay->GetExactResolution() && rDPIY < 96 ) + { + rDPIX = Divide( rDPIX * 96, rDPIY ); + rDPIY = 96; + } + else if ( rDPIY > 200 ) + { + rDPIX = Divide( rDPIX * 200, rDPIY ); + rDPIY = 200; + } + + // #i12705# equalize x- and y-resolution if they are close enough + if( rDPIX != rDPIY ) + { + // different x- and y- resolutions are usually artifacts of + // a wrongly calculated screen size. + //if( (13*rDPIX >= 10*rDPIY) && (13*rDPIY >= 10*rDPIX) ) //+-30% + { +#ifdef DEBUG + printf("Forcing Resolution from %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 " to %" SAL_PRIdINT32 "x%" SAL_PRIdINT32 "\n", + rDPIX,rDPIY,rDPIY,rDPIY); +#endif + rDPIX = rDPIY; // y-resolution is more trustworthy + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +USHORT X11SalGraphics::GetBitCount() // const +{ + return GetVisual().GetDepth(); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long X11SalGraphics::GetGraphicsWidth() const +{ + if( m_pFrame ) + return m_pFrame->maGeometry.nWidth; + else if( m_pVDev ) + return m_pVDev->GetWidth(); + else + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +long X11SalGraphics::GetGraphicsHeight() const +{ + if( m_pFrame ) + return m_pFrame->maGeometry.nHeight; + else if( m_pVDev ) + return m_pVDev->GetHeight(); + else + return 0; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::ResetClipRegion() +{ + if( pClipRegion_ ) + { + bPenGC_ = FALSE; + bFontGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + + XDestroyRegion( pClipRegion_ ); + pClipRegion_ = NULL; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::BeginSetClipRegion( ULONG ) +{ + if( pClipRegion_ ) + XDestroyRegion( pClipRegion_ ); + pClipRegion_ = XCreateRegion(); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +BOOL X11SalGraphics::unionClipRegion( long nX, long nY, long nDX, long nDY ) +{ + if (!nDX || !nDY) + return TRUE; + + XRectangle aRect; + aRect.x = (short)nX; + aRect.y = (short)nY; + aRect.width = (unsigned short)nDX; + aRect.height = (unsigned short)nDY; + + XUnionRectWithRegion( &aRect, pClipRegion_, pClipRegion_ ); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +bool X11SalGraphics::unionClipRegion( const ::basegfx::B2DPolyPolygon& ) +{ + // TODO: implement and advertise OutDevSupport_B2DClip support + return false; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::EndSetClipRegion() +{ + bPenGC_ = FALSE; + bFontGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + + if( XEmptyRegion( pClipRegion_ ) ) + { + XDestroyRegion( pClipRegion_ ); + pClipRegion_= NULL; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetLineColor() +{ + if( nPenColor_ != SALCOLOR_NONE ) + { + nPenColor_ = SALCOLOR_NONE; + bPenGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetLineColor( SalColor nSalColor ) +{ + if( nPenColor_ != nSalColor ) + { + nPenColor_ = nSalColor; + nPenPixel_ = GetPixel( nSalColor ); + bPenGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetFillColor() +{ + if( nBrushColor_ != SALCOLOR_NONE ) + { + bDitherBrush_ = FALSE; + nBrushColor_ = SALCOLOR_NONE; + bBrushGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetFillColor( SalColor nSalColor ) +{ + if( nBrushColor_ != nSalColor ) + { + bDitherBrush_ = FALSE; + nBrushColor_ = nSalColor; + nBrushPixel_ = GetPixel( nSalColor ); + if( TrueColor != GetColormap().GetVisual().GetClass() + && GetColormap().GetColor( nBrushPixel_ ) != nBrushColor_ + && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x00 ) // black + && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0x80 ) // blue + && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x00 ) // green + && nSalColor != MAKE_SALCOLOR( 0x00, 0x80, 0x80 ) // cyan + && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x00 ) // red + && nSalColor != MAKE_SALCOLOR( 0x80, 0x00, 0x80 ) // magenta + && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x00 ) // brown + && nSalColor != MAKE_SALCOLOR( 0x80, 0x80, 0x80 ) // gray + && nSalColor != MAKE_SALCOLOR( 0xC0, 0xC0, 0xC0 ) // light gray + && nSalColor != MAKE_SALCOLOR( 0x00, 0x00, 0xFF ) // light blue + && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0x00 ) // light green + && nSalColor != MAKE_SALCOLOR( 0x00, 0xFF, 0xFF ) // light cyan + && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0x00 ) // light red + && nSalColor != MAKE_SALCOLOR( 0xFF, 0x00, 0xFF ) // light magenta + && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0x00 ) // light brown + && nSalColor != MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ) + bDitherBrush_ = GetDitherPixmap(nSalColor); + bBrushGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetROPLineColor( SalROPColor nROPColor ) +{ + switch( nROPColor ) + { + case SAL_ROP_0 : // 0 + nPenPixel_ = (Pixel)0; + break; + case SAL_ROP_1 : // 1 + nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + case SAL_ROP_INVERT : // 2 + nPenPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + } + nPenColor_ = GetColormap().GetColor( nPenPixel_ ); + bPenGC_ = FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetROPFillColor( SalROPColor nROPColor ) +{ + switch( nROPColor ) + { + case SAL_ROP_0 : // 0 + nBrushPixel_ = (Pixel)0; + break; + case SAL_ROP_1 : // 1 + nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + case SAL_ROP_INVERT : // 2 + nBrushPixel_ = (Pixel)(1 << GetVisual().GetDepth()) - 1; + break; + } + bDitherBrush_ = FALSE; + nBrushColor_ = GetColormap().GetColor( nBrushPixel_ ); + bBrushGC_ = FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::SetXORMode( bool bSet, bool ) +{ + if( !bXORMode_ == bSet ) + { + bXORMode_ = bSet; + bPenGC_ = FALSE; + bBrushGC_ = FALSE; + bMonoGC_ = FALSE; + bCopyGC_ = FALSE; + bInvertGC_ = FALSE; + bInvert50GC_ = FALSE; + bStippleGC_ = FALSE; + bTrackingGC_ = FALSE; + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPixel( long nX, long nY ) +{ + if( nPenColor_ != SALCOLOR_NONE ) + XDrawPoint( GetXDisplay(), GetDrawable(), SelectPen(), nX, nY ); +} + +void X11SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) +{ + if( nSalColor != SALCOLOR_NONE ) + { + Display *pDisplay = GetXDisplay(); + + if( (nPenColor_ == SALCOLOR_NONE) && !bPenGC_ ) + { + SetLineColor( nSalColor ); + XDrawPoint( pDisplay, GetDrawable(), SelectPen(), nX, nY ); + nPenColor_ = SALCOLOR_NONE; + bPenGC_ = False; + } + else + { + GC pGC = SelectPen(); + + if( nSalColor != nPenColor_ ) + XSetForeground( pDisplay, pGC, GetPixel( nSalColor ) ); + + XDrawPoint( pDisplay, GetDrawable(), pGC, nX, nY ); + + if( nSalColor != nPenColor_ ) + XSetForeground( pDisplay, pGC, nPenPixel_ ); + } + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) +{ + if( nPenColor_ != SALCOLOR_NONE ) + { + if ( GetDisplay()->GetProperties() & PROPERTY_BUG_DrawLine ) + { + GC aGC = SelectPen(); + XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX1, (int)nY1); + XDrawPoint (GetXDisplay(), GetDrawable(), aGC, (int)nX2, (int)nY2); + XDrawLine (GetXDisplay(), GetDrawable(), aGC, nX1, nY1, nX2, nY2 ); + } + else + XDrawLine( GetXDisplay(), GetDrawable(),SelectPen(), + nX1, nY1, nX2, nY2 ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawRect( long nX, long nY, long nDX, long nDY ) +{ + if( nBrushColor_ != SALCOLOR_NONE ) + { + XFillRectangle( GetXDisplay(), + GetDrawable(), + SelectBrush(), + nX, nY, nDX, nDY ); + } + // Beschreibung DrawRect verkehrt, deshalb -1 + if( nPenColor_ != SALCOLOR_NONE ) + XDrawRectangle( GetXDisplay(), + GetDrawable(), + SelectPen(), + nX, nY, nDX-1, nDY-1 ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry ) +{ + drawPolyLine( nPoints, pPtAry, false ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolyLine( ULONG nPoints, const SalPoint *pPtAry, bool bClose ) +{ + if( nPenColor_ != 0xFFFFFFFF ) + { + SalPolyLine Points( nPoints, pPtAry ); + + DrawLines( nPoints, Points, SelectPen(), bClose ); + } +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolygon( ULONG nPoints, const SalPoint* pPtAry ) +{ + if( nPoints == 0 ) + return; + + if( nPoints < 3 ) + { + if( !bXORMode_ ) + { + if( 1 == nPoints ) + drawPixel( pPtAry[0].mnX, pPtAry[0].mnY ); + else + drawLine( pPtAry[0].mnX, pPtAry[0].mnY, + pPtAry[1].mnX, pPtAry[1].mnY ); + } + return; + } + + SalPolyLine Points( nPoints, pPtAry ); + + nPoints++; + + /* WORKAROUND: some Xservers (Xorg, VIA chipset in this case) + * do not draw the visible part of a polygon + * if it overlaps to the left of screen 0,y. + * This happens to be the case in the gradient drawn in the + * menubar background. workaround for the special case of + * of a rectangle overlapping to the left. + */ + if( nPoints == 5 && + Points[ 0 ].x == Points[ 1 ].x && + Points[ 1 ].y == Points[ 2 ].y && + Points[ 2 ].x == Points[ 3 ].x && + Points[ 0 ].x == Points[ 4 ].x && Points[ 0 ].y == Points[ 4 ].y + ) + { + bool bLeft = false; + bool bRight = false; + for(unsigned int i = 0; i < nPoints; i++ ) + { + if( Points[i].x < 0 ) + bLeft = true; + else + bRight= true; + } + if( bLeft && ! bRight ) + return; + if( bLeft && bRight ) + { + for( unsigned int i = 0; i < nPoints; i++ ) + if( Points[i].x < 0 ) + Points[i].x = 0; + } + } + + if( nBrushColor_ != SALCOLOR_NONE ) + XFillPolygon( GetXDisplay(), + GetDrawable(), + SelectBrush(), + &Points[0], nPoints, + Complex, CoordModeOrigin ); + + if( nPenColor_ != 0xFFFFFFFF ) + DrawLines( nPoints, Points, SelectPen(), true ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +void X11SalGraphics::drawPolyPolygon( sal_uInt32 nPoly, + const sal_uInt32 *pPoints, + PCONSTSALPOINT *pPtAry ) +{ + if( nBrushColor_ != SALCOLOR_NONE ) + { + ULONG i, n; + XLIB_Region pXRegA = NULL; + + for( i = 0; i < nPoly; i++ ) { + n = pPoints[i]; + SalPolyLine Points( n, pPtAry[i] ); + if( n > 2 ) + { + XLIB_Region pXRegB = XPolygonRegion( &Points[0], n+1, WindingRule ); + if( !pXRegA ) + pXRegA = pXRegB; + else + { + XXorRegion( pXRegA, pXRegB, pXRegA ); + XDestroyRegion( pXRegB ); + } + } + } + + if( pXRegA ) + { + XRectangle aXRect; + XClipBox( pXRegA, &aXRect ); + + GC pGC = SelectBrush(); + SetClipRegion( pGC, pXRegA ); // ??? doppelt + XDestroyRegion( pXRegA ); + bBrushGC_ = FALSE; + + XFillRectangle( GetXDisplay(), + GetDrawable(), + pGC, + aXRect.x, aXRect.y, aXRect.width, aXRect.height ); + } + } + + if( nPenColor_ != SALCOLOR_NONE ) + for( ULONG i = 0; i < nPoly; i++ ) + drawPolyLine( pPoints[i], pPtAry[i], true ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sal_Bool X11SalGraphics::drawPolyLineBezier( ULONG, const SalPoint*, const BYTE* ) +{ + return sal_False; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sal_Bool X11SalGraphics::drawPolygonBezier( ULONG, const SalPoint*, const BYTE* ) +{ + return sal_False; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +sal_Bool X11SalGraphics::drawPolyPolygonBezier( sal_uInt32, const sal_uInt32*, + const SalPoint* const*, const BYTE* const* ) +{ + return sal_False; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +void X11SalGraphics::invert( ULONG nPoints, + const SalPoint* pPtAry, + SalInvert nFlags ) +{ + SalPolyLine Points ( nPoints, pPtAry ); + + GC pGC; + if( SAL_INVERT_50 & nFlags ) + pGC = GetInvert50GC(); + else + if ( SAL_INVERT_TRACKFRAME & nFlags ) + pGC = GetTrackingGC(); + else + pGC = GetInvertGC(); + + if( SAL_INVERT_TRACKFRAME & nFlags ) + DrawLines ( nPoints, Points, pGC, true ); + else + XFillPolygon( GetXDisplay(), + GetDrawable(), + pGC, + &Points[0], nPoints, + Complex, CoordModeOrigin ); +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +BOOL X11SalGraphics::drawEPS( long,long,long,long,void*,ULONG ) +{ + return FALSE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +XID X11SalGraphics::GetXRenderPicture() +{ + if( !m_aRenderPicture ) + { + // check xrender support for matching visual + // find a XRenderPictFormat compatible with the Drawable + XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + XRenderPictFormat* pVisualFormat = static_cast<XRenderPictFormat*>(GetXRenderFormat()); + if( !pVisualFormat ) + { + Visual* pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); + pVisualFormat = rRenderPeer.FindVisualFormat( pVisual ); + if( !pVisualFormat ) + return 0; + // cache the XRenderPictFormat + SetXRenderFormat( static_cast<void*>(pVisualFormat) ); + } + + // get the matching xrender target for drawable + m_aRenderPicture = rRenderPeer.CreatePicture( hDrawable_, pVisualFormat, 0, NULL ); + } + +#if 0 + // setup clipping so the callers don't have to do it themselves + // TODO: avoid clipping if already set correctly + if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) + rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ ); +#endif + + return m_aRenderPicture; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +SystemGraphicsData X11SalGraphics::GetGraphicsData() const +{ + SystemGraphicsData aRes; + + aRes.nSize = sizeof(aRes); + aRes.pDisplay = GetXDisplay(); + aRes.hDrawable = hDrawable_; + aRes.pVisual = GetDisplay()->GetVisual( m_nScreen ).GetVisual(); + aRes.nScreen = m_nScreen; + aRes.nDepth = GetDisplay()->GetVisual( m_nScreen ).GetDepth(); + aRes.aColormap = GetDisplay()->GetColormap( m_nScreen ).GetXColormap(); + aRes.pRenderFormat = m_pRenderFormat; + return aRes; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +// B2DPolygon support methods + +namespace { // anonymous namespace to prevent export +// the methods and structures here are used by the +// B2DPolyPolygon->RenderTrapezoid conversion algorithm + +// compare two line segments +// assumption: both segments point downward +// assumption: they must have at least some y-overlap +// assumption: rA.p1.y <= rB.p1.y +bool IsLeftOf( const XLineFixed& rA, const XLineFixed& rB ) +{ + bool bAbove = (rA.p1.y <= rB.p1.y); + const XLineFixed& rU = bAbove ? rA : rB; + const XLineFixed& rL = bAbove ? rB : rA; + + const XFixed aXDiff = rU.p2.x - rU.p1.x; + const XFixed aYDiff = rU.p2.y - rU.p1.y; + + if( (rU.p1.y != rL.p1.y) || (rU.p1.x != rL.p1.x) ) + { + const sal_Int64 n1 = (sal_Int64)aXDiff * (rL.p1.y - rU.p1.y); + const sal_Int64 n2 = (sal_Int64)aYDiff * (rL.p1.x - rU.p1.x); + if( n1 != n2 ) + return ((n1 < n2) == bAbove); + } + + if( (rU.p2.y != rL.p2.y) || (rU.p2.x != rL.p2.x) ) + { + const sal_Int64 n3 = (sal_Int64)aXDiff * (rL.p2.y - rU.p1.y); + const sal_Int64 n4 = (sal_Int64)aYDiff * (rL.p2.x - rU.p1.x); + if( n3 != n4 ) + return ((n3 < n4) == bAbove); + } + + // both segments overlap + return false; +} + +struct HalfTrapezoid +{ + // assumptions: + // maLine.p1.y <= mnY < maLine.p2.y + XLineFixed maLine; + XFixed mnY; +}; + +struct HalfTrapCompare +{ + bool operator()( const HalfTrapezoid& rA, const HalfTrapezoid& rB ) const + { + bool bIsTopLeft = false; + if( rA.mnY != rB.mnY ) // sort top-first if possible + bIsTopLeft = (rA.mnY < rB.mnY); + else // else sort left-first + bIsTopLeft = IsLeftOf( rA.maLine, rB.maLine ); + // adjust to priority_queue sorting convention + return !bIsTopLeft; + } +}; + +typedef std::priority_queue< HalfTrapezoid, std::vector<HalfTrapezoid>, HalfTrapCompare > HTQueueBase; +// we need a priority queue with a reserve() to prevent countless reallocations +class HTQueue +: public HTQueueBase +{ +public: + void reserve( size_t n ) { c.reserve( n ); } + int capacity() { return c.capacity(); } +}; + +typedef std::vector<XTrapezoid> TrapezoidVector; + +class TrapezoidXCompare +{ + const TrapezoidVector& mrVector; +public: + TrapezoidXCompare( const TrapezoidVector& rVector ) + : mrVector( rVector ) {} + bool operator()( int nA, int nB ) const + { return IsLeftOf( mrVector[nA].left, mrVector[nB].left ); } +}; + +typedef std::multiset< int, TrapezoidXCompare > ActiveTrapSet; + +class TrapezoidYCompare +{ + const TrapezoidVector& mrVector; +public: + TrapezoidYCompare( const TrapezoidVector& rVector ) + : mrVector( rVector ) {} + bool operator()( int nA, int nB ) const + { return (mrVector[nA].bottom < mrVector[nB].bottom); } +}; + +typedef std::multiset< int, TrapezoidYCompare > VerticalTrapSet; +} // end of anonymous namespace + +// draw a poly-polygon +bool X11SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly, double fTransparency) +{ + // nothing to do for empty polypolygons + const int nPolygonCount = rPolyPoly.count(); + if( nPolygonCount <= 0 ) + return TRUE; + + // nothing to do if everything is transparent + if( (nBrushColor_ == SALCOLOR_NONE) + && (nPenColor_ == SALCOLOR_NONE) ) + return TRUE; + + // cannot handle pencolor!=brushcolor yet + if( (nPenColor_ != SALCOLOR_NONE) + && (nPenColor_ != nBrushColor_) ) + return FALSE; + + // TODO: remove the env-variable when no longer needed + static const char* pRenderEnv = getenv( "SAL_DISABLE_RENDER_POLY" ); + if( pRenderEnv ) + return FALSE; + + // check xrender support for trapezoids + XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + if( !rRenderPeer.AreTrapezoidsSupported() ) + return FALSE; + Picture aDstPic = GetXRenderPicture(); + // check xrender support for this drawable + if( !aDstPic ) + return FALSE; + + // don't bother with polygons outside of visible area + const basegfx::B2DRange aViewRange( 0, 0, GetGraphicsWidth(), GetGraphicsHeight() ); + const basegfx::B2DRange aPolyRange = basegfx::tools::getRange( rPolyPoly ); + const bool bNeedViewClip = !aPolyRange.isInside( aViewRange ); + if( !aPolyRange.overlaps( aViewRange ) ) + return true; + + // convert the polypolygon to trapezoids + + // first convert the B2DPolyPolygon to HalfTrapezoids + // #i100922# try to prevent priority-queue reallocations by reservering enough + int nHTQueueReserve = 0; + for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx ) + { + const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx ); + const int nPointCount = aOuterPolygon.count(); + nHTQueueReserve += aOuterPolygon.areControlPointsUsed() ? 8 * nPointCount : nPointCount; + } + nHTQueueReserve = ((4*nHTQueueReserve) | 0x1FFF) + 1; + HTQueue aHTQueue; + aHTQueue.reserve( nHTQueueReserve ); + for( int nOuterPolyIdx = 0; nOuterPolyIdx < nPolygonCount; ++nOuterPolyIdx ) + { + const ::basegfx::B2DPolygon aOuterPolygon = rPolyPoly.getB2DPolygon( nOuterPolyIdx ); + + // render-trapezoids should be inside the view => clip polygon against view range + basegfx::B2DPolyPolygon aClippedPolygon( aOuterPolygon ); + if( bNeedViewClip ) + { + aClippedPolygon = basegfx::tools::clipPolygonOnRange( aOuterPolygon, aViewRange, true, false ); + DBG_ASSERT( aClippedPolygon.count(), "polygon confirmed to overlap with view should not get here" ); + if( !aClippedPolygon.count() ) + continue; + } + + // render-trapezoids have linear edges => get rid of bezier segments + if( aClippedPolygon.areControlPointsUsed() ) + aClippedPolygon = ::basegfx::tools::adaptiveSubdivideByDistance( aClippedPolygon, 0.125 ); + + // test and remove self intersections + // TODO: make code intersection save, then remove this test + basegfx::B2DPolyPolygon aInnerPolyPoly(basegfx::tools::solveCrossovers( aClippedPolygon)); + const int nInnerPolyCount = aInnerPolyPoly.count(); + for( int nInnerPolyIdx = 0; nInnerPolyIdx < nInnerPolyCount; ++nInnerPolyIdx ) + { + ::basegfx::B2DPolygon aInnerPolygon = aInnerPolyPoly.getB2DPolygon( nInnerPolyIdx ); + const int nPointCount = aInnerPolygon.count(); + if( !nPointCount ) + continue; + + aHTQueue.reserve( aHTQueue.size() + 8 * nPointCount ); + + // convert polygon point pairs to HalfTrapezoids + // connect the polygon point with the first one if needed + XPointFixed aOldXPF = { 0, 0 }; + XPointFixed aNewXPF; + for( int nPointIdx = 0; nPointIdx <= nPointCount; ++nPointIdx, aOldXPF = aNewXPF ) + { + const int k = (nPointIdx < nPointCount) ? nPointIdx : 0; + const ::basegfx::B2DPoint& aPoint = aInnerPolygon.getB2DPoint( k ); + + // convert the B2DPoint into XRENDER units + if(getAntiAliasB2DDraw()) + { + aNewXPF.x = XDoubleToFixed( aPoint.getX() ); + aNewXPF.y = XDoubleToFixed( aPoint.getY() ); + } + else + { + aNewXPF.x = XDoubleToFixed( basegfx::fround( aPoint.getX() ) ); + aNewXPF.y = XDoubleToFixed( basegfx::fround( aPoint.getY() ) ); + } + + // check if enough data is available for a new HalfTrapezoid + if( nPointIdx == 0 ) + continue; + // ignore vertical segments + if( aNewXPF.y == aOldXPF.y ) + continue; + + // construct HalfTrapezoid as topdown segment + HalfTrapezoid aHT; + if( aNewXPF.y < aOldXPF.y ) + { + aHT.maLine.p1 = aNewXPF; + aHT.maLine.p2 = aOldXPF; + } + else + { + aHT.maLine.p2 = aNewXPF; + aHT.maLine.p1 = aOldXPF; + } + + aHT.mnY = aHT.maLine.p1.y; + +#if 0 // ignore clipped HalfTrapezoids + if( aHT.mnY < 0 ) + aHT.mnY = 0; + else if( aHT.mnY > 10000 ) + continue; +#endif + + // queue up the HalfTrapezoid + aHTQueue.push( aHT ); + } + } + } + + if( aHTQueue.empty() ) + return TRUE; + + // then convert the HalfTrapezoids into full Trapezoids + TrapezoidVector aTrapVector; + aTrapVector.reserve( aHTQueue.size() * 2 ); // just a guess + + TrapezoidXCompare aTrapXCompare( aTrapVector ); + ActiveTrapSet aActiveTraps( aTrapXCompare ); + + TrapezoidYCompare aTrapYCompare( aTrapVector ); + VerticalTrapSet aVerticalTraps( aTrapYCompare ); + + while( !aHTQueue.empty() ) + { + XTrapezoid aTrapezoid; + + // convert a HalfTrapezoid pair + const HalfTrapezoid& rLeft = aHTQueue.top(); + aTrapezoid.top = rLeft.mnY; + aTrapezoid.bottom = rLeft.maLine.p2.y; + aTrapezoid.left = rLeft.maLine; + +#if 0 + // ignore empty trapezoids + if( aTrapezoid.bottom <= aTrapezoid.top ) + continue; +#endif + + aHTQueue.pop(); + if( aHTQueue.empty() ) // TODO: assert + break; + const HalfTrapezoid& rRight = aHTQueue.top(); + aTrapezoid.right = rRight.maLine; + aHTQueue.pop(); + + aTrapezoid.bottom = aTrapezoid.left.p2.y; + if( aTrapezoid.bottom > aTrapezoid.right.p2.y ) + aTrapezoid.bottom = aTrapezoid.right.p2.y; + + // keep the full Trapezoid candidate + aTrapVector.push_back( aTrapezoid ); + + // unless it splits an older trapezoid + bool bSplit = false; + for(;;) + { + // check if the new trapezoid overlaps with an old trapezoid + ActiveTrapSet::iterator aActiveTrapsIt + = aActiveTraps.upper_bound( aTrapVector.size()-1 ); + if( aActiveTrapsIt == aActiveTraps.begin() ) + break; + --aActiveTrapsIt; + + XTrapezoid& rLeftTrap = aTrapVector[ *aActiveTrapsIt ]; + + // in the ActiveTrapSet there are still trapezoids where + // a vertical overlap with new trapezoids is no longer possible + // they could have been removed in the verticaltraps loop below + // but this would have been expensive and is not needed as we can + // simply ignore them now and remove them from the ActiveTrapSet + // so they won't bother us in the future + if( rLeftTrap.bottom <= aTrapezoid.top ) + { + aActiveTraps.erase( aActiveTrapsIt ); + continue; + } + + // check if there is horizontal overlap + // aTrapezoid.left==rLeftTrap.right is allowed though + if( !IsLeftOf( aTrapezoid.left, rLeftTrap.right ) ) + break; + + // split the old trapezoid and keep its upper part + // find the old trapezoids entry in the VerticalTrapSet and remove it + typedef std::pair<VerticalTrapSet::iterator, VerticalTrapSet::iterator> VTSPair; + VTSPair aVTSPair = aVerticalTraps.equal_range( *aActiveTrapsIt ); + VerticalTrapSet::iterator aVTSit = aVTSPair.first; + for(; (aVTSit != aVTSPair.second) && (*aVTSit != *aActiveTrapsIt); ++aVTSit ) ; + if( aVTSit != aVTSPair.second ) + aVerticalTraps.erase( aVTSit ); + // then update the old trapezoid's bottom + rLeftTrap.bottom = aTrapezoid.top; + // enter the updated old trapzoid in VerticalTrapSet + aVerticalTraps.insert( aVerticalTraps.begin(), *aActiveTrapsIt ); + // the old trapezoid is no longer active + aActiveTraps.erase( aActiveTrapsIt ); + + // the trapezoid causing the split has become obsolete + // so its both sides have to be re-queued + HalfTrapezoid aHT; + aHT.mnY = aTrapezoid.top; + aHT.maLine = aTrapezoid.left; + aHTQueue.push( aHT ); + aHT.maLine = aTrapezoid.right; + aHTQueue.push( aHT ); + + bSplit = true; + break; + } + + // keep or forget the resulting full Trapezoid + if( bSplit ) + aTrapVector.pop_back(); + else + { + aActiveTraps.insert( aTrapVector.size()-1 ); + aVerticalTraps.insert( aTrapVector.size()-1 ); + } + + // mark trapezoids that can no longer be split as inactive + // and recycle their sides which were not fully resolved + static const XFixed nMaxTop = +0x7FFFFFFF; + XFixed nNewTop = aHTQueue.empty() ? nMaxTop : aHTQueue.top().mnY; + while( !aVerticalTraps.empty() ) + { + const XTrapezoid& rOldTrap = aTrapVector[ *aVerticalTraps.begin() ]; + if( nNewTop < rOldTrap.bottom ) + break; + // the reference Trapezoid can no longer be split + aVerticalTraps.erase( aVerticalTraps.begin() ); + + // recycle its sides that were not fully resolved + HalfTrapezoid aHT; + aHT.mnY = rOldTrap.bottom; + if( rOldTrap.left.p2.y > rOldTrap.bottom ) + { + aHT.maLine = rOldTrap.left; + aHTQueue.push( aHT ); + } + if( rOldTrap.right.p2.y > rOldTrap.bottom ) + { + aHT.maLine = rOldTrap.right; + aHTQueue.push( aHT ); + } + } + } + + // create xrender Picture for polygon foreground + SalDisplay::RenderEntry& rEntry = GetDisplay()->GetRenderEntries( m_nScreen )[ 32 ]; + if( !rEntry.m_aPicture ) + { + Display* pXDisplay = GetXDisplay(); + + rEntry.m_aPixmap = ::XCreatePixmap( pXDisplay, hDrawable_, 1, 1, 32 ); + XRenderPictureAttributes aAttr; + aAttr.repeat = true; + + XRenderPictFormat* pXRPF = rRenderPeer.FindStandardFormat( PictStandardARGB32 ); + rEntry.m_aPicture = rRenderPeer.CreatePicture( rEntry.m_aPixmap, pXRPF, CPRepeat, &aAttr ); + } + + // set polygon foreground color and opacity + XRenderColor aRenderColor = GetXRenderColor( nBrushColor_ , fTransparency ); + rRenderPeer.FillRectangle( PictOpSrc, rEntry.m_aPicture, &aRenderColor, 0, 0, 1, 1 ); + + // set clipping + // TODO: move into GetXRenderPicture? + if( pClipRegion_ && !XEmptyRegion( pClipRegion_ ) ) + rRenderPeer.SetPictureClipRegion( aDstPic, pClipRegion_ ); + + // render the trapezoids + const XRenderPictFormat* pMaskFormat = rRenderPeer.GetStandardFormatA8(); + rRenderPeer.CompositeTrapezoids( PictOpOver, + rEntry.m_aPicture, aDstPic, pMaskFormat, 0, 0, &aTrapVector[0], aTrapVector.size() ); + + return TRUE; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +bool X11SalGraphics::drawPolyLine(const ::basegfx::B2DPolygon& rPolygon, const ::basegfx::B2DVector& rLineWidth, basegfx::B2DLineJoin eLineJoin) +{ + // #i101491# + if(rPolygon.count() > 1000) + { + // the used basegfx::tools::createAreaGeometry is simply too + // expensive with very big polygons; fallback to caller (who + // should use ImplLineConverter normally) + return false; + } + const XRenderPeer& rRenderPeer = XRenderPeer::GetInstance(); + if( !rRenderPeer.AreTrapezoidsSupported() ) + return false; + + // get the area polygon for the line polygon + basegfx::B2DPolygon aPolygon = rPolygon; + if( (rLineWidth.getX() != rLineWidth.getY()) + && !basegfx::fTools::equalZero( rLineWidth.getY() ) ) + { + // prepare for createAreaGeometry() with anisotropic linewidth + basegfx::B2DHomMatrix aAnisoMatrix; + aAnisoMatrix.scale( 1.0, rLineWidth.getX() / rLineWidth.getY() ); + aPolygon.transform( aAnisoMatrix ); + } + + // AW: reSegment no longer needed; new createAreaGeometry will remove exteme positions + // and create bezier polygons + //if( aPolygon.areControlPointsUsed() ) + // aPolygon = basegfx::tools::reSegmentPolygonEdges( aPolygon, 8, true, false ); + //const basegfx::B2DPolyPolygon aAreaPolyPoly = basegfx::tools::createAreaGeometryForSimplePolygon( + // aPolygon, 0.5*rLineWidth.getX(), eLineJoin ); + const basegfx::B2DPolyPolygon aAreaPolyPoly(basegfx::tools::createAreaGeometry(aPolygon, 0.5*rLineWidth.getX(), eLineJoin)); + + if( (rLineWidth.getX() != rLineWidth.getY()) + && !basegfx::fTools::equalZero( rLineWidth.getX() ) ) + { + // postprocess createAreaGeometry() for anisotropic linewidth + basegfx::B2DHomMatrix aAnisoMatrix; + aAnisoMatrix.scale( 1.0, rLineWidth.getY() / rLineWidth.getX() ); + aPolygon.transform( aAnisoMatrix ); + } + + // temporarily adjust brush color to pen color + // since the line is drawn as an area-polygon + const SalColor aKeepBrushColor = nBrushColor_; + nBrushColor_ = nPenColor_; + + // draw each area polypolygon component individually + // to emulate the polypolygon winding rule "non-zero" + bool bDrawOk = true; + const int nPolyCount = aAreaPolyPoly.count(); + for( int nPolyIdx = 0; nPolyIdx < nPolyCount; ++nPolyIdx ) + { + const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( nPolyIdx ) ); + bDrawOk = drawPolyPolygon( aOnePoly, 0.0); + if( !bDrawOk ) + break; + } + + // restore the original brush GC + nBrushColor_ = aKeepBrushColor; + return bDrawOk; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/vcl/unx/source/gdi/salgdi3.cxx b/vcl/unx/source/gdi/salgdi3.cxx index d1a60cda4097..0ee0e0bb20c8 100644 --- a/vcl/unx/source/gdi/salgdi3.cxx +++ b/vcl/unx/source/gdi/salgdi3.cxx @@ -82,6 +82,11 @@ #include <hash_set> +#ifdef ENABLE_GRAPHITE +#include <vcl/graphite_layout.hxx> +#include <vcl/graphite_serverfont.hxx> +#endif + struct cairo_surface_t; struct cairo_t; struct cairo_font_face_t; @@ -1681,11 +1686,29 @@ BOOL X11SalGraphics::GetGlyphOutline( long nGlyphIndex, SalLayout* X11SalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) { - GenericSalLayout* pLayout = NULL; + SalLayout* pLayout = NULL; if( mpServerFont[ nFallbackLevel ] && !(rArgs.mnFlags & SAL_LAYOUT_DISABLE_GLYPH_PROCESSING) ) - pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] ); + { +#ifdef ENABLE_GRAPHITE + // Is this a Graphite font? + if (!bDisableGraphite_ && + GraphiteFontAdaptor::IsGraphiteEnabledFont(*mpServerFont[nFallbackLevel])) + { + sal_Int32 xdpi, ydpi; + + xdpi = GetDisplay()->GetResolution().A(); + ydpi = GetDisplay()->GetResolution().B(); + + GraphiteFontAdaptor * pGrfont = new GraphiteFontAdaptor( *mpServerFont[nFallbackLevel], xdpi, ydpi); + if (!pGrfont) return NULL; + pLayout = new GraphiteServerFontLayout(pGrfont); + } + else +#endif + pLayout = new ServerFontLayout( *mpServerFont[ nFallbackLevel ] ); + } else if( mXFont[ nFallbackLevel ] ) pLayout = new X11FontLayout( *mXFont[ nFallbackLevel ] ); else diff --git a/vcl/unx/source/gdi/salprnpsp.cxx b/vcl/unx/source/gdi/salprnpsp.cxx index 5f8c76fdb16f..2cf4e3baedd3 100644 --- a/vcl/unx/source/gdi/salprnpsp.cxx +++ b/vcl/unx/source/gdi/salprnpsp.cxx @@ -126,37 +126,6 @@ inline int PtTo10Mu( int nPoints ) { return (int)((((double)nPoints)*35.27777778 inline int TenMuToPt( int nUnits ) { return (int)((((double)nUnits)/35.27777778)+0.5); } -static struct -{ - int width; - int height; - const char* name; - int namelength; - Paper paper; -} aPaperTab[] = -{ - { 29700, 42000, "A3", 2, PAPER_A3 }, - { 21000, 29700, "A4", 2, PAPER_A4 }, - { 14800, 21000, "A5", 2, PAPER_A5 }, - { 25000, 35300, "B4", 2, PAPER_B4 }, - { 17600, 25000, "B5", 2, PAPER_B5 }, - { 21600, 27900, "Letter", 6, PAPER_LETTER }, - { 21600, 35600, "Legal", 5, PAPER_LEGAL }, - { 27900, 43100, "Tabloid", 7, PAPER_TABLOID }, - { 0, 0, "USER", 4, PAPER_USER } -}; - -static Paper getPaperType( const String& rPaperName ) -{ - ByteString aPaper( rPaperName, RTL_TEXTENCODING_ISO_8859_1 ); - for( unsigned int i = 0; i < sizeof( aPaperTab )/sizeof( aPaperTab[0] ); i++ ) - { - if( ! rtl_str_compareIgnoreAsciiCase( aPaper.GetBuffer(), aPaperTab[i].name ) ) - return aPaperTab[i].paper; - } - return PAPER_USER; -} - static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData ) { pJobSetup->meOrientation = (Orientation)(rData.m_eOrientation == orientation::Landscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT); @@ -166,7 +135,8 @@ static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData ) int width, height; rData.m_aContext.getPageSize( aPaper, width, height ); - pJobSetup->mePaperFormat = getPaperType( aPaper ); + pJobSetup->mePaperFormat = PaperInfo::fromPSName(OUStringToOString( aPaper, RTL_TEXTENCODING_ISO_8859_1 )); + pJobSetup->mnPaperWidth = 0; pJobSetup->mnPaperHeight = 0; if( pJobSetup->mePaperFormat == PAPER_USER ) @@ -544,14 +514,9 @@ void PspSalInfoPrinter::InitPaperFormats( const ImplJobSetup* ) for( int i = 0; i < nValues; i++ ) { const PPDValue* pValue = pKey->getValue( i ); - vcl::PaperInfo aInfo; - aInfo.m_aPaperName = pValue->m_aOptionTranslation; - if( ! aInfo.m_aPaperName.Len() ) - aInfo.m_aPaperName = pValue->m_aOption; int nWidth = 0, nHeight = 0; m_aJobData.m_pParser->getPaperDimension( pValue->m_aOption, nWidth, nHeight ); - aInfo.m_nPaperWidth = (unsigned long)((PtTo10Mu( nWidth )+50)/100); - aInfo.m_nPaperHeight = (unsigned long)((PtTo10Mu( nHeight )+50)/100); + PaperInfo aInfo(PtTo10Mu( nWidth ), PtTo10Mu( nHeight )); m_aPaperFormats.push_back( aInfo ); } } @@ -730,7 +695,7 @@ BOOL PspSalInfoPrinter::SetData( TenMuToPt( pJobSetup->mnPaperWidth ), TenMuToPt( pJobSetup->mnPaperHeight ) ); else - aPaper = String( ByteString( aPaperTab[ pJobSetup->mePaperFormat ].name ), RTL_TEXTENCODING_ISO_8859_1 ); + aPaper = rtl::OStringToOUString(PaperInfo::toPSName(pJobSetup->mePaperFormat), RTL_TEXTENCODING_ISO_8859_1); pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) ); pValue = pKey ? pKey->getValueCaseInsensitive( aPaper ) : NULL; diff --git a/vcl/unx/source/plugadapt/salplug.cxx b/vcl/unx/source/plugadapt/salplug.cxx index 0c791ca8091f..8a1ed05b8e25 100644 --- a/vcl/unx/source/plugadapt/salplug.cxx +++ b/vcl/unx/source/plugadapt/salplug.cxx @@ -55,13 +55,16 @@ typedef SalInstance*(*salFactoryProc)( oslModule pModule); static oslModule pCloseModule = NULL; -#define DESKTOP_NONE 0 -#define DESKTOP_UNKNOWN 1 -#define DESKTOP_GNOME 2 -#define DESKTOP_KDE 3 -#define DESKTOP_CDE 4 +enum { + DESKTOP_NONE = 0, + DESKTOP_UNKNOWN, + DESKTOP_GNOME, + DESKTOP_KDE, + DESKTOP_KDE4, + DESKTOP_CDE +}; -static const char * desktop_strings[5] = { "none", "unknown", "GNOME", "KDE", "CDE" }; +static const char * desktop_strings[] = { "none", "unknown", "GNOME", "KDE", "KDE4", "CDE" }; static SalInstance* tryInstance( const OUString& rModuleBase ) { @@ -225,15 +228,18 @@ extern "C" typedef int(* XErrorHandler)(Display*,XErrorEvent*); } -static OUString getNetWMName( Display* pDisplay ) +static int KDEVersion( Display* pDisplay ) { - OUString aRet; + int nRet = 0; - Atom nWmCheck = XInternAtom( pDisplay, "_NET_SUPPORTING_WM_CHECK", True ); - Atom nWmName = XInternAtom( pDisplay, "_NET_WM_NAME", True ); - if( nWmName && nWmCheck ) + Atom nFullSession = XInternAtom( pDisplay, "KDE_FULL_SESSION", True ); + Atom nKDEVersion = XInternAtom( pDisplay, "KDE_SESSION_VERSION", True ); + + if( nFullSession ) { - XLIB_Window aCheckWin = None; + if( !nKDEVersion ) + return 3; + Atom aRealType = None; int nFormat = 8; unsigned long nItems = 0; @@ -241,86 +247,63 @@ static OUString getNetWMName( Display* pDisplay ) unsigned char* pProperty = NULL; XGetWindowProperty( pDisplay, DefaultRootWindow( pDisplay ), - nWmCheck, + nKDEVersion, 0, 1, False, - XA_WINDOW, + AnyPropertyType, &aRealType, &nFormat, &nItems, &nBytesLeft, &pProperty ); - if( aRealType == XA_WINDOW && nFormat == 32 && nItems != 0 ) - aCheckWin = *(XLIB_Window*)pProperty; + if( !WasXError() && nItems != 0 && pProperty ) + { + nRet = *reinterpret_cast< sal_Int32* >( pProperty ); + } if( pProperty ) { XFree( pProperty ); pProperty = NULL; } + } + return nRet; +} - // see if that window really exists and has the check property set - if( aCheckWin != None ) +static bool is_kde_desktop( Display* pDisplay ) +{ + if ( NULL != getenv( "KDE_FULL_SESSION" ) ) + { + const char *pVer = getenv( "KDE_SESSION_VERSION" ); + if ( !pVer || pVer[0] == '0' ) { - // clear error flag - WasXError(); - // get the property - XGetWindowProperty( pDisplay, - aCheckWin, - nWmCheck, - 0, 1, - False, - XA_WINDOW, - &aRealType, - &nFormat, - &nItems, - &nBytesLeft, - &pProperty ); - if( ! WasXError() && aRealType == XA_WINDOW && nFormat == 32 && nItems != 0 && pProperty ) - { - if( aCheckWin == *(XLIB_Window*)pProperty ) - { - XFree( pProperty ); - pProperty = NULL; - XGetWindowProperty( pDisplay, - aCheckWin, - nWmName, - 0, 256, - False, - AnyPropertyType, - &aRealType, - &nFormat, - &nItems, - &nBytesLeft, - &pProperty ); - if( !WasXError() && nItems != 0 && pProperty && *pProperty ) - { - if( aRealType == XA_STRING ) // some WM's use this although the should use UTF8_STRING - { - aRet = rtl::OStringToOUString( rtl::OString( (sal_Char*)pProperty ), RTL_TEXTENCODING_ISO_8859_1 ); - } - else - aRet = rtl::OStringToOUString( rtl::OString( (sal_Char*)pProperty ), RTL_TEXTENCODING_UTF8 ); - } - } - } - if( pProperty ) - { - XFree( pProperty ); - pProperty = NULL; - } + return true; // does not exist => KDE3 + } + + rtl::OUString aVer( RTL_CONSTASCII_USTRINGPARAM( "3" ) ); + if ( aVer.equalsIgnoreAsciiCaseAscii( pVer ) ) + { + return true; } } - return aRet; + + if ( KDEVersion( pDisplay ) == 3 ) + return true; + + return false; } -static bool is_kde_desktop( Display* pDisplay ) +static bool is_kde4_desktop( Display* pDisplay ) { if ( NULL != getenv( "KDE_FULL_SESSION" ) ) - return true; + { + rtl::OUString aVer( RTL_CONSTASCII_USTRINGPARAM( "4" ) ); + + const char *pVer = getenv( "KDE_SESSION_VERSION" ); + if ( pVer && aVer.equalsIgnoreAsciiCaseAscii( pVer ) ) + return true; + } - // check for kwin - rtl::OUString aWM = getNetWMName( pDisplay ); - if( aWM.equalsIgnoreAsciiCaseAscii( "KWin" ) ) + if ( KDEVersion( pDisplay ) == 4 ) return true; return false; @@ -355,6 +338,8 @@ static const char * get_desktop_environment() pRet = desktop_strings[DESKTOP_CDE]; if ( aOver.equalsIgnoreAsciiCase( "kde" ) ) pRet = desktop_strings[DESKTOP_KDE]; + if ( aOver.equalsIgnoreAsciiCase( "kde4" ) ) + pRet = desktop_strings[DESKTOP_KDE4]; if ( aOver.equalsIgnoreAsciiCase( "gnome" ) ) pRet = desktop_strings[DESKTOP_GNOME]; if ( aOver.equalsIgnoreAsciiCase( "none" ) ) @@ -395,7 +380,9 @@ static const char * get_desktop_environment() { XErrorHandler pOldHdl = XSetErrorHandler( autodect_error_handler ); - if ( is_kde_desktop( pDisplay ) ) + if ( is_kde4_desktop( pDisplay ) ) + pRet = desktop_strings[DESKTOP_KDE4]; + else if ( is_kde_desktop( pDisplay ) ) pRet = desktop_strings[DESKTOP_KDE]; else if ( is_gnome_desktop( pDisplay ) ) pRet = desktop_strings[DESKTOP_GNOME]; @@ -428,6 +415,8 @@ static const char* autodetect_plugin() pRet = "gtk"; else if( desktop == desktop_strings[DESKTOP_KDE] ) pRet = "kde"; + else if( desktop == desktop_strings[DESKTOP_KDE4] ) + pRet = "kde4"; else { // #i95296# use the much nicer looking gtk plugin diff --git a/vcl/unx/source/printer/printerinfomanager.cxx b/vcl/unx/source/printer/printerinfomanager.cxx index cf5a4a886c41..b3e5b4667a6a 100644 --- a/vcl/unx/source/printer/printerinfomanager.cxx +++ b/vcl/unx/source/printer/printerinfomanager.cxx @@ -44,6 +44,8 @@ #include "tools/debug.hxx" #include "tools/config.hxx" +#include "i18npool/paper.hxx" + #include "rtl/strbuf.hxx" #include "osl/thread.hxx" @@ -154,77 +156,9 @@ void PrinterInfoManager::setCUPSDisabled( bool bDisable ) void PrinterInfoManager::initSystemDefaultPaper() { - bool bSuccess = false; - - // try libpaper - - // #i78617# workaround missing paperconf command - FILE* pPipe = popen( "sh -c paperconf 2>/dev/null", "r" ); - if( pPipe ) - { - char pBuffer[ 1024 ]; - *pBuffer = 0; - fgets( pBuffer, sizeof(pBuffer)-1, pPipe ); - pclose( pPipe ); - - ByteString aPaper( pBuffer ); - aPaper = WhitespaceToSpace( aPaper ); - if( aPaper.Len() ) - { - m_aSystemDefaultPaper = OUString( OStringToOUString( aPaper, osl_getThreadTextEncoding() ) ); - bSuccess = true; - #if OSL_DEBUG_LEVEL > 1 - fprintf( stderr, "paper from paperconf = %s\n", aPaper.GetBuffer() ); - #endif - } - if( bSuccess ) - return; - } - - // default value is Letter for US (en_US), Cannada (en_CA, fr_CA); else A4 - // en will be interpreted as en_US - - // note: at this point m_aSystemDefaultPaper is set to "A4" from the constructor - - // check for LC_PAPER - const char* pPaperLang = getenv( "LC_PAPER" ); - if( pPaperLang && *pPaperLang ) - { - OString aLang( pPaperLang ); - if( aLang.getLength() > 5 ) - aLang = aLang.copy( 0, 5 ); - if( aLang.getLength() == 5 ) - { - if( aLang.equalsIgnoreAsciiCase( "en_us" ) - || aLang.equalsIgnoreAsciiCase( "en_ca" ) - || aLang.equalsIgnoreAsciiCase( "fr_ca" ) - ) - m_aSystemDefaultPaper = OUString( RTL_CONSTASCII_USTRINGPARAM( "Letter" ) ); - } - else if( aLang.getLength() == 2 && aLang.equalsIgnoreAsciiCase( "en" ) ) - m_aSystemDefaultPaper = OUString( RTL_CONSTASCII_USTRINGPARAM( "Letter" ) ); - return; - } - - // use process locale to determine paper - rtl_Locale* pLoc = NULL; - osl_getProcessLocale( &pLoc ); - if( pLoc ) - { - if( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pLoc->Language->buffer, pLoc->Language->length, "en") ) - { - if( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pLoc->Country->buffer, pLoc->Country->length, "us") - || 0 == rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pLoc->Country->buffer, pLoc->Country->length, "ca") - || pLoc->Country->length == 0 - ) - m_aSystemDefaultPaper = OUString( RTL_CONSTASCII_USTRINGPARAM( "Letter" ) ); - } - else if( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pLoc->Language->buffer, pLoc->Language->length, "fr") ) - { - if( 0 == rtl_ustr_ascii_compareIgnoreAsciiCase_WithLength( pLoc->Country->buffer, pLoc->Country->length, "ca") ) - m_aSystemDefaultPaper = OUString( RTL_CONSTASCII_USTRINGPARAM( "Letter" ) ); - } - } + m_aSystemDefaultPaper = rtl::OStringToOUString( + PaperInfo::toPSName(PaperInfo::getSystemDefaultPaper().getPaper()), + RTL_TEXTENCODING_UTF8); } // ----------------------------------------------------------------- diff --git a/vcl/unx/source/window/salframe.cxx b/vcl/unx/source/window/salframe.cxx index 22e43999caa6..04eb9cd32771 100644 --- a/vcl/unx/source/window/salframe.cxx +++ b/vcl/unx/source/window/salframe.cxx @@ -72,6 +72,7 @@ #include "tools/debug.hxx" #include "sal/alloca.h" +#include <com/sun/star/uno/Exception.hpp> #include <algorithm> @@ -425,15 +426,26 @@ void X11SalFrame::Init( ULONG nSalFrameStyle, int nScreen, SystemParentData* pPa if( IsOverrideRedirect() ) Attributes.override_redirect = True; // default icon - if( (nStyle_ & SAL_FRAME_STYLE_INTRO) == 0 && - SelectAppIconPixmap( pDisplay_, m_nScreen, - mnIconID != 1 ? mnIconID : - (mpParent ? mpParent->mnIconID : 1), 32, - Hints.icon_pixmap, Hints.icon_mask )) + if( (nStyle_ & SAL_FRAME_STYLE_INTRO) == 0 ) { - Hints.flags |= IconPixmapHint; - if( Hints.icon_mask ) - Hints.flags |= IconMaskHint; + bool bOk=false; + try + { + bOk=SelectAppIconPixmap( pDisplay_, m_nScreen, + mnIconID != 1 ? mnIconID : + (mpParent ? mpParent->mnIconID : 1), 32, + Hints.icon_pixmap, Hints.icon_mask ); + } + catch( com::sun::star::uno::Exception& ) + { + // can happen - no ucb during early startup + } + if( bOk ) + { + Hints.flags |= IconPixmapHint; + if( Hints.icon_mask ) + Hints.flags |= IconMaskHint; + } } // find the top level frame of the transience hierarchy diff --git a/vcl/util/linksvp/makefile.mk b/vcl/util/linksvp/makefile.mk index 8e7d6f35ef83..e5e82323af5c 100644 --- a/vcl/util/linksvp/makefile.mk +++ b/vcl/util/linksvp/makefile.mk @@ -54,6 +54,7 @@ SHL1LIBS=$(LIB1TARGET) SHL1DEPN=$(LB)$/libvcl$(DLLPOSTFIX)$(DLLPOST) SHL1STDLIBS=\ $(VCLLIB)\ + $(I18NPAPERLIB)\ $(BASEBMPLIB)\ $(BASEGFXLIB)\ $(TOOLSLIB) \ diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk index 08d6f9197f28..4c0cd7dba656 100644 --- a/vcl/util/makefile.mk +++ b/vcl/util/makefile.mk @@ -6,10 +6,6 @@ # # OpenOffice.org - a multi-platform office productivity suite # -# $RCSfile: makefile.mk,v $ -# -# $Revision: 1.111.36.3 $ -# # This file is part of OpenOffice.org. # # OpenOffice.org is free software: you can redistribute it and/or modify @@ -170,8 +166,9 @@ SHL1STDLIBS+=\ $(SOTLIB) \ $(UNOTOOLSLIB) \ $(TOOLSLIB) \ + $(I18NPAPERLIB) \ $(I18NISOLANGLIB) \ - $(I18NUTILLIB) \ + $(I18NUTILLIB) \ $(COMPHELPERLIB) \ $(UCBHELPERLIB) \ $(CPPUHELPERLIB) \ @@ -183,6 +180,16 @@ SHL1STDLIBS+=\ $(ICUDATALIB) \ $(ICULELIB) \ $(JVMACCESSLIB) + +.IF "$(GUI)" == "UNX" +.IF "$(ENABLE_GRAPHITE)" != "" +.IF "$(SYSTEM_GRAPHITE)" == "YES" +SHL1STDLIBS+= $(GRAPHITE_LIBS) +.ELSE +SHL1STDLIBS+= $(SOLARVERSION)/$(INPATH)/lib$(UPDMINOREXT)/libgraphite.a +.ENDIF +.ENDIF +.ENDIF SHL1USE_EXPORTS=name .IF "$(GUIBASE)"=="aqua" @@ -197,12 +204,16 @@ LIB1FILES+= \ .IF "$(USE_BUILTIN_RASTERIZER)"!="" LIB1FILES += $(SLB)$/glyphs.lib SHL1STDLIBS+= $(FREETYPELIB) +.ELSE +.IF "$(ENABLE_GRAPHITE)" == "TRUE" + LIB1FILES += $(SLB)$/glyphs.lib +.ENDIF .ENDIF # USE_BUILTIN_RASTERIZER SHL1LIBS= $(LIB1TARGET) .IF "$(GUI)"!="UNX" .IF "$(COM)"!="GCC" -SHL1OBJS= $(SLO)$/salshl.obj +#SHL1OBJS= $(SLO)$/salshl.obj .ENDIF .ENDIF @@ -222,6 +233,14 @@ DEFLIB1NAME =vcl .IF "$(GUI)" == "WNT" +.IF "$(ENABLE_GRAPHITE)" == "TRUE" +.IF "$(COM)" == "GCC" +SHL1STDLIBS += -lgraphite +.ELSE +SHL1STDLIBS += graphite_dll.lib +.ENDIF +.ENDIF + SHL1STDLIBS += $(UWINAPILIB) \ $(GDI32LIB) \ $(GDIPLUSLIB) \ @@ -264,6 +283,7 @@ SHL2DEPN=$(SHL1IMPLIBN) $(SHL1TARGETN) # libs for generic plugin SHL2STDLIBS=\ $(VCLLIB)\ + $(I18NPAPERLIB) \ $(TOOLSLIB) \ $(VOSLIB) \ $(BASEGFXLIB) \ @@ -364,7 +384,7 @@ SHL5IMPLIB=ikde_plug_ SHL5LIBS=$(LIB5TARGET) SHL5DEPN=$(SHL2TARGETN) # libs for KDE plugin -SHL5STDLIBS=$(KDE_LIBS) +SHL5LINKFLAGS+=$(KDE_LIBS) SHL5STDLIBS+=-l$(SHL2TARGET) SHL5STDLIBS+=\ $(VCLLIB) \ @@ -380,6 +400,35 @@ SHL5STDLIBS+= $(XRANDR_LIBS) .ENDIF # "$(ENABLE_KDE)" != "" +# KDE4 plugin +.IF "$(ENABLE_KDE4)" != "" +.IF "$(KDE4_ROOT)"!="" +EXTRALIBPATHS+=-L$(KDE4_ROOT)$/lib +.ENDIF +LIB6TARGET=$(SLB)$/ikde4_plug_ +LIB6FILES=$(SLB)$/kde4plug.lib +SHL6TARGET=vclplug_kde4$(DLLPOSTFIX) +SHL6IMPLIB=ikde4_plug_ +SHL6LIBS=$(LIB6TARGET) +SHL6DEPN=$(SHL2TARGETN) +# libs for KDE4 plugin +SHL6LINKFLAGS+=$(KDE4_LIBS) +SHL6STDLIBS+=-l$(SHL2TARGET) +SHL6STDLIBS+=\ + $(VCLLIB) \ + $(PSPLIB) \ + $(TOOLSLIB) \ + $(VOSLIB) \ + $(SALLIB) + +.IF "$(ENABLE_RANDR)" != "" +.IF "$(XRANDR_DLOPEN)" == "FALSE" +SHL6STDLIBS+= $(XRANDR_LIBS) +.ENDIF +.ENDIF + +.ENDIF # "$(ENABLE_KDE4)" != "" + .ENDIF # UNX # --- Allgemein ---------------------------------------------------------- diff --git a/vcl/win/inc/salgdi.h b/vcl/win/inc/salgdi.h index 0475ea4a193e..c7ceb68199b9 100644 --- a/vcl/win/inc/salgdi.h +++ b/vcl/win/inc/salgdi.h @@ -81,6 +81,9 @@ public: bool SupportsArabic() const { return mbHasArabicSupport; } bool AliasSymbolsHigh() const { return mbAliasSymbolsHigh; } bool AliasSymbolsLow() const { return mbAliasSymbolsLow; } +#ifdef ENABLE_GRAPHITE + bool SupportsGraphite() const { return mbHasGraphiteSupport; } +#endif ImplFontCharMap* GetImplFontCharMap() const; const Ucs2SIntMap* GetEncodingVector() const { return mpEncodingVector; } @@ -97,6 +100,9 @@ private: mutable bool mbDisableGlyphApi; mutable bool mbHasKoreanRange; mutable bool mbHasCJKSupport; +#ifdef ENABLE_GRAPHITE + mutable bool mbHasGraphiteSupport; +#endif mutable bool mbHasArabicSupport; mutable ImplFontCharMap* mpUnicodeMap; mutable const Ucs2SIntMap* mpEncodingVector; diff --git a/vcl/win/source/gdi/MAKEFILE.MK b/vcl/win/source/gdi/MAKEFILE.MK index d50abc1b5aa3..3d8fd904b35b 100644 --- a/vcl/win/source/gdi/MAKEFILE.MK +++ b/vcl/win/source/gdi/MAKEFILE.MK @@ -44,7 +44,6 @@ TARGET=salgdi # --- #105371# .IF "$(COM)"=="GCC" -CDEFS += -UWINVER -DWINVER=0x0400 .ELSE CFLAGS += -DWINVER=0x0400 .ENDIF @@ -65,6 +64,10 @@ SLOFILES= $(SLO)$/salgdi.obj \ EXCEPTIONSFILES= $(SLO)$/salprn.obj +.IF "$(ENABLE_GRAPHITE)" == "TRUE" +CFLAGS+=-DENABLE_GRAPHITE +.ENDIF + # --- Targets ------------------------------------------------------ .INCLUDE : target.mk diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 99f276faa964..2bae9ab1388b 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -74,6 +74,11 @@ #include <algorithm> #endif +#ifdef ENABLE_GRAPHITE +#include <graphite/GrClient.h> +#include <graphite/WinFont.h> +#endif + #include <vector> #include <set> #include <map> @@ -807,6 +812,9 @@ ImplWinFontData::ImplWinFontData( const ImplDevFontAttributes& rDFS, mbDisableGlyphApi( false ), mbHasKoreanRange( false ), mbHasCJKSupport( false ), +#ifdef ENABLE_GRAPHITE + mbHasGraphiteSupport( false ), +#endif mbHasArabicSupport ( false ), mbAliasSymbolsLow( false ), mbAliasSymbolsHigh( false ), @@ -865,6 +873,13 @@ void ImplWinFontData::UpdateFromHDC( HDC hDC ) const ReadCmapTable( hDC ); ReadOs2Table( hDC ); +#ifdef ENABLE_GRAPHITE + static const char* pDisableGraphiteText = getenv( "SAL_DISABLE_GRAPHITE" ); + if( !pDisableGraphiteText || (pDisableGraphiteText[0] == '0') ) + { + mbHasGraphiteSupport = gr::WinFont::FontHasGraphiteTables(hDC); + } +#endif // even if the font works some fonts have problems with the glyph API // => the heuristic below tries to figure out which fonts have the problem diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx index 8709fc872540..5c00c786e22d 100644 --- a/vcl/win/source/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx @@ -64,75 +64,79 @@ void impAddB2DPolygonToGDIPlusGraphicsPath(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon) { - const sal_uInt32 nCount(rPolygon.count());
-
- if(nCount)
- {
- const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
- const bool bControls(rPolygon.areControlPointsUsed());
- basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
- Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY()));
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- const sal_uInt32 nNextIndex((a + 1) % nCount);
- const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
- const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY()));
-
- if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
- {
- const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
- rPath.AddBezier(
- aFCurr,
- Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())),
- Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())),
- aFNext);
- }
- else
- {
- rPath.AddLine(aFCurr, aFNext);
- }
-
- if(a + 1 < nEdgeCount)
- {
- aCurr = aNext;
- aFCurr = aFNext;
- }
- }
- }
+ const sal_uInt32 nCount(rPolygon.count()); + + if(nCount) + { + const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1); + const bool bControls(rPolygon.areControlPointsUsed()); + basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0)); + Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY())); + + for(sal_uInt32 a(0); a < nEdgeCount; a++) + { + const sal_uInt32 nNextIndex((a + 1) % nCount); + const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex)); + const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY())); + + if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex))) + { + const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a)); + const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex)); + + rPath.AddBezier( + aFCurr, + Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())), + Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())), + aFNext); + } + else + { + rPath.AddLine(aFCurr, aFNext); + } + + if(a + 1 < nEdgeCount) + { + aCurr = aNext; + aFCurr = aFNext; + } + } + } } bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency) { - const sal_uInt32 nCount(rPolyPolygon.count());
+ const sal_uInt32 nCount(rPolyPolygon.count()); if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0)) { - Gdiplus::Graphics aGraphics(mhDC);
+ Gdiplus::Graphics aGraphics(mhDC); const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0)); - Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
- Gdiplus::SolidBrush aTestBrush(aTestColor);
- Gdiplus::GraphicsPath aPath;
+ Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor)); + Gdiplus::SolidBrush aTestBrush(aTestColor); + Gdiplus::GraphicsPath aPath; for(sal_uInt32 a(0); a < nCount; a++) { - aPath.StartFigure(); + if(0 != a) + { + aPath.StartFigure(); // #i101491# not needed for first run + } + impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolyPolygon.getB2DPolygon(a)); aPath.CloseFigure(); } if(getAntiAliasB2DDraw()) { - aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
- }
-
- aGraphics.FillPath(&aTestBrush, &aPath);
+ aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + else + { + aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone); + } + + aGraphics.FillPath(&aTestBrush, &aPath); } return true; @@ -140,53 +144,59 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly bool WinSalGraphics::drawPolyLine(const basegfx::B2DPolygon& rPolygon, const basegfx::B2DVector& rLineWidths, basegfx::B2DLineJoin eLineJoin) { - const sal_uInt32 nCount(rPolygon.count());
+ const sal_uInt32 nCount(rPolygon.count()); if(mbPen && nCount) { - Gdiplus::Graphics aGraphics(mhDC);
- Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
- Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
- Gdiplus::GraphicsPath aPath;
-
- switch(eLineJoin)
- {
+ Gdiplus::Graphics aGraphics(mhDC); + Gdiplus::Color aTestColor(255, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor)); + Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX())); + Gdiplus::GraphicsPath aPath; + + switch(eLineJoin) + { default : // basegfx::B2DLINEJOIN_NONE : { break; } case basegfx::B2DLINEJOIN_BEVEL : { - aTestPen.SetLineJoin(Gdiplus::LineJoinBevel);
+ aTestPen.SetLineJoin(Gdiplus::LineJoinBevel); break; } case basegfx::B2DLINEJOIN_MIDDLE : case basegfx::B2DLINEJOIN_MITER : { const Gdiplus::REAL aMiterLimit(15.0); - aTestPen.SetMiterLimit(aMiterLimit);
- aTestPen.SetLineJoin(Gdiplus::LineJoinMiter);
+ aTestPen.SetMiterLimit(aMiterLimit); + aTestPen.SetLineJoin(Gdiplus::LineJoinMiter); break; } case basegfx::B2DLINEJOIN_ROUND : { - aTestPen.SetLineJoin(Gdiplus::LineJoinRound);
+ aTestPen.SetLineJoin(Gdiplus::LineJoinRound); break; } - }
+ } impAddB2DPolygonToGDIPlusGraphicsPath(aPath, rPolygon); -
- if(getAntiAliasB2DDraw())
- {
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
- }
-
- aGraphics.DrawPath(&aTestPen, &aPath);
+ + if(rPolygon.isClosed()) + { + // #i101491# needed to create the correct line joins + aPath.CloseFigure(); + } + + if(getAntiAliasB2DDraw()) + { + aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); + } + else + { + aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone); + } + + aGraphics.DrawPath(&aTestPen, &aPath); } return true; diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx index cc359da97cd9..ecf91aea7c1b 100644 --- a/vcl/win/source/gdi/salprn.cxx +++ b/vcl/win/source/gdi/salprn.cxx @@ -894,6 +894,24 @@ static void ImplDevModeToJobSetup( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS } switch( CHOOSE_DEVMODE(dmPaperSize) ) { + case( DMPAPER_LETTER ): + pSetupData->mePaperFormat = PAPER_LETTER; + break; + case( DMPAPER_TABLOID ): + pSetupData->mePaperFormat = PAPER_TABLOID; + break; + case( DMPAPER_LEDGER ): + pSetupData->mePaperFormat = PAPER_LEDGER; + break; + case( DMPAPER_LEGAL ): + pSetupData->mePaperFormat = PAPER_LEGAL; + break; + case( DMPAPER_STATEMENT ): + pSetupData->mePaperFormat = PAPER_STATEMENT; + break; + case( DMPAPER_EXECUTIVE ): + pSetupData->mePaperFormat = PAPER_EXECUTIVE; + break; case( DMPAPER_A3 ): pSetupData->mePaperFormat = PAPER_A3; break; @@ -903,20 +921,138 @@ static void ImplDevModeToJobSetup( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS case( DMPAPER_A5 ): pSetupData->mePaperFormat = PAPER_A5; break; + //See http://wiki.services.openoffice.org/wiki/DefaultPaperSize + //i.e. + //http://msdn.microsoft.com/en-us/library/dd319099(VS.85).aspx + //DMPAPER_B4 12 B4 (JIS) 257 x 364 mm + //http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf + //also says that the MS DMPAPER_B4 is JIS, which makes most sense. And + //matches our Excel filter's belief about the matching XlPaperSize + //enumeration. + // + //http://msdn.microsoft.com/en-us/library/ms776398(VS.85).aspx said + ////"DMPAPER_B4 12 B4 (JIS) 250 x 354" + //which is bogus as it's either JIS 257 × 364 or ISO 250 × 353 + //(cmc) case( DMPAPER_B4 ): - pSetupData->mePaperFormat = PAPER_B4; + pSetupData->mePaperFormat = PAPER_B4_JIS; break; case( DMPAPER_B5 ): - pSetupData->mePaperFormat = PAPER_B5; + pSetupData->mePaperFormat = PAPER_B5_JIS; break; - case( DMPAPER_LETTER ): + case( DMPAPER_QUARTO ): + pSetupData->mePaperFormat = PAPER_QUARTO; + break; + case( DMPAPER_10X14 ): + pSetupData->mePaperFormat = PAPER_10x14; + break; + case( DMPAPER_NOTE ): pSetupData->mePaperFormat = PAPER_LETTER; break; - case( DMPAPER_LEGAL ): - pSetupData->mePaperFormat = PAPER_LEGAL; + case( DMPAPER_ENV_9 ): + pSetupData->mePaperFormat = PAPER_ENV_9; break; - case( DMPAPER_TABLOID ): - pSetupData->mePaperFormat = PAPER_TABLOID; + case( DMPAPER_ENV_10 ): + pSetupData->mePaperFormat = PAPER_ENV_10; + break; + case( DMPAPER_ENV_11 ): + pSetupData->mePaperFormat = PAPER_ENV_11; + break; + case( DMPAPER_ENV_12 ): + pSetupData->mePaperFormat = PAPER_ENV_12; + break; + case( DMPAPER_ENV_14 ): + pSetupData->mePaperFormat = PAPER_ENV_14; + break; + case( DMPAPER_CSHEET ): + pSetupData->mePaperFormat = PAPER_C; + break; + case( DMPAPER_DSHEET ): + pSetupData->mePaperFormat = PAPER_D; + break; + case( DMPAPER_ESHEET ): + pSetupData->mePaperFormat = PAPER_E; + break; + case( DMPAPER_ENV_DL): + pSetupData->mePaperFormat = PAPER_ENV_DL; + break; + case( DMPAPER_ENV_C5): + pSetupData->mePaperFormat = PAPER_ENV_C5; + break; + case( DMPAPER_ENV_C3): + pSetupData->mePaperFormat = PAPER_ENV_C3; + break; + case( DMPAPER_ENV_C4): + pSetupData->mePaperFormat = PAPER_ENV_C4; + break; + case( DMPAPER_ENV_C6): + pSetupData->mePaperFormat = PAPER_ENV_C6; + break; + case( DMPAPER_ENV_C65): + pSetupData->mePaperFormat = PAPER_ENV_C65; + break; + case( DMPAPER_ENV_ITALY ): + pSetupData->mePaperFormat = PAPER_ENV_ITALY; + break; + case( DMPAPER_ENV_MONARCH ): + pSetupData->mePaperFormat = PAPER_ENV_MONARCH; + break; + case( DMPAPER_ENV_PERSONAL ): + pSetupData->mePaperFormat = PAPER_ENV_PERSONAL; + break; + case( DMPAPER_FANFOLD_US ): + pSetupData->mePaperFormat = PAPER_FANFOLD_US; + break; + case( DMPAPER_FANFOLD_STD_GERMAN ): + pSetupData->mePaperFormat = PAPER_FANFOLD_DE; + break; + case( DMPAPER_FANFOLD_LGL_GERMAN ): + pSetupData->mePaperFormat = PAPER_FANFOLD_LEGAL_DE; + break; + case( DMPAPER_ISO_B4 ): + pSetupData->mePaperFormat = PAPER_B4_ISO; + break; + case( DMPAPER_JAPANESE_POSTCARD ): + pSetupData->mePaperFormat = PAPER_POSTCARD_JP; + break; + case( DMPAPER_9X11 ): + pSetupData->mePaperFormat = PAPER_9x11; + break; + case( DMPAPER_10X11 ): + pSetupData->mePaperFormat = PAPER_10x11; + break; + case( DMPAPER_15X11 ): + pSetupData->mePaperFormat = PAPER_15x11; + break; + case( DMPAPER_ENV_INVITE ): + pSetupData->mePaperFormat = PAPER_ENV_INVITE; + break; + case( DMPAPER_A_PLUS ): + pSetupData->mePaperFormat = PAPER_A_PLUS; + break; + case( DMPAPER_B_PLUS ): + pSetupData->mePaperFormat = PAPER_B_PLUS; + break; + case( DMPAPER_LETTER_PLUS ): + pSetupData->mePaperFormat = PAPER_LETTER_PLUS; + break; + case( DMPAPER_A4_PLUS ): + pSetupData->mePaperFormat = PAPER_A4_PLUS; + break; + case( DMPAPER_A2 ): + pSetupData->mePaperFormat = PAPER_A2; + break; + case( DMPAPER_DBL_JAPANESE_POSTCARD ): + pSetupData->mePaperFormat = PAPER_DOUBLEPOSTCARD_JP; + break; + case( DMPAPER_A6 ): + pSetupData->mePaperFormat = PAPER_A6; + break; + case( DMPAPER_B6_JIS ): + pSetupData->mePaperFormat = PAPER_B6_JIS; + break; + case( DMPAPER_12X11 ): + pSetupData->mePaperFormat = PAPER_12x11; break; default: pSetupData->mePaperFormat = PAPER_USER; @@ -927,17 +1063,6 @@ static void ImplDevModeToJobSetup( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS // ----------------------------------------------------------------------- -static BOOL ImplPaperSizeEqual( short nPaperWidth1, short nPaperHeight1, - short nPaperWidth2, short nPaperHeight2 ) -{ - const short PAPER_SLOPPY = 1; // 0.1 mm accuracy - - return ( (Abs( nPaperWidth1-nPaperWidth2 ) <= PAPER_SLOPPY) && - (Abs( nPaperHeight1-nPaperHeight2 ) <= PAPER_SLOPPY) ); -} - -// ----------------------------------------------------------------------- - static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pSetupData, ULONG nFlags ) { if ( !pSetupData || !pSetupData->mpDriverData ) @@ -979,6 +1104,9 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS switch( pSetupData->mePaperFormat ) { + case( PAPER_A2 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A2; + break; case( PAPER_A3 ): CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A3; break; @@ -988,11 +1116,8 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS case( PAPER_A5 ): CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A5; break; - case( PAPER_B4 ): - CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B4; - break; - case( PAPER_B5 ): - CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B5; + case( PAPER_B4_ISO): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ISO_B4; break; case( PAPER_LETTER ): CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LETTER; @@ -1003,6 +1128,136 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS case( PAPER_TABLOID ): CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_TABLOID; break; +#if 0 + //http://msdn.microsoft.com/en-us/library/ms776398(VS.85).aspx + //DMPAPER_ENV_B6 is documented as: + //"DMPAPER_ENV_B6 35 Envelope B6 176 x 125 mm" + //which is the wrong way around, it is surely 125 x 176, i.e. + //compare DMPAPER_ENV_B4 and DMPAPER_ENV_B4 as + //DMPAPER_ENV_B4 33 Envelope B4 250 x 353 mm + //DMPAPER_ENV_B5 34 Envelope B5 176 x 250 mm + case( PAPER_B6_ISO ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_B6; + break; +#endif + case( PAPER_ENV_C4 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C4; + break; + case( PAPER_ENV_C5 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C5; + break; + case( PAPER_ENV_C6 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C6; + break; + case( PAPER_ENV_C65 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C65; + break; + case( PAPER_ENV_DL ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_DL; + break; + case( PAPER_C ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_CSHEET; + break; + case( PAPER_D ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_DSHEET; + break; + case( PAPER_E ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ESHEET; + break; + case( PAPER_EXECUTIVE ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_EXECUTIVE; + break; + case( PAPER_FANFOLD_LEGAL_DE ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_FANFOLD_LGL_GERMAN; + break; + case( PAPER_ENV_MONARCH ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_MONARCH; + break; + case( PAPER_ENV_PERSONAL ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_PERSONAL; + break; + case( PAPER_ENV_9 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_9; + break; + case( PAPER_ENV_10 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_10; + break; + case( PAPER_ENV_11 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_11; + break; + case( PAPER_ENV_12 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_12; + break; + //See the comments on DMPAPER_B4 above + case( PAPER_B4_JIS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B4; + break; + case( PAPER_B5_JIS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B5; + break; + case( PAPER_B6_JIS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B6_JIS; + break; + case( PAPER_LEDGER ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LEDGER; + break; + case( PAPER_STATEMENT ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_STATEMENT; + break; + case( PAPER_10x14 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_10X14; + break; + case( PAPER_ENV_14 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_14; + break; + case( PAPER_ENV_C3 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_C3; + break; + case( PAPER_ENV_ITALY ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_ITALY; + break; + case( PAPER_FANFOLD_US ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_FANFOLD_US; + break; + case( PAPER_FANFOLD_DE ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_FANFOLD_STD_GERMAN; + break; + case( PAPER_POSTCARD_JP ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_JAPANESE_POSTCARD; + break; + case( PAPER_9x11 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_9X11; + break; + case( PAPER_10x11 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_10X11; + break; + case( PAPER_15x11 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_15X11; + break; + case( PAPER_ENV_INVITE ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_ENV_INVITE; + break; + case( PAPER_A_PLUS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A_PLUS; + break; + case( PAPER_B_PLUS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_B_PLUS; + break; + case( PAPER_LETTER_PLUS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_LETTER_PLUS; + break; + case( PAPER_A4_PLUS ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A4_PLUS; + break; + case( PAPER_DOUBLEPOSTCARD_JP ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_DBL_JAPANESE_POSTCARD; + break; + case( PAPER_A6 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_A6; + break; + case( PAPER_12x11 ): + CHOOSE_DEVMODE(dmPaperSize) = DMPAPER_12X11; + break; default: { short nPaper = 0; @@ -1023,13 +1278,11 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS } if ( (nPaperSizeCount == nPaperCount) && pPapers && pPaperSizes ) { + PaperInfo aInfo(pSetupData->mnPaperWidth, pSetupData->mnPaperHeight); // compare paper formats and select a good match for ( ULONG i = 0; i < nPaperCount; i++ ) { - if ( ImplPaperSizeEqual( (short)(pSetupData->mnPaperWidth/10), - (short)(pSetupData->mnPaperHeight/10), - (short)pPaperSizes[i].x, - (short)pPaperSizes[i].y ) ) + if ( aInfo.sloppyEqual(PaperInfo(pPaperSizes[i].x*10, pPaperSizes[i].y*10))) { nPaper = pPapers[i]; break; @@ -1041,12 +1294,10 @@ static void ImplJobSetupToDevMode( WinSalInfoPrinter* pPrinter, ImplJobSetup* pS // all paper sizes with portrait orientation only!! if ( !nPaper && nLandscapeAngle != 0 ) { + PaperInfo aRotatedInfo(pSetupData->mnPaperHeight, pSetupData->mnPaperWidth); for ( ULONG i = 0; i < nPaperCount; i++ ) { - if ( ImplPaperSizeEqual( (short)(pSetupData->mnPaperWidth/10), - (short)(pSetupData->mnPaperHeight/10), - (short)pPaperSizes[i].y, - (short)pPaperSizes[i].x ) ) + if ( aRotatedInfo.sloppyEqual(PaperInfo(pPaperSizes[i].x*10, pPaperSizes[i].y*10)) ) { nPaper = pPapers[i]; break; @@ -1284,11 +1535,7 @@ void WinSalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData ) ImplDeviceCaps( this, DC_PAPERNAMES, (BYTE*)pNamesBuffer, pSetupData ); for( DWORD i = 0; i < nCount; ++i ) { - vcl::PaperInfo aInfo; - aInfo.m_nPaperWidth = (pPaperSizes[i].x + 5) / 10; - aInfo.m_nPaperHeight = (pPaperSizes[i].y + 5) / 10; - pNamesBuffer[(i+1)*64-1] = '\0'; // make very long names zero terminated - aInfo.m_aPaperName = pNamesBuffer + (i*64); + PaperInfo aInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10); m_aPaperFormats.push_back( aInfo ); } rtl_freeMemory( pNamesBuffer ); @@ -1299,11 +1546,7 @@ void WinSalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData ) ImplDeviceCaps( this, DC_PAPERNAMES, (BYTE*)pNamesBuffer, pSetupData ); for( DWORD i = 0; i < nCount; ++i ) { - vcl::PaperInfo aInfo; - aInfo.m_nPaperWidth = (pPaperSizes[i].x + 5) / 10; - aInfo.m_nPaperHeight = (pPaperSizes[i].y + 5) / 10; - pNamesBuffer[(i+1)*64-1] = '\0'; // make very long names zero terminated - aInfo.m_aPaperName = ImplSalGetUniString( (const char*)(pNamesBuffer + (i*64)) ); + PaperInfo aInfo(pPaperSizes[i].x * 10, pPaperSizes[i].y * 10); m_aPaperFormats.push_back( aInfo ); } rtl_freeMemory( pNamesBuffer ); diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index 8d9347e7e352..2d335808e4c1 100755..100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -71,6 +71,17 @@ typedef std::hash_map<int,int> IntMap; typedef std::set<int> IntSet; +// Graphite headers +#ifdef ENABLE_GRAPHITE +#include <i18npool/mslangid.hxx> +#include <graphite/GrClient.h> +#include <graphite/WinFont.h> +#include <graphite/Segment.h> +#include <vcl/graphite_layout.hxx> +#include <vcl/graphite_cache.hxx> +#include <vcl/graphite_features.hxx> +#endif + #define DROPPED_OUTGLYPH 0xFFFF using namespace rtl; @@ -1757,6 +1768,8 @@ bool UniscribeLayout::GetItemSubrange( const VisualItem& rVisualItem, if( nMaxGlyphPos < n ) nMaxGlyphPos = n; } + if (nMaxGlyphPos > rVisualItem.mnEndGlyphPos) + nMaxGlyphPos = rVisualItem.mnEndGlyphPos - 1; // extend the glyph range to account for all glyphs in referenced clusters if( !rVisualItem.IsRTL() ) // LTR-item @@ -2041,11 +2054,25 @@ void UniscribeLayout::MoveGlyph( int nStartx8, long nNewXPos ) long nDelta = nNewXPos - pVI->mnXOffset; if( nStart > nMinGlyphPos ) { - // move the glyph by expanding its left glyph - int i; + // move the glyph by expanding its left glyph but ignore dropped glyphs + int i, nLastUndropped = nMinGlyphPos - 1; for( i = nMinGlyphPos; i < nStart; ++i ) - nDelta -= mpGlyphAdvances[ i ]; - mpGlyphAdvances[ i-1 ] += nDelta; + { + if (mpOutGlyphs[i] != DROPPED_OUTGLYPH) + { + nDelta -= (mpJustifications)? mpJustifications[ i ] : mpGlyphAdvances[ i ]; + nLastUndropped = i; + } + } + if (nLastUndropped >= nMinGlyphPos) + { + mpGlyphAdvances[ nLastUndropped ] += nDelta; + if (mpJustifications) mpJustifications[ nLastUndropped ] += nDelta; + } + else + { + pVI->mnXOffset += nDelta; + } } else { @@ -2066,11 +2093,18 @@ void UniscribeLayout::DropGlyph( int nStartx8 ) --nStart; else // nStart<=0 for first visible glyph { - const VisualItem* pVI = mpVisualItems; + VisualItem* pVI = mpVisualItems; for( int i = mnItemCount, nDummy; --i >= 0; ++pVI ) if( GetItemSubrange( *pVI, nStart, nDummy ) ) break; DBG_ASSERT( nStart <= mnGlyphCount, "USPLayout::DropG overflow" ); + int nOffset = 0; + int j = pVI->mnMinGlyphPos; + while (mpOutGlyphs[j] == DROPPED_OUTGLYPH) j++; + if (j == nStart) + { + pVI->mnXOffset += ((mpJustifications)? mpJustifications[nStart] : mpGlyphAdvances[nStart]); + } } mpOutGlyphs[ nStart ] = DROPPED_OUTGLYPH; @@ -2127,11 +2161,12 @@ void UniscribeLayout::Simplify( bool /*bIsBase*/ ) } // handle dropped glyphs at start of visual item - int nEndGlyphPos; - GetItemSubrange( rVI, i, nEndGlyphPos ); + int nMinGlyphPos, nEndGlyphPos, nOrigMinGlyphPos = rVI.mnMinGlyphPos; + GetItemSubrange( rVI, nMinGlyphPos, nEndGlyphPos ); + i = nMinGlyphPos; while( (mpOutGlyphs[i] == cDroppedGlyph) && (i < nEndGlyphPos) ) { - rVI.mnXOffset += pGlyphWidths[ i ]; + //rVI.mnXOffset += pGlyphWidths[ i ]; rVI.mnMinGlyphPos = ++i; } @@ -2141,6 +2176,17 @@ void UniscribeLayout::Simplify( bool /*bIsBase*/ ) rVI.mnEndGlyphPos = 0; continue; } + // If there are still glyphs in the cluster and mnMinGlyphPos + // has changed then we need to remove the dropped glyphs at start + // to correct logClusters, which is unsigned and relative to the + // item start. + if (rVI.mnMinGlyphPos != nOrigMinGlyphPos) + { + // drop any glyphs in the visual item outside the range + for (i = nOrigMinGlyphPos; i < nMinGlyphPos; i++) + mpOutGlyphs[ i ] = cDroppedGlyph; + rVI.mnMinGlyphPos = i = nOrigMinGlyphPos; + } // handle dropped glyphs in the middle of visual item for(; i < nEndGlyphPos; ++i ) @@ -2157,9 +2203,10 @@ void UniscribeLayout::Simplify( bool /*bIsBase*/ ) mpGlyphAdvances[ j ] = mpGlyphAdvances[ i ]; if( mpJustifications ) mpJustifications[ j ] = mpJustifications[ i ]; - int k = mpGlyphs2Chars[ i ]; + const int k = mpGlyphs2Chars[ i ]; mpGlyphs2Chars[ j ] = k; - mpLogClusters[ k ] = sal::static_int_cast<WORD>(j++); + const int nRelGlyphPos = (j++) - rVI.mnMinGlyphPos; + mpLogClusters[ k ] = static_cast<WORD>(nRelGlyphPos); } rVI.mnEndGlyphPos = j; @@ -2751,6 +2798,234 @@ bool UniscribeLayout::IsKashidaPosValid ( int nCharPos ) const #endif // USE_UNISCRIBE +#ifdef ENABLE_GRAPHITE + +class GraphiteLayoutWinImpl : public GraphiteLayout +{ +public: + GraphiteLayoutWinImpl(const gr::Font & font, ImplWinFontEntry & rFont) + throw() + : GraphiteLayout(font), mrFont(rFont) {}; + virtual ~GraphiteLayoutWinImpl() throw() {}; + virtual sal_GlyphId getKashidaGlyph(int & rWidth); +private: + ImplWinFontEntry & mrFont; +}; + +sal_GlyphId GraphiteLayoutWinImpl::getKashidaGlyph(int & rWidth) +{ + rWidth = mrFont.GetMinKashidaWidth(); + return mrFont.GetMinKashidaGlyph(); +} + +// This class uses the SIL Graphite engine to provide complex text layout services to the VCL +// @author tse +// +class GraphiteWinLayout : public WinLayout +{ +private: + mutable gr::WinFont mpFont; + grutils::GrFeatureParser * mpFeatures; + mutable GraphiteLayoutWinImpl maImpl; +public: + GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE); + + static bool IsGraphiteEnabledFont(HDC hDC) throw(); + + // used by upper layers + virtual bool LayoutText( ImplLayoutArgs& ); // first step of layout + virtual void AdjustLayout( ImplLayoutArgs& ); // adjusting after fallback etc. + // virtual void InitFont() const; + virtual void DrawText( SalGraphics& ) const; + + // methods using string indexing + virtual int GetTextBreak( long nMaxWidth, long nCharExtra=0, int nFactor=1 ) const; + virtual long FillDXArray( long* pDXArray ) const; + + virtual void GetCaretPositions( int nArraySize, long* pCaretXArray ) const; + + // methods using glyph indexing + virtual int GetNextGlyphs(int nLen, sal_GlyphId* pGlyphIdxAry, ::Point & rPos, int&, + long* pGlyphAdvAry = 0, int* pCharPosAry = 0 ) const; + + // used by glyph+font+script fallback + virtual void MoveGlyph( int nStart, long nNewXPos ); + virtual void DropGlyph( int nStart ); + virtual void Simplify( bool bIsBase ); + ~GraphiteWinLayout() { delete mpFeatures; mpFeatures = NULL; }; +protected: + virtual void ReplaceDC(gr::Segment & segment) const; + virtual void RestoreDC(gr::Segment & segment) const; +}; + +bool GraphiteWinLayout::IsGraphiteEnabledFont(HDC hDC) throw() +{ + return gr::WinFont::FontHasGraphiteTables(hDC); +} + +GraphiteWinLayout::GraphiteWinLayout(HDC hDC, const ImplWinFontData& rWFD, ImplWinFontEntry& rWFE) throw() + : WinLayout(hDC, rWFD, rWFE), mpFont(hDC), + maImpl(mpFont, rWFE) +{ + const rtl::OString aLang = MsLangId::convertLanguageToIsoByteString( rWFE.maFontSelData.meLanguage ); + rtl::OString name = rtl::OUStringToOString( + rWFE.maFontSelData.maTargetName, RTL_TEXTENCODING_UTF8 ); + sal_Int32 nFeat = name.indexOf(grutils::GrFeatureParser::FEAT_PREFIX) + 1; + if (nFeat > 0) + { + rtl::OString aFeat = name.copy(nFeat, name.getLength() - nFeat); + mpFeatures = new grutils::GrFeatureParser(mpFont, aFeat.getStr(), aLang.getStr()); + } + else + { + mpFeatures = new grutils::GrFeatureParser(mpFont, aLang.getStr()); + } + maImpl.SetFeatures(mpFeatures); +} + +void GraphiteWinLayout::ReplaceDC(gr::Segment & segment) const +{ + COLORREF color = GetTextColor(mhDC); + dynamic_cast<gr::WinFont&>(segment.getFont()).replaceDC(mhDC); + SetTextColor(mhDC, color); +} + +void GraphiteWinLayout::RestoreDC(gr::Segment & segment) const +{ + dynamic_cast<gr::WinFont&>(segment.getFont()).restoreDC(); +} + +bool GraphiteWinLayout::LayoutText( ImplLayoutArgs & args) +{ + HFONT hUnRotatedFont; + if (args.mnOrientation) + { + // Graphite gets very confused if the font is rotated + LOGFONTW aLogFont; + ::GetObjectW( mhFont, sizeof(LOGFONTW), &aLogFont); + aLogFont.lfEscapement = 0; + aLogFont.lfOrientation = 0; + hUnRotatedFont = ::CreateFontIndirectW( &aLogFont); + ::SelectFont(mhDC, hUnRotatedFont); + } + WinLayout::AdjustLayout(args); + mpFont.replaceDC(mhDC); + maImpl.SetFontScale(WinLayout::mfFontScale); + //bool succeeded = maImpl.LayoutText(args); +#ifdef GRCACHE + GrSegRecord * pSegRecord = NULL; + gr::Segment * pSegment = maImpl.CreateSegment(args, &pSegRecord); +#else + gr::Segment * pSegment = maImpl.CreateSegment(args); +#endif + bool bSucceeded = false; + if (pSegment) + { + // replace the DC on the font within the segment + ReplaceDC(*pSegment); + // create glyph vectors +#ifdef GRCACHE + bSucceeded = maImpl.LayoutGlyphs(args, pSegment, pSegRecord); +#else + bSucceeded = maImpl.LayoutGlyphs(args, pSegment); +#endif + // restore original DC + RestoreDC(*pSegment); +#ifdef GRCACHE + if (pSegRecord) pSegRecord->unlock(); + else delete pSegment; +#else + delete pSegment; +#endif + } + mpFont.restoreDC(); + if (args.mnOrientation) + { + // restore the rotated font + ::SelectFont(mhDC, mhFont); + ::DeleteObject(hUnRotatedFont); + } + return bSucceeded; +} + +void GraphiteWinLayout::AdjustLayout(ImplLayoutArgs& rArgs) +{ + WinLayout::AdjustLayout(rArgs); + maImpl.DrawBase() = WinLayout::maDrawBase; + maImpl.DrawOffset() = WinLayout::maDrawOffset; + if ( (rArgs.mnFlags & SAL_LAYOUT_BIDI_RTL) && rArgs.mpDXArray) + { + mrWinFontEntry.InitKashidaHandling(mhDC); + } + maImpl.AdjustLayout(rArgs); +} + +void GraphiteWinLayout::DrawText(SalGraphics &sal_graphics) const +{ + HFONT hOrigFont = DisableFontScaling(); + HDC aHDC = static_cast<WinSalGraphics&>(sal_graphics).mhDC; + maImpl.DrawBase() = WinLayout::maDrawBase; + maImpl.DrawOffset() = WinLayout::maDrawOffset; + const int MAX_GLYPHS = 2; + sal_GlyphId glyphIntStr[MAX_GLYPHS]; + WORD glyphWStr[MAX_GLYPHS]; + int glyphIndex = 0; + Point aPos(0,0); + int nGlyphs = 0; + do + { + nGlyphs = maImpl.GetNextGlyphs(1, glyphIntStr, aPos, glyphIndex); + if (nGlyphs < 1) + break; + std::copy(glyphIntStr, glyphIntStr + nGlyphs, glyphWStr); + ::ExtTextOutW(aHDC, aPos.X(), aPos.Y(), ETO_GLYPH_INDEX, + NULL, (LPCWSTR)&(glyphWStr), nGlyphs, NULL); + } while (nGlyphs); + if( hOrigFont ) + DeleteFont( SelectFont( mhDC, hOrigFont ) ); +} + +int GraphiteWinLayout::GetTextBreak( long nMaxWidth, long nCharExtra, int nFactor ) const +{ + mpFont.replaceDC(mhDC); + int nBreak = maImpl.GetTextBreak(nMaxWidth, nCharExtra, nFactor); + mpFont.restoreDC(); + return nBreak; +} + +long GraphiteWinLayout::FillDXArray( long* pDXArray ) const +{ + return maImpl.FillDXArray(pDXArray); +} + +void GraphiteWinLayout::GetCaretPositions( int nArraySize, long* pCaretXArray ) const +{ + maImpl.GetCaretPositions(nArraySize, pCaretXArray); +} + +int GraphiteWinLayout::GetNextGlyphs( int length, sal_GlyphId* glyph_out, + ::Point & pos_out, int &glyph_slot, long * glyph_adv, int *char_index) const +{ + maImpl.DrawBase() = WinLayout::maDrawBase; + maImpl.DrawOffset() = WinLayout::maDrawOffset; + return maImpl.GetNextGlyphs(length, glyph_out, pos_out, glyph_slot, glyph_adv, char_index); +} + +void GraphiteWinLayout::MoveGlyph( int glyph_idx, long new_x_pos ) +{ + maImpl.MoveGlyph(glyph_idx, new_x_pos); +} + +void GraphiteWinLayout::DropGlyph( int glyph_idx ) +{ + maImpl.DropGlyph(glyph_idx); +} + +void GraphiteWinLayout::Simplify( bool is_base ) +{ + maImpl.Simplify(is_base); +} +#endif // ENABLE_GRAPHITE // ======================================================================= SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLevel ) @@ -2766,6 +3041,11 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe if( !(rArgs.mnFlags & SAL_LAYOUT_COMPLEX_DISABLED) && (aUspModule || (bUspEnabled && InitUSP())) ) // CTL layout engine { +#ifdef ENABLE_GRAPHITE + if (rFontFace.SupportsGraphite()) + pWinLayout = new GraphiteWinLayout(mhDC, rFontFace, rFontInstance); + else +#endif // ENABLE_GRAPHITE // script complexity is determined in upper layers pWinLayout = new UniscribeLayout( mhDC, rFontFace, rFontInstance ); // NOTE: it must be guaranteed that the WinSalGraphics lives longer than @@ -2788,7 +3068,12 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe BYTE eCharSet = ANSI_CHARSET; if( mpLogFont ) eCharSet = mpLogFont->lfCharSet; - pWinLayout = new SimpleWinLayout( mhDC, eCharSet, rFontFace, rFontInstance ); +#ifdef ENABLE_GRAPHITE + if (rFontFace.SupportsGraphite()) + pWinLayout = new GraphiteWinLayout(mhDC, rFontFace, rFontInstance); + else +#endif // ENABLE_GRAPHITE + pWinLayout = new SimpleWinLayout( mhDC, eCharSet, rFontFace, rFontInstance ); } if( mfFontScale != 1.0 ) diff --git a/vcl/win/source/window/MAKEFILE.MK b/vcl/win/source/window/MAKEFILE.MK index 9a65a5000ccf..67cb1bf3e080 100644 --- a/vcl/win/source/window/MAKEFILE.MK +++ b/vcl/win/source/window/MAKEFILE.MK @@ -43,7 +43,7 @@ ENABLE_EXCEPTIONS=TRUE # --- #105371# .IF "$(COM)"=="GCC" -CDEFS += -UWINVER -DWINVER=0x0400 -D_WIN32_WINNT=0x0501 +CFLAGS += -D_WIN32_WINNT=0x0501 .ELSE CFLAGS += -DWINVER=0x0400 -D_WIN32_WINNT=0x0501 @@ -60,6 +60,10 @@ SLOFILES= \ EXCEPTIONSFILES= $(SLO)$/salframe.obj .ENDIF +.IF "$(ENABLE_GRAPHITE)" == "TRUE" +CFLAGS+=-DENABLE_GRAPHITE +.ENDIF + # --- Targets ------------------------------------------------------ .INCLUDE : target.mk diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index 57ad272bcf51..3ffc358bd76d 100644 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -6,9 +6,6 @@ * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: salframe.cxx,v $ - * $Revision: 1.157.20.2 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -355,11 +352,9 @@ SalFrame* ImplSalCreateFrame( WinSalInstance* pInst, { OUString aLibraryName( RTL_CONSTASCII_USTRINGPARAM( "user32" ) ); oslModule pLib = osl_loadModule( aLibraryName.pData, SAL_LOADMODULE_DEFAULT ); - void *pFunc = NULL; + oslGenericFunction pFunc = NULL; if( pLib ) - { pFunc = osl_getAsciiFunctionSymbol( pLib, "SetLayeredWindowAttributes" ); - } lpfnSetLayeredWindowAttributes = ( SetLayeredWindowAttributes_Proc_T ) pFunc; @@ -3155,7 +3150,8 @@ void WinSalFrame::Beep( SoundType eSoundType ) MB_ICONQUESTION // SOUND_QUERY }; - MessageBeep( aImplSoundTab[eSoundType] ); + if( eSoundType != SOUND_DISABLE ) // don't beep on disable + MessageBeep( aImplSoundTab[eSoundType] ); } // ----------------------------------------------------------------------- diff --git a/vcl/workben/makefile.mk b/vcl/workben/makefile.mk index 83abbbf4e6bf..34316356a1a6 100644 --- a/vcl/workben/makefile.mk +++ b/vcl/workben/makefile.mk @@ -125,6 +125,7 @@ APP5OBJS= $(OBJ)$/svpclient.obj APP5STDLIBS= $(CPPULIB) \ $(CPPUHELPERLIB) \ $(COMPHELPERLIB) \ + $(UCBHELPERLIB) \ $(VCLLIB) \ $(TOOLSLIB) \ $(SALLIB) \ diff --git a/vcl/workben/svpclient.cxx b/vcl/workben/svpclient.cxx index cf64d58110e8..7bea0b94f76a 100644 --- a/vcl/workben/svpclient.cxx +++ b/vcl/workben/svpclient.cxx @@ -50,6 +50,8 @@ #include <comphelper/processfactory.hxx> #include <cppuhelper/servicefactory.hxx> #include <cppuhelper/bootstrap.hxx> +#include "ucbhelper/contentbroker.hxx" +#include "ucbhelper/configurationkeys.hxx" #include <errno.h> #include <unistd.h> @@ -60,6 +62,8 @@ using namespace rtl; +using namespace cppu; +using namespace comphelper; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; // ----------------------------------------------------------------------- @@ -73,10 +77,47 @@ SAL_IMPLEMENT_MAIN() { tools::extendApplicationEnvironment(); - Reference< XMultiServiceFactory > xMS; - xMS = cppu::createRegistryServiceFactory( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "applicat.rdb" ) ), sal_True ); + //------------------------------------------------- + // create the global service-manager + //------------------------------------------------- + Reference< XMultiServiceFactory > xFactory; + try + { + Reference< XComponentContext > xCtx = defaultBootstrap_InitialComponentContext(); + xFactory = Reference< XMultiServiceFactory >( xCtx->getServiceManager(), UNO_QUERY ); + if( xFactory.is() ) + setProcessServiceFactory( xFactory ); + } + catch( com::sun::star::uno::Exception& rExc) + { + } + + if( ! xFactory.is() ) + { + fprintf( stderr, "Could not bootstrap UNO, installation must be in disorder. Exiting.\n" ); + exit( 1 ); + } + + /* + * Create UCB. + */ + Sequence< Any > aArgs( 2 ); + aArgs[ 0 ] <<= OUString::createFromAscii( UCB_CONFIGURATION_KEY1_LOCAL ); + aArgs[ 1 ] <<= OUString::createFromAscii( UCB_CONFIGURATION_KEY2_OFFICE ); +#if OSL_DEBUG_LEVEL > 1 + sal_Bool bSuccess = +#endif + ::ucbhelper::ContentBroker::initialize( xFactory, aArgs ); + +#if OSL_DEBUG_LEVEL > 1 + if ( !bSuccess ) + { + fprintf( stderr, "Error creating UCB, installation must be in disorder. Exiting.\n" ); + exit( 1 ); + } +#endif - InitVCL( xMS ); + InitVCL( xFactory ); ::Main(); DeInitVCL(); |