diff options
Diffstat (limited to 'vcl/win/gdi')
-rw-r--r-- | vcl/win/gdi/DWriteTextRenderer.cxx | 22 | ||||
-rw-r--r-- | vcl/win/gdi/gdiimpl.cxx | 769 | ||||
-rw-r--r-- | vcl/win/gdi/salbmp.cxx | 357 | ||||
-rw-r--r-- | vcl/win/gdi/salfont.cxx | 103 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi.cxx | 707 | ||||
-rw-r--r-- | vcl/win/gdi/salgdi2.cxx | 10 | ||||
-rw-r--r-- | vcl/win/gdi/salnativewidgets-luna.cxx | 11 | ||||
-rw-r--r-- | vcl/win/gdi/salprn.cxx | 310 | ||||
-rw-r--r-- | vcl/win/gdi/salvd.cxx | 101 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 36 |
10 files changed, 892 insertions, 1534 deletions
diff --git a/vcl/win/gdi/DWriteTextRenderer.cxx b/vcl/win/gdi/DWriteTextRenderer.cxx index cb3c1ba4c060..15441a8389e1 100644 --- a/vcl/win/gdi/DWriteTextRenderer.cxx +++ b/vcl/win/gdi/DWriteTextRenderer.cxx @@ -269,19 +269,19 @@ IDWriteFontFace* D2DWriteTextOutRenderer::GetDWriteFace(const WinFontInstance& r float* lfSize) const { auto pFontFace = rWinFont.GetDWFontFace(); - if (pFontFace) - { - LOGFONTW aLogFont; - HFONT hFont = rWinFont.GetHFONT(); + if (!pFontFace) + return nullptr; - GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont); - float dpix, dpiy; - mpRT->GetDpi(&dpix, &dpiy); - *lfSize = aLogFont.lfHeight * 96.0f / dpiy; + LOGFONTW aLogFont; + HFONT hFont = rWinFont.GetHFONT(); - assert(*lfSize < 0); - *lfSize *= -1; - } + GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont); + float dpix, dpiy; + mpRT->GetDpi(&dpix, &dpiy); + *lfSize = aLogFont.lfHeight * 96.0f / dpiy; + + assert(*lfSize < 0); + *lfSize *= -1; return pFontFace; } diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx index e72414f70abb..eb4ab2c18972 100644 --- a/vcl/win/gdi/gdiimpl.cxx +++ b/vcl/win/gdi/gdiimpl.cxx @@ -67,8 +67,7 @@ namespace { // #100127# Fill point and flag memory from array of points which // might also contain bezier control points for the PolyDraw() GDI method // Make sure pWinPointAry and pWinFlagAry are big enough -void ImplPreparePolyDraw( bool bCloseFigures, - sal_uLong nPoly, +void ImplPreparePolyDraw( sal_uLong nPoly, const sal_uInt32* pPoints, const Point* const* pPtAry, const PolyFlags* const* pFlgAry, @@ -133,9 +132,8 @@ void ImplPreparePolyDraw( bool bCloseFigures, ++nCurrPoint; } - // end figure? - if( bCloseFigures ) - pWinFlagAry[-1] |= PT_CLOSEFIGURE; + // end figure + pWinFlagAry[-1] |= PT_CLOSEFIGURE; } } } @@ -150,62 +148,6 @@ Color ImplGetROPColor( SalROPColor nROPColor ) return nColor; } -bool IsDitherColor(BYTE nRed, BYTE nGreen, BYTE nBlue) -{ - constexpr sal_uInt8 DITHER_PAL_DELTA = 51; - - return !(nRed % DITHER_PAL_DELTA) && - !(nGreen % DITHER_PAL_DELTA) && - !(nBlue % DITHER_PAL_DELTA); -} - -bool IsPaletteColor(BYTE nRed, BYTE nGreen, BYTE nBlue) -{ - static const PALETTEENTRY aImplSalSysPalEntryAry[] = - { - { 0, 0, 0, 0 }, - { 0, 0, 0x80, 0 }, - { 0, 0x80, 0, 0 }, - { 0, 0x80, 0x80, 0 }, - { 0x80, 0, 0, 0 }, - { 0x80, 0, 0x80, 0 }, - { 0x80, 0x80, 0, 0 }, - { 0x80, 0x80, 0x80, 0 }, - { 0xC0, 0xC0, 0xC0, 0 }, - { 0, 0, 0xFF, 0 }, - { 0, 0xFF, 0, 0 }, - { 0, 0xFF, 0xFF, 0 }, - { 0xFF, 0, 0, 0 }, - { 0xFF, 0, 0xFF, 0 }, - { 0xFF, 0xFF, 0, 0 }, - { 0xFF, 0xFF, 0xFF, 0 } - }; - - for (const auto& rPalEntry : aImplSalSysPalEntryAry) - { - if(rPalEntry.peRed == nRed && - rPalEntry.peGreen == nGreen && - rPalEntry.peBlue == nBlue) - { - return true; - } - } - - return false; -} - -bool IsExtraColor(BYTE nRed, BYTE nGreen, BYTE nBlue) -{ - return (nRed == 0) && (nGreen == 184) && (nBlue == 255); -} - -bool ImplIsPaletteEntry(BYTE nRed, BYTE nGreen, BYTE nBlue) -{ - return IsDitherColor(nRed, nGreen, nBlue) || - IsPaletteColor(nRed, nGreen, nBlue) || - IsExtraColor(nRed, nGreen, nBlue); -} - } // namespace WinSalGraphicsImpl::WinSalGraphicsImpl(WinSalGraphics& rParent): @@ -514,102 +456,101 @@ namespace { void ImplDrawBitmap( HDC hDC, const SalTwoRect& rPosAry, const WinSalBitmap& rSalBitmap, bool bPrinter, int nDrawMode ) { - if( hDC ) - { - HGLOBAL hDrawDIB; - HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB(); - std::optional<WinSalBitmap> xTmpSalBmp; - bool bPrintDDB = ( bPrinter && hDrawDDB ); + if( !hDC ) + return; - if( bPrintDDB ) - { - xTmpSalBmp.emplace(); - xTmpSalBmp->Create(rSalBitmap, vcl::bitDepthToPixelFormat(rSalBitmap.GetBitCount())); - hDrawDIB = xTmpSalBmp->ImplGethDIB(); - } - else - hDrawDIB = rSalBitmap.ImplGethDIB(); + HGLOBAL hDrawDIB; + HBITMAP hDrawDDB = rSalBitmap.ImplGethDDB(); + std::optional<WinSalBitmap> xTmpSalBmp; + bool bPrintDDB = ( bPrinter && hDrawDDB ); - if( hDrawDIB ) + if( bPrintDDB ) + { + xTmpSalBmp.emplace(); + xTmpSalBmp->Create(rSalBitmap, vcl::bitDepthToPixelFormat(rSalBitmap.GetBitCount())); + hDrawDIB = xTmpSalBmp->ImplGethDIB(); + } + else + hDrawDIB = rSalBitmap.ImplGethDIB(); + + if( hDrawDIB ) + { + if (PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( hDrawDIB ))) { - if (PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( hDrawDIB ))) - { - PBYTE pBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + - WinSalBitmap::ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD ); - const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); - - int nHeight = -pBI->bmiHeader.biHeight; // height is negative for top-down bitmap - StretchDIBits( hDC, - static_cast<int>(rPosAry.mnDestX), static_cast<int>(rPosAry.mnDestY), - static_cast<int>(rPosAry.mnDestWidth), static_cast<int>(rPosAry.mnDestHeight), - static_cast<int>(rPosAry.mnSrcX), static_cast<int>(nHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY), - static_cast<int>(rPosAry.mnSrcWidth), static_cast<int>(rPosAry.mnSrcHeight), - pBits, pBI, DIB_RGB_COLORS, nDrawMode ); - - GlobalUnlock( hDrawDIB ); - SetStretchBltMode( hDC, nOldStretchMode ); - } + PBYTE pBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + + WinSalBitmap::ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGBQUAD ); + const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); + + StretchDIBits( hDC, + static_cast<int>(rPosAry.mnDestX), static_cast<int>(rPosAry.mnDestY), + static_cast<int>(rPosAry.mnDestWidth), static_cast<int>(rPosAry.mnDestHeight), + static_cast<int>(rPosAry.mnSrcX), static_cast<int>(pBI->bmiHeader.biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY), + static_cast<int>(rPosAry.mnSrcWidth), static_cast<int>(rPosAry.mnSrcHeight), + pBits, pBI, DIB_RGB_COLORS, nDrawMode ); + + GlobalUnlock( hDrawDIB ); + SetStretchBltMode( hDC, nOldStretchMode ); } - else if( hDrawDDB && !bPrintDDB ) - { - ScopedCachedHDC<CACHED_HDC_DRAW> hBmpDC(hDrawDDB); + } + else if( hDrawDDB && !bPrintDDB ) + { + ScopedCachedHDC<CACHED_HDC_DRAW> hBmpDC(hDrawDDB); - COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF); - COLORREF nOldTextColor = RGB(0,0,0); - bool bMono = ( rSalBitmap.GetBitCount() == 1 ); + COLORREF nOldBkColor = RGB(0xFF,0xFF,0xFF); + COLORREF nOldTextColor = RGB(0,0,0); + bool bMono = ( rSalBitmap.GetBitCount() == 1 ); - if( bMono ) + if( bMono ) + { + COLORREF nBkColor = RGB( 0xFF, 0xFF, 0xFF ); + COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 ); + //fdo#33455 handle 1 bit depth pngs with palette entries + //to set fore/back colors + if (BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(BitmapAccessMode::Info)) { - COLORREF nBkColor = RGB( 0xFF, 0xFF, 0xFF ); - COLORREF nTextColor = RGB( 0x00, 0x00, 0x00 ); - //fdo#33455 handle 1 bit depth pngs with palette entries - //to set fore/back colors - if (BitmapBuffer* pBitmapBuffer = const_cast<WinSalBitmap&>(rSalBitmap).AcquireBuffer(BitmapAccessMode::Info)) + const BitmapPalette& rPalette = pBitmapBuffer->maPalette; + if (rPalette.GetEntryCount() == 2) { - const BitmapPalette& rPalette = pBitmapBuffer->maPalette; - if (rPalette.GetEntryCount() == 2) - { - Color nCol = rPalette[0]; - nTextColor = RGB( nCol.GetRed(), nCol.GetGreen(), nCol.GetBlue() ); - nCol = rPalette[1]; - nBkColor = RGB( nCol.GetRed(), nCol.GetGreen(), nCol.GetBlue() ); - } - const_cast<WinSalBitmap&>(rSalBitmap).ReleaseBuffer(pBitmapBuffer, BitmapAccessMode::Info); + Color nCol = rPalette[0]; + nTextColor = RGB( nCol.GetRed(), nCol.GetGreen(), nCol.GetBlue() ); + nCol = rPalette[1]; + nBkColor = RGB( nCol.GetRed(), nCol.GetGreen(), nCol.GetBlue() ); } - nOldBkColor = SetBkColor( hDC, nBkColor ); - nOldTextColor = ::SetTextColor( hDC, nTextColor ); + const_cast<WinSalBitmap&>(rSalBitmap).ReleaseBuffer(pBitmapBuffer, BitmapAccessMode::Info); } + nOldBkColor = SetBkColor( hDC, nBkColor ); + nOldTextColor = ::SetTextColor( hDC, nTextColor ); + } - if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && - (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) - { - BitBlt( hDC, + if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && + (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) + { + BitBlt( hDC, + static_cast<int>(rPosAry.mnDestX), static_cast<int>(rPosAry.mnDestY), + static_cast<int>(rPosAry.mnDestWidth), static_cast<int>(rPosAry.mnDestHeight), + hBmpDC.get(), + static_cast<int>(rPosAry.mnSrcX), static_cast<int>(rPosAry.mnSrcY), + nDrawMode ); + } + else + { + const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); + + StretchBlt( hDC, static_cast<int>(rPosAry.mnDestX), static_cast<int>(rPosAry.mnDestY), static_cast<int>(rPosAry.mnDestWidth), static_cast<int>(rPosAry.mnDestHeight), hBmpDC.get(), static_cast<int>(rPosAry.mnSrcX), static_cast<int>(rPosAry.mnSrcY), + static_cast<int>(rPosAry.mnSrcWidth), static_cast<int>(rPosAry.mnSrcHeight), nDrawMode ); - } - else - { - const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); - - StretchBlt( hDC, - static_cast<int>(rPosAry.mnDestX), static_cast<int>(rPosAry.mnDestY), - static_cast<int>(rPosAry.mnDestWidth), static_cast<int>(rPosAry.mnDestHeight), - hBmpDC.get(), - static_cast<int>(rPosAry.mnSrcX), static_cast<int>(rPosAry.mnSrcY), - static_cast<int>(rPosAry.mnSrcWidth), static_cast<int>(rPosAry.mnSrcHeight), - nDrawMode ); - SetStretchBltMode( hDC, nOldStretchMode ); - } + SetStretchBltMode( hDC, nOldStretchMode ); + } - if( bMono ) - { - SetBkColor( hDC, nOldBkColor ); - ::SetTextColor( hDC, nOldTextColor ); - } + if( bMono ) + { + SetBkColor( hDC, nOldBkColor ); + ::SetTextColor( hDC, nOldTextColor ); } } } @@ -770,10 +711,10 @@ void WinSalGraphicsImpl::drawMask(const SalTwoRect& rPosAry, WinSalBitmap aTmp; if( aTmp.Create( rSalBitmap, &mrParent ) ) - ImplDrawBitmap( hDC, aPosAry, aTmp, false, 0x00B8074AUL ); + ImplDrawBitmap( hDC, aPosAry, aTmp, false, 0x00B8074AUL ); // raster operation PSDPxax } else - ImplDrawBitmap( hDC, aPosAry, rSalBitmap, false, 0x00B8074AUL ); + ImplDrawBitmap( hDC, aPosAry, rSalBitmap, false, 0x00B8074AUL );// raster operation PSDPxax } std::shared_ptr<SalBitmap> WinSalGraphicsImpl::getBitmap( tools::Long nX, tools::Long nY, tools::Long nDX, tools::Long nDY ) @@ -909,17 +850,10 @@ void WinSalGraphicsImpl::invert( sal_uInt32 nPoints, const Point* pPtAry, SalInv for (sal_uInt32 i=0; i<nPoints; ++i) pWinPtAry[i] = POINT { static_cast<LONG>(pPtAry[i].getX()), static_cast<LONG>(pPtAry[i].getY()) }; - // for Windows 95 and its maximum number of points if ( nSalFlags & SalInvert::TrackFrame ) - { - if ( !Polyline( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( mrParent.getHDC(), pWinPtAry.get(), MAX_64KSALPOINTS ); - } + Polyline( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ); else - { - if ( !Polygon( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ) && (nPoints > MAX_64KSALPOINTS) ) - Polygon( mrParent.getHDC(), pWinPtAry.get(), MAX_64KSALPOINTS ); - } + Polygon( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ); SetROP2( mrParent.getHDC(), nOldROP ); SelectPen( mrParent.getHDC(), hOldPen ); @@ -940,24 +874,20 @@ sal_uInt16 WinSalGraphicsImpl::GetBitCount() const tools::Long WinSalGraphicsImpl::GetGraphicsWidth() const { - if( mrParent.gethWnd() && IsWindow( mrParent.gethWnd() ) ) - { - WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() ); - if( pFrame ) - { - if (pFrame->GetWidth()) - return pFrame->GetWidth(); - else - { - // TODO: perhaps not needed, width should always be up-to-date - RECT aRect; - GetClientRect( mrParent.gethWnd(), &aRect ); - return aRect.right; - } - } - } + if( !mrParent.gethWnd() || !IsWindow( mrParent.gethWnd() ) ) + return 0; + + WinSalFrame* pFrame = GetWindowPtr( mrParent.gethWnd() ); + if( !pFrame ) + return 0; + + if (pFrame->GetWidth()) + return pFrame->GetWidth(); - return 0; + // TODO: perhaps not needed, width should always be up-to-date + RECT aRect; + GetClientRect( mrParent.gethWnd(), &aRect ); + return aRect.right; } void WinSalGraphicsImpl::ResetClipRegion() @@ -974,16 +904,12 @@ void WinSalGraphicsImpl::ResetClipRegion() static bool containsOnlyHorizontalAndVerticalEdges(const basegfx::B2DPolygon& rCandidate) { if(rCandidate.areControlPointsUsed()) - { return false; - } const sal_uInt32 nPointCount(rCandidate.count()); if(nPointCount < 2) - { return true; - } const sal_uInt32 nEdgeCount(rCandidate.isClosed() ? nPointCount + 1 : nPointCount); basegfx::B2DPoint aLast(rCandidate.getB2DPoint(0)); @@ -1007,9 +933,7 @@ static bool containsOnlyHorizontalAndVerticalEdges(const basegfx::B2DPolygon& rC static bool containsOnlyHorizontalAndVerticalEdges(const basegfx::B2DPolyPolygon& rCandidate) { if(rCandidate.areControlPointsUsed()) - { return false; - } for(auto const& rPolygon : rCandidate) { @@ -1299,15 +1223,15 @@ void WinSalGraphicsImpl::SetLineColor(Color nColor) HPEN WinSalGraphicsImpl::SearchStockPen(COLORREF nPenColor) { // Only screen, because printer has problems, when we use stock objects. - if (!mrParent.isPrinter()) - { - const SalData* pSalData = GetSalData(); + if (mrParent.isPrinter()) + return nullptr; - for (sal_uInt16 i = 0; i < pSalData->mnStockPenCount; i++) - { - if (nPenColor == pSalData->maStockPenColorAry[i]) - return pSalData->mhStockPenAry[i]; - } + const SalData* pSalData = GetSalData(); + + for (sal_uInt16 i = 0; i < pSalData->mnStockPenCount; i++) + { + if (nPenColor == pSalData->maStockPenColorAry[i]) + return pSalData->mhStockPenAry[i]; } return nullptr; @@ -1315,17 +1239,9 @@ HPEN WinSalGraphicsImpl::SearchStockPen(COLORREF nPenColor) HPEN WinSalGraphicsImpl::MakePen(Color nColor) { - COLORREF nPenColor = PALETTERGB(nColor.GetRed(), - nColor.GetGreen(), - nColor.GetBlue()); - - if (!mrParent.isPrinter()) - { - if (GetSalData()->mhDitherPal && ImplIsSysColorEntry(nColor)) - { - nPenColor = PALRGB_TO_RGB(nPenColor); - } - } + COLORREF nPenColor = RGB(nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue()); return CreatePen(PS_SOLID, mrParent.mnPenWidth, nPenColor); } @@ -1397,112 +1313,14 @@ HBRUSH WinSalGraphicsImpl::SearchStockBrush(COLORREF nBrushColor) return nullptr; } -namespace -{ - -BYTE GetDitherMappingValue(BYTE nVal, BYTE nThres, const SalData* pSalData) -{ - return (pSalData->mpDitherDiff[nVal] > nThres) ? - pSalData->mpDitherHigh[nVal] : pSalData->mpDitherLow[nVal]; -} - -HBRUSH Make16BitDIBPatternBrush(Color nColor) -{ - const SalData* pSalData = GetSalData(); - - const BYTE nRed = nColor.GetRed(); - const BYTE nGreen = nColor.GetGreen(); - const BYTE nBlue = nColor.GetBlue(); - - static const BYTE aOrdDither16Bit[8][8] = - { - { 0, 6, 1, 7, 0, 6, 1, 7 }, - { 4, 2, 5, 3, 4, 2, 5, 3 }, - { 1, 7, 0, 6, 1, 7, 0, 6 }, - { 5, 3, 4, 2, 5, 3, 4, 2 }, - { 0, 6, 1, 7, 0, 6, 1, 7 }, - { 4, 2, 5, 3, 4, 2, 5, 3 }, - { 1, 7, 0, 6, 1, 7, 0, 6 }, - { 5, 3, 4, 2, 5, 3, 4, 2 } - }; - - BYTE* pTmp = pSalData->mpDitherDIBData; - - for(int nY = 0; nY < 8; ++nY) - { - for(int nX = 0; nX < 8; ++nX) - { - const BYTE nThres = aOrdDither16Bit[nY][nX]; - *pTmp++ = GetDitherMappingValue(nBlue, nThres, pSalData); - *pTmp++ = GetDitherMappingValue(nGreen, nThres, pSalData); - *pTmp++ = GetDitherMappingValue(nRed, nThres, pSalData); - } - } - - return CreateDIBPatternBrush(pSalData->mhDitherDIB, DIB_RGB_COLORS); -} - -HBRUSH Make8BitDIBPatternBrush(Color nColor) -{ - const SalData* pSalData = GetSalData(); - - const BYTE nRed = nColor.GetRed(); - const BYTE nGreen = nColor.GetGreen(); - const BYTE nBlue = nColor.GetBlue(); - - static const BYTE aOrdDither8Bit[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 } - }; - - BYTE* pTmp = pSalData->mpDitherDIBData; - - for (int nY = 0; nY < 8; ++nY) - { - for (int nX = 0; nX < 8; ++nX) - { - const BYTE nThres = aOrdDither8Bit[nY][nX]; - *pTmp = GetDitherMappingValue(nRed, nThres, pSalData) + - GetDitherMappingValue(nGreen, nThres, pSalData) * 6 + - GetDitherMappingValue(nBlue, nThres, pSalData) * 36; - pTmp++; - } - } - - return CreateDIBPatternBrush(pSalData->mhDitherDIB, DIB_PAL_COLORS); -} - -} // namespace - HBRUSH WinSalGraphicsImpl::MakeBrush(Color nColor) { - const SalData* pSalData = GetSalData(); - const BYTE nRed = nColor.GetRed(); const BYTE nGreen = nColor.GetGreen(); const BYTE nBlue = nColor.GetBlue(); - const COLORREF nBrushColor = PALETTERGB(nRed, nGreen, nBlue); - - if (mrParent.isPrinter() || !pSalData->mhDitherDIB) - return CreateSolidBrush(nBrushColor); + const COLORREF nBrushColor = RGB(nRed, nGreen, nBlue); - if (24 == reinterpret_cast<BITMAPINFOHEADER*>(pSalData->mpDitherDIB)->biBitCount) - return Make16BitDIBPatternBrush(nColor); - - if (ImplIsSysColorEntry(nColor)) - return CreateSolidBrush(PALRGB_TO_RGB(nBrushColor)); - - if (ImplIsPaletteEntry(nRed, nGreen, nBlue)) - return CreateSolidBrush(nBrushColor); - - return Make8BitDIBPatternBrush(nColor); + return CreateSolidBrush(nBrushColor); } void WinSalGraphicsImpl::ResetBrush(HBRUSH hNewBrush) @@ -1561,14 +1379,9 @@ void WinSalGraphicsImpl::drawPixel( tools::Long nX, tools::Long nY ) void WinSalGraphicsImpl::drawPixel( tools::Long nX, tools::Long nY, Color nColor ) { - COLORREF nCol = PALETTERGB( nColor.GetRed(), - nColor.GetGreen(), - nColor.GetBlue() ); - - if ( !mrParent.isPrinter() && - GetSalData()->mhDitherPal && - ImplIsSysColorEntry( nColor ) ) - nCol = PALRGB_TO_RGB( nCol ); + COLORREF nCol = RGB( nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue() ); DrawPixelImpl( nX, nY, nCol ); } @@ -1613,9 +1426,7 @@ void WinSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const Point* pPtAry ) for (sal_uInt32 i=0; i<nPoints; ++i) pWinPtAry[i] = POINT { static_cast<LONG>(pPtAry[i].getX()), static_cast<LONG>(pPtAry[i].getY()) }; - // for Windows 95 and its maximum number of points - if ( !Polyline( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( mrParent.getHDC(), pWinPtAry.get(), MAX_64KSALPOINTS ); + Polyline( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ); // Polyline seems to uses LineTo, which doesn't paint the last pixel (see 87eb8f8ee) if ( !mrParent.isPrinter() ) @@ -1628,9 +1439,7 @@ void WinSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const Point* pPtAry ) for (sal_uInt32 i=0; i<nPoints; ++i) pWinPtAry[i] = POINT { static_cast<LONG>(pPtAry[i].getX()), static_cast<LONG>(pPtAry[i].getY()) }; - // for Windows 95 and its maximum number of points - if ( !Polygon( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ) && (nPoints > MAX_64KSALPOINTS) ) - Polygon( mrParent.getHDC(), pWinPtAry.get(), MAX_64KSALPOINTS ); + Polygon( mrParent.getHDC(), pWinPtAry.get(), static_cast<int>(nPoints) ); } void WinSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, @@ -1671,25 +1480,7 @@ void WinSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pP n += nPoints; } - if ( !PolyPolygon( mrParent.getHDC(), pWinPointAryAry, reinterpret_cast<int*>(pWinPointAry), static_cast<UINT>(nPoly) ) && - (nPolyPolyPoints > MAX_64KSALPOINTS) ) - { - nPolyPolyPoints = 0; - nPoly = 0; - do - { - nPolyPolyPoints += pWinPointAry[static_cast<UINT>(nPoly)]; - nPoly++; - } - while ( nPolyPolyPoints < MAX_64KSALPOINTS ); - nPoly--; - if ( pWinPointAry[static_cast<UINT>(nPoly)] > MAX_64KSALPOINTS ) - pWinPointAry[static_cast<UINT>(nPoly)] = MAX_64KSALPOINTS; - if ( nPoly == 1 ) - Polygon( mrParent.getHDC(), pWinPointAryAry, *pWinPointAry ); - else - PolyPolygon( mrParent.getHDC(), pWinPointAryAry, reinterpret_cast<int*>(pWinPointAry), nPoly ); - } + PolyPolygon( mrParent.getHDC(), pWinPointAryAry, reinterpret_cast<int*>(pWinPointAry), static_cast<UINT>(nPoly) ); if ( pWinPointAry != aWinPointAry ) delete [] pWinPointAry; @@ -1756,7 +1547,7 @@ bool WinSalGraphicsImpl::drawPolygonBezier( sal_uInt32 nPoints, const Point* pPt } sal_uInt32 nPoints_i32(nPoints); - ImplPreparePolyDraw(true, 1, &nPoints_i32, &pPtAry, &pFlgAry, pWinPointAry, pWinFlagAry); + ImplPreparePolyDraw(1, &nPoints_i32, &pPtAry, &pFlgAry, pWinPointAry, pWinFlagAry); bool bRet( false ); @@ -1803,7 +1594,7 @@ bool WinSalGraphicsImpl::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt pWinFlagAry = aStackAry2; } - ImplPreparePolyDraw(true, nPoly, pPoints, pPtAry, pFlgAry, pWinPointAry, pWinFlagAry); + ImplPreparePolyDraw(nPoly, pPoints, pPtAry, pFlgAry, pWinPointAry, pWinFlagAry); bool bRet( false ); @@ -1877,78 +1668,76 @@ static void impAddB2DPolygonToGDIPlusGraphicsPathReal( bool bPixelSnapHairline) { sal_uInt32 nCount(rPolygon.count()); + if(nCount == 0) + return; + + const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1); + if(nEdgeCount == 0) + return; + + const bool bControls(rPolygon.areControlPointsUsed()); + basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0)); + basegfx::B2DHomMatrix aObjectToDeviceInv; + + if(bPixelSnapHairline) + { + aCurr = impPixelSnap(rPolygon, rObjectToDevice, aObjectToDeviceInv, 0); + } - if(nCount) + for(sal_uInt32 a(0); a < nEdgeCount; a++) { - const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1); + const sal_uInt32 nNextIndex((a + 1) % nCount); + basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex)); + const bool b1stControlPointUsed(bControls && rPolygon.isNextControlPointUsed(a)); + const bool b2ndControlPointUsed(bControls && rPolygon.isPrevControlPointUsed(nNextIndex)); - if(nEdgeCount) + if(bPixelSnapHairline) { - const bool bControls(rPolygon.areControlPointsUsed()); - basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0)); - basegfx::B2DHomMatrix aObjectToDeviceInv; + aNext = impPixelSnap(rPolygon, rObjectToDevice, aObjectToDeviceInv, nNextIndex); + } - if(bPixelSnapHairline) + if(b1stControlPointUsed || b2ndControlPointUsed) + { + basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a)); + basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex)); + + // tdf#99165 MS Gdiplus cannot handle creating correct extra geometry for fat lines + // with LineCap or LineJoin when a bezier segment starts or ends trivial, e.g. has + // no 1st or 2nd control point, despite that these are mathematically correct definitions + // (basegfx can handle that). + // Caution: This error (and it's correction) might be necessary for other graphical + // sub-systems in a similar way. + // tdf#101026 The 1st attempt to create a mathematically correct replacement control + // vector was wrong. Best alternative is one as close as possible which means short. + if(!b1stControlPointUsed) { - aCurr = impPixelSnap(rPolygon, rObjectToDevice, aObjectToDeviceInv, 0); + aCa = aCurr + ((aCb - aCurr) * 0.0005); } - - for(sal_uInt32 a(0); a < nEdgeCount; a++) + else if(!b2ndControlPointUsed) { - const sal_uInt32 nNextIndex((a + 1) % nCount); - basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex)); - const bool b1stControlPointUsed(bControls && rPolygon.isNextControlPointUsed(a)); - const bool b2ndControlPointUsed(bControls && rPolygon.isPrevControlPointUsed(nNextIndex)); - - if(bPixelSnapHairline) - { - aNext = impPixelSnap(rPolygon, rObjectToDevice, aObjectToDeviceInv, nNextIndex); - } - - if(b1stControlPointUsed || b2ndControlPointUsed) - { - basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a)); - basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex)); - - // tdf#99165 MS Gdiplus cannot handle creating correct extra geometry for fat lines - // with LineCap or LineJoin when a bezier segment starts or ends trivial, e.g. has - // no 1st or 2nd control point, despite that these are mathematically correct definitions - // (basegfx can handle that). - // Caution: This error (and it's correction) might be necessary for other graphical - // sub-systems in a similar way. - // tdf#101026 The 1st attempt to create a mathematically correct replacement control - // vector was wrong. Best alternative is one as close as possible which means short. - if(!b1stControlPointUsed) - { - aCa = aCurr + ((aCb - aCurr) * 0.0005); - } - else if(!b2ndControlPointUsed) - { - aCb = aNext + ((aCa - aNext) * 0.0005); - } + aCb = aNext + ((aCa - aNext) * 0.0005); + } - rGraphicsPath.AddBezier( - static_cast< Gdiplus::REAL >(aCurr.getX()), static_cast< Gdiplus::REAL >(aCurr.getY()), - static_cast< Gdiplus::REAL >(aCa.getX()), static_cast< Gdiplus::REAL >(aCa.getY()), - static_cast< Gdiplus::REAL >(aCb.getX()), static_cast< Gdiplus::REAL >(aCb.getY()), - static_cast< Gdiplus::REAL >(aNext.getX()), static_cast< Gdiplus::REAL >(aNext.getY())); - } - else - { - rGraphicsPath.AddLine( - static_cast< Gdiplus::REAL >(aCurr.getX()), static_cast< Gdiplus::REAL >(aCurr.getY()), - static_cast< Gdiplus::REAL >(aNext.getX()), static_cast< Gdiplus::REAL >(aNext.getY())); - } + rGraphicsPath.AddBezier( + static_cast< Gdiplus::REAL >(aCurr.getX()), static_cast< Gdiplus::REAL >(aCurr.getY()), + static_cast< Gdiplus::REAL >(aCa.getX()), static_cast< Gdiplus::REAL >(aCa.getY()), + static_cast< Gdiplus::REAL >(aCb.getX()), static_cast< Gdiplus::REAL >(aCb.getY()), + static_cast< Gdiplus::REAL >(aNext.getX()), static_cast< Gdiplus::REAL >(aNext.getY())); + } + else + { + rGraphicsPath.AddLine( + static_cast< Gdiplus::REAL >(aCurr.getX()), static_cast< Gdiplus::REAL >(aCurr.getY()), + static_cast< Gdiplus::REAL >(aNext.getX()), static_cast< Gdiplus::REAL >(aNext.getY())); + } - if(a + 1 < nEdgeCount) - { - aCurr = aNext; + if(a + 1 < nEdgeCount) + { + aCurr = aNext; - if(bNoLineJoin) - { - rGraphicsPath.StartFigure(); - } - } + if(bNoLineJoin) + { + rGraphicsPath.StartFigure(); } } } @@ -2004,17 +1793,17 @@ sal_Int64 SystemDependentData_GraphicsPath::estimateUsageInBytes() const { sal_Int64 nRetval(0); - if(mpGraphicsPath) - { - const INT nPointCount(mpGraphicsPath->GetPointCount()); + if(!mpGraphicsPath) + return 0; - if(0 != nPointCount) - { - // Each point has - // - 2 x sizeof(Gdiplus::REAL) - // - 1 byte (see GetPathTypes in docu) - nRetval = nPointCount * ((2 * sizeof(Gdiplus::REAL)) + 1); - } + const INT nPointCount(mpGraphicsPath->GetPointCount()); + + if(0 != nPointCount) + { + // Each point has + // - 2 x sizeof(Gdiplus::REAL) + // - 1 byte (see GetPathTypes in docu) + nRetval = nPointCount * ((2 * sizeof(Gdiplus::REAL)) + 1); } return nRetval; @@ -2033,8 +1822,8 @@ void WinSalGraphicsImpl::drawPolyPolygon( } Gdiplus::Graphics aGraphics(mrParent.getHDC()); - const sal_uInt8 aTrans(sal_uInt8(255) - static_cast<sal_uInt8>(basegfx::fround(fTransparency * 255.0))); - const Gdiplus::Color aTestColor(aTrans, maFillColor.GetRed(), maFillColor.GetGreen(), maFillColor.GetBlue()); + const sal_uInt8 nAlpha(sal_uInt8(255) - static_cast<sal_uInt8>(basegfx::fround(fTransparency * 255.0))); + const Gdiplus::Color aTestColor(nAlpha, maFillColor.GetRed(), maFillColor.GetGreen(), maFillColor.GetBlue()); const Gdiplus::SolidBrush aSolidBrush(aTestColor.GetValue()); // Set full (Object-to-Device) transformation - if used @@ -2211,8 +2000,8 @@ bool WinSalGraphicsImpl::drawPolyLine( } Gdiplus::Graphics aGraphics(mrParent.getHDC()); - const sal_uInt8 aTrans = static_cast<sal_uInt8>(basegfx::fround( 255 * (1.0 - fTransparency) )); - const Gdiplus::Color aTestColor(aTrans, maLineColor.GetRed(), maLineColor.GetGreen(), maLineColor.GetBlue()); + const sal_uInt8 nAlpha = static_cast<sal_uInt8>(basegfx::fround( 255 * (1.0 - fTransparency) )); + const Gdiplus::Color aTestColor(nAlpha, maLineColor.GetRed(), maLineColor.GetGreen(), maLineColor.GetBlue()); Gdiplus::Pen aPen(aTestColor.GetValue(), Gdiplus::REAL(fLineWidth)); bool bNoLineJoin(false); @@ -2533,34 +2322,32 @@ static void setInterpolationMode( bool WinSalGraphicsImpl::TryDrawBitmapGDIPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap) { - if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight) - { - assert(dynamic_cast<const WinSalBitmap*>(&rSrcBitmap)); + if(!rTR.mnSrcWidth || !rTR.mnSrcHeight || !rTR.mnDestWidth || !rTR.mnDestHeight) + return false; - const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); - std::shared_ptr< Gdiplus::Bitmap > aARGB(rSalBitmap.ImplGetGdiPlusBitmap()); + assert(dynamic_cast<const WinSalBitmap*>(&rSrcBitmap)); - if(aARGB) - { - Gdiplus::Graphics aGraphics(mrParent.getHDC()); + const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); + std::shared_ptr< Gdiplus::Bitmap > aARGB(rSalBitmap.ImplGetGdiPlusBitmap()); - setInterpolationMode( - aGraphics, - rTR.mnSrcWidth, - rTR.mnDestWidth, - rTR.mnSrcHeight, - rTR.mnDestHeight); + if(!aARGB) + return false; - paintToGdiPlus( - aGraphics, - rTR, - *aARGB); + Gdiplus::Graphics aGraphics(mrParent.getHDC()); - return true; - } - } + setInterpolationMode( + aGraphics, + rTR.mnSrcWidth, + rTR.mnDestWidth, + rTR.mnSrcHeight, + rTR.mnDestHeight); - return false; + paintToGdiPlus( + aGraphics, + rTR, + *aARGB); + + return true; } bool WinSalGraphicsImpl::blendBitmap( @@ -2584,36 +2371,34 @@ bool WinSalGraphicsImpl::drawAlphaBitmap( const SalBitmap& rSrcBitmap, const SalBitmap& rAlphaBmp) { - if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight) - { - assert(dynamic_cast<const WinSalBitmap*>(&rSrcBitmap)); - assert(dynamic_cast<const WinSalBitmap*>(&rAlphaBmp)); + if(!rTR.mnSrcWidth || !rTR.mnSrcHeight || !rTR.mnDestWidth || !rTR.mnDestHeight) + return false; - const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); - const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp); - std::shared_ptr< Gdiplus::Bitmap > aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha)); + assert(dynamic_cast<const WinSalBitmap*>(&rSrcBitmap)); + assert(dynamic_cast<const WinSalBitmap*>(&rAlphaBmp)); - if(aARGB) - { - Gdiplus::Graphics aGraphics(mrParent.getHDC()); + const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); + const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp); + std::shared_ptr< Gdiplus::Bitmap > aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha)); + + if(!aARGB) + return false; - setInterpolationMode( - aGraphics, - rTR.mnSrcWidth, - rTR.mnDestWidth, - rTR.mnSrcHeight, - rTR.mnDestHeight); + Gdiplus::Graphics aGraphics(mrParent.getHDC()); - paintToGdiPlus( - aGraphics, - rTR, - *aARGB); + setInterpolationMode( + aGraphics, + rTR.mnSrcWidth, + rTR.mnDestWidth, + rTR.mnSrcHeight, + rTR.mnDestHeight); - return true; - } - } + paintToGdiPlus( + aGraphics, + rTR, + *aARGB); - return false; + return true; } bool WinSalGraphicsImpl::drawTransformedBitmap( @@ -2634,56 +2419,54 @@ bool WinSalGraphicsImpl::drawTransformedBitmap( const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap); std::shared_ptr< Gdiplus::Bitmap > aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha)); - if(aARGB) - { - const tools::Long nSrcWidth(aARGB->GetWidth()); - const tools::Long nSrcHeight(aARGB->GetHeight()); + if(!aARGB) + return false; - if(nSrcWidth && nSrcHeight) - { - const tools::Long nDestWidth(basegfx::fround<tools::Long>(basegfx::B2DVector(rX - rNull).getLength())); - const tools::Long nDestHeight(basegfx::fround<tools::Long>(basegfx::B2DVector(rY - rNull).getLength())); + const tools::Long nSrcWidth(aARGB->GetWidth()); + const tools::Long nSrcHeight(aARGB->GetHeight()); - if(nDestWidth && nDestHeight) - { - Gdiplus::Graphics aGraphics(mrParent.getHDC()); - Gdiplus::PointF aDestPoints[3]; - Gdiplus::ImageAttributes aAttributes; - - setInterpolationMode( - aGraphics, - nSrcWidth, - nDestWidth, - nSrcHeight, - nDestHeight); - - // this mode is only capable of drawing the whole bitmap to a parallelogram - aDestPoints[0].X = Gdiplus::REAL(rNull.getX()); - aDestPoints[0].Y = Gdiplus::REAL(rNull.getY()); - aDestPoints[1].X = Gdiplus::REAL(rX.getX()); - aDestPoints[1].Y = Gdiplus::REAL(rX.getY()); - aDestPoints[2].X = Gdiplus::REAL(rY.getX()); - aDestPoints[2].Y = Gdiplus::REAL(rY.getY()); - - aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); - - aGraphics.DrawImage( - aARGB.get(), - aDestPoints, - 3, - Gdiplus::REAL(0.0), - Gdiplus::REAL(0.0), - Gdiplus::REAL(nSrcWidth), - Gdiplus::REAL(nSrcHeight), - Gdiplus::UnitPixel, - &aAttributes); - } - } + if(!nSrcWidth || !nSrcHeight) + return true; + + const tools::Long nDestWidth(basegfx::fround<tools::Long>(basegfx::B2DVector(rX - rNull).getLength())); + const tools::Long nDestHeight(basegfx::fround<tools::Long>(basegfx::B2DVector(rY - rNull).getLength())); + if(!nDestWidth || !nDestHeight) return true; - } - return false; + Gdiplus::Graphics aGraphics(mrParent.getHDC()); + Gdiplus::PointF aDestPoints[3]; + Gdiplus::ImageAttributes aAttributes; + + setInterpolationMode( + aGraphics, + nSrcWidth, + nDestWidth, + nSrcHeight, + nDestHeight); + + // this mode is only capable of drawing the whole bitmap to a parallelogram + aDestPoints[0].X = Gdiplus::REAL(rNull.getX()); + aDestPoints[0].Y = Gdiplus::REAL(rNull.getY()); + aDestPoints[1].X = Gdiplus::REAL(rX.getX()); + aDestPoints[1].Y = Gdiplus::REAL(rX.getY()); + aDestPoints[2].X = Gdiplus::REAL(rY.getX()); + aDestPoints[2].Y = Gdiplus::REAL(rY.getY()); + + aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); + + aGraphics.DrawImage( + aARGB.get(), + aDestPoints, + 3, + Gdiplus::REAL(0.0), + Gdiplus::REAL(0.0), + Gdiplus::REAL(nSrcWidth), + Gdiplus::REAL(nSrcHeight), + Gdiplus::UnitPixel, + &aAttributes); + + return true; } bool WinSalGraphicsImpl::hasFastDrawTransformedBitmap() const diff --git a/vcl/win/gdi/salbmp.cxx b/vcl/win/gdi/salbmp.cxx index 1008cb83da30..3d2a020896a2 100644 --- a/vcl/win/gdi/salbmp.cxx +++ b/vcl/win/gdi/salbmp.cxx @@ -21,7 +21,6 @@ #include <vcl/BitmapAccessMode.hxx> #include <vcl/BitmapBuffer.hxx> #include <vcl/BitmapPalette.hxx> -#include <vcl/ColorMask.hxx> #include <vcl/Scanline.hxx> #include <com/sun/star/beans/XFastPropertySet.hpp> #include <win/wincomp.hxx> @@ -104,52 +103,50 @@ SystemDependentData_GdiPlusBitmap::SystemDependentData_GdiPlusBitmap( sal_Int64 SystemDependentData_GdiPlusBitmap::estimateUsageInBytes() const { - sal_Int64 nRetval(0); + if(!mpGdiPlusBitmap) + return 0; - if(mpGdiPlusBitmap) - { - const UINT nWidth(mpGdiPlusBitmap->GetWidth()); - const UINT nHeight(mpGdiPlusBitmap->GetHeight()); + const UINT nWidth(mpGdiPlusBitmap->GetWidth()); + const UINT nHeight(mpGdiPlusBitmap->GetHeight()); - if(0 != nWidth && 0 != nHeight) - { - nRetval = nWidth * nHeight; + if(0 == nWidth || 0 == nHeight) + return 0; - switch(mpGdiPlusBitmap->GetPixelFormat()) - { - case PixelFormat1bppIndexed: - nRetval /= 8; - break; - case PixelFormat4bppIndexed: - nRetval /= 4; - break; - case PixelFormat16bppGrayScale: - case PixelFormat16bppRGB555: - case PixelFormat16bppRGB565: - case PixelFormat16bppARGB1555: - nRetval *= 2; - break; - case PixelFormat24bppRGB: - nRetval *= 3; - break; - case PixelFormat32bppRGB: - case PixelFormat32bppARGB: - case PixelFormat32bppPARGB: - case PixelFormat32bppCMYK: - nRetval *= 4; - break; - case PixelFormat48bppRGB: - nRetval *= 6; - break; - case PixelFormat64bppARGB: - case PixelFormat64bppPARGB: - nRetval *= 8; - break; - default: - case PixelFormat8bppIndexed: - break; - } - } + sal_Int64 nRetval = nWidth * nHeight; + + switch(mpGdiPlusBitmap->GetPixelFormat()) + { + case PixelFormat1bppIndexed: + nRetval /= 8; + break; + case PixelFormat4bppIndexed: + nRetval /= 4; + break; + case PixelFormat16bppGrayScale: + case PixelFormat16bppRGB555: + case PixelFormat16bppRGB565: + case PixelFormat16bppARGB1555: + nRetval *= 2; + break; + case PixelFormat24bppRGB: + nRetval *= 3; + break; + case PixelFormat32bppRGB: + case PixelFormat32bppARGB: + case PixelFormat32bppPARGB: + case PixelFormat32bppCMYK: + nRetval *= 4; + break; + case PixelFormat48bppRGB: + nRetval *= 6; + break; + case PixelFormat64bppARGB: + case PixelFormat64bppPARGB: + nRetval *= 8; + break; + default: + case PixelFormat8bppIndexed: + break; } return nRetval; @@ -251,6 +248,7 @@ std::shared_ptr<Gdiplus::Bitmap> WinSalBitmap::ImplCreateGdiPlusBitmap() { sal_uInt8* pSrcRGB(pRGB->mpBits); const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3)); + const bool bTopDown(pRGB->meDirection == ScanlineDirection::TopDown); const Gdiplus::Rect aAllRect(0, 0, nW, nH); Gdiplus::BitmapData aGdiPlusBitmapData; pRetval->LockBits(&aAllRect, Gdiplus::ImageLockModeWrite, PixelFormat24bppRGB, &aGdiPlusBitmapData); @@ -258,7 +256,8 @@ std::shared_ptr<Gdiplus::Bitmap> WinSalBitmap::ImplCreateGdiPlusBitmap() // copy data to Gdiplus::Bitmap; format is BGR here in both cases, so memcpy is possible for(sal_uInt32 y(0); y < nH; y++) { - sal_uInt8* targetPixels = static_cast<sal_uInt8*>(aGdiPlusBitmapData.Scan0) + (y * aGdiPlusBitmapData.Stride); + const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1); + sal_uInt8* targetPixels = static_cast<sal_uInt8*>(aGdiPlusBitmapData.Scan0) + (nYInsert * aGdiPlusBitmapData.Stride); memcpy(targetPixels, pSrcRGB, nW * 3); pSrcRGB += nW * 3 + nExtraRGB; @@ -335,13 +334,11 @@ std::shared_ptr<Gdiplus::Bitmap> WinSalBitmap::ImplCreateGdiPlusBitmap(const Win { // convert alpha bitmap to ScanlineFormat::N8BitPal format if not yet in that format SalTwoRect aSalTwoRect(0, 0, pA->mnWidth, pA->mnHeight, 0, 0, pA->mnWidth, pA->mnHeight); - const BitmapPalette& rTargetPalette = Bitmap::GetGreyPalette(256); pExtraA = StretchAndConvert( *pA, aSalTwoRect, - ScanlineFormat::N8BitPal, - rTargetPalette); + ScanlineFormat::N8BitPal); pSalA->ReleaseBuffer(pA, BitmapAccessMode::Read); pA = pExtraA ? &*pExtraA : nullptr; @@ -368,6 +365,7 @@ std::shared_ptr<Gdiplus::Bitmap> WinSalBitmap::ImplCreateGdiPlusBitmap(const Win sal_uInt8* pSrcA(pA->mpBits); const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3)); const sal_uInt32 nExtraA(pA->mnScanlineSize - nW); + const bool bTopDown(pRGB->meDirection == ScanlineDirection::TopDown); const Gdiplus::Rect aAllRect(0, 0, nW, nH); Gdiplus::BitmapData aGdiPlusBitmapData; pRetval->LockBits(&aAllRect, Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, &aGdiPlusBitmapData); @@ -376,7 +374,8 @@ std::shared_ptr<Gdiplus::Bitmap> WinSalBitmap::ImplCreateGdiPlusBitmap(const Win // A from alpha, so inner loop is needed (who invented BitmapEx..?) for(sal_uInt32 y(0); y < nH; y++) { - sal_uInt8* targetPixels = static_cast<sal_uInt8*>(aGdiPlusBitmapData.Scan0) + (y * aGdiPlusBitmapData.Stride); + const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1); + sal_uInt8* targetPixels = static_cast<sal_uInt8*>(aGdiPlusBitmapData.Scan0) + (nYInsert * aGdiPlusBitmapData.Stride); for(sal_uInt32 x(0); x < nW; x++) { @@ -468,29 +467,26 @@ bool WinSalBitmap::Create( const SalBitmap& rSSalBitmap ) assert(!mhDIB && "already created"); assert(!mhDDB && "already created"); - bool bRet = false; const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); - if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB ) - { - HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB, - rSalBitmap.mhDIB != nullptr ); + if ( !rSalBitmap.mhDIB && !rSalBitmap.mhDDB ) + return false; - if ( hNewHdl ) - { - if( rSalBitmap.mhDIB ) - mhDIB = static_cast<HGLOBAL>(hNewHdl); - else if( rSalBitmap.mhDDB ) - mhDDB = static_cast<HBITMAP>(hNewHdl); + HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB, + rSalBitmap.mhDIB != nullptr ); - maSize = rSalBitmap.maSize; - mnBitCount = rSalBitmap.mnBitCount; + if ( !hNewHdl ) + return false; - bRet = true; - } - } + if( rSalBitmap.mhDIB ) + mhDIB = static_cast<HGLOBAL>(hNewHdl); + else if( rSalBitmap.mhDDB ) + mhDDB = static_cast<HBITMAP>(hNewHdl); - return bRet; + maSize = rSalBitmap.maSize; + mnBitCount = rSalBitmap.mnBitCount; + + return true; } bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics ) @@ -510,21 +506,10 @@ bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics ) WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics); HDC hDC = pGraphics->getHDC(); - HBITMAP hNewDDB; BITMAP aDDBInfo; PBYTE pBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + - ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGBQUAD ); - - if( pBI->bmiHeader.biBitCount == 1 ) - { - int nHeight = -pBI->bmiHeader.biHeight; // height is negative for top-down bitmap - hNewDDB = CreateBitmap( pBI->bmiHeader.biWidth, nHeight, 1, 1, nullptr ); - - if( hNewDDB ) - SetDIBits( hDC, hNewDDB, 0, nHeight, pBits, pBI, DIB_RGB_COLORS ); - } - else - hNewDDB = CreateDIBitmap( hDC, &pBI->bmiHeader, CBM_INIT, pBits, pBI, DIB_RGB_COLORS ); + ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGBQUAD ); + HBITMAP hNewDDB = CreateDIBitmap( hDC, &pBI->bmiHeader, CBM_INIT, pBits, pBI, DIB_RGB_COLORS ); GlobalUnlock( rSalBmp.mhDIB ); @@ -547,54 +532,43 @@ bool WinSalBitmap::Create(const SalBitmap& rSSalBmp, vcl::PixelFormat eNewPixelF assert(!mhDIB && "already created"); assert(!mhDDB && "already created"); - bool bRet = false; - const WinSalBitmap& rSalBmp = static_cast<const WinSalBitmap&>(rSSalBmp); assert( rSalBmp.mhDDB && "why copy an empty WinSalBitmap"); - if( rSalBmp.mhDDB ) - { - mhDIB = ImplCreateDIB( rSalBmp.maSize, eNewPixelFormat, BitmapPalette() ); + if( !rSalBmp.mhDDB ) + return false; - if( mhDIB ) - { - if (PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( mhDIB ))) - { - const int nLines = static_cast<int>(rSalBmp.maSize.Height()); - HDC hDC = GetDC( nullptr ); - PBYTE pBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + - ImplGetDIBColorCount( mhDIB ) * sizeof( RGBQUAD ); - SalData* pSalData = GetSalData(); - HPALETTE hOldPal = nullptr; - - if ( pSalData->mhDitherPal ) - { - hOldPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); - RealizePalette( hDC ); - } + mhDIB = ImplCreateDIB( rSalBmp.maSize, eNewPixelFormat, BitmapPalette() ); - if( GetDIBits( hDC, rSalBmp.mhDDB, 0, nLines, pBits, pBI, DIB_RGB_COLORS ) == nLines ) - { - GlobalUnlock( mhDIB ); - maSize = rSalBmp.maSize; - mnBitCount = vcl::pixelFormatBitCount(eNewPixelFormat); - bRet = true; - } - else - { - GlobalUnlock( mhDIB ); - GlobalFree( mhDIB ); - mhDIB = nullptr; - } + if( !mhDIB ) + return false; - if( hOldPal ) - SelectPalette( hDC, hOldPal, TRUE ); + PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( mhDIB )); + if (!pBI) + return false; - ReleaseDC( nullptr, hDC ); - } - } + bool bRet = false; + const int nLines = static_cast<int>(rSalBmp.maSize.Height()); + HDC hDC = GetDC( nullptr ); + PBYTE pBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + + ImplGetDIBColorCount( mhDIB ) * sizeof( RGBQUAD ); + + if( GetDIBits( hDC, rSalBmp.mhDDB, 0, nLines, pBits, pBI, DIB_RGB_COLORS ) == nLines ) + { + GlobalUnlock( mhDIB ); + maSize = rSalBmp.maSize; + mnBitCount = vcl::pixelFormatBitCount(eNewPixelFormat); + bRet = true; } + else + { + GlobalUnlock( mhDIB ); + GlobalFree( mhDIB ); + mhDIB = nullptr; + } + + ReleaseDC( nullptr, hDC ); return bRet; } @@ -605,20 +579,18 @@ bool WinSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCan xFastPropertySet( rBitmapCanvas, css::uno::UNO_QUERY ); assert( xFastPropertySet && "creating without an xFastPropertySet?"); + if( !xFastPropertySet ) + return false; - if( xFastPropertySet ) - { - css::uno::Sequence< css::uno::Any > args; + css::uno::Sequence< css::uno::Any > args; + if( !(xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args) ) + return false; - if( xFastPropertySet->getFastPropertyValue(bMask ? 2 : 1) >>= args ) { - sal_Int64 aHBmp64; + sal_Int64 aHBmp64; + if( !(args[0] >>= aHBmp64) ) + return false; - if( args[0] >>= aHBmp64 ) { - return Create( reinterpret_cast<HBITMAP>(aHBmp64) ); - } - } - } - return false; + return Create( reinterpret_cast<HBITMAP>(aHBmp64) ); } sal_uInt16 WinSalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB ) @@ -626,26 +598,25 @@ sal_uInt16 WinSalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB ) if (!hDIB) return 0; - sal_uInt16 nColors = 0; + PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( hDIB )); + if (!pBI) + return 0; - if (PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( hDIB ))) + sal_uInt16 nColors = 0; + if ( pBI->bmiHeader.biSize != sizeof( BITMAPCOREHEADER ) ) { - - if ( pBI->bmiHeader.biSize != sizeof( BITMAPCOREHEADER ) ) + if( pBI->bmiHeader.biBitCount <= 8 ) { - if( pBI->bmiHeader.biBitCount <= 8 ) - { - if ( pBI->bmiHeader.biClrUsed ) - nColors = static_cast<sal_uInt16>(pBI->bmiHeader.biClrUsed); - else - nColors = 1 << pBI->bmiHeader.biBitCount; - } + if ( pBI->bmiHeader.biClrUsed ) + nColors = static_cast<sal_uInt16>(pBI->bmiHeader.biClrUsed); + else + nColors = 1 << pBI->bmiHeader.biBitCount; } - else if( reinterpret_cast<PBITMAPCOREHEADER>(pBI)->bcBitCount <= 8 ) - nColors = 1 << reinterpret_cast<PBITMAPCOREHEADER>(pBI)->bcBitCount; - - GlobalUnlock( hDIB ); } + else if( reinterpret_cast<PBITMAPCOREHEADER>(pBI)->bcBitCount <= 8 ) + nColors = 1 << reinterpret_cast<PBITMAPCOREHEADER>(pBI)->bcBitCount; + + GlobalUnlock( hDIB ); return nColors; } @@ -688,7 +659,7 @@ HGLOBAL WinSalBitmap::ImplCreateDIB(const Size& rSize, vcl::PixelFormat ePixelFo pBIH->biSize = sizeof( BITMAPINFOHEADER ); pBIH->biWidth = rSize.Width(); - pBIH->biHeight = -rSize.Height(); // negative for top-down bitmap + pBIH->biHeight = rSize.Height(); pBIH->biPlanes = 1; pBIH->biBitCount = nBits; pBIH->biCompression = BI_RGB; @@ -760,87 +731,49 @@ BitmapBuffer* WinSalBitmap::AcquireBuffer( BitmapAccessMode /*nMode*/ ) if (!mhDIB) return nullptr; + PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( mhDIB )); + if (!pBI) + return nullptr; + std::unique_ptr<BitmapBuffer> pBuffer; + PBITMAPINFOHEADER pBIH = &pBI->bmiHeader; - if (PBITMAPINFO pBI = static_cast<PBITMAPINFO>(GlobalLock( mhDIB ))) + if( pBIH->biPlanes == 1 ) { - PBITMAPINFOHEADER pBIH = &pBI->bmiHeader; + pBuffer.reset(new BitmapBuffer); - if( pBIH->biPlanes == 1 ) - { - pBuffer.reset(new BitmapBuffer); + pBuffer->meFormat = pBIH->biBitCount == 8 ? ScanlineFormat::N8BitPal : + pBIH->biBitCount == 24 ? ScanlineFormat::N24BitTcBgr : + pBIH->biBitCount == 32 ? ScanlineFormat::N32BitTcBgrx : + ScanlineFormat::NONE; + assert (pBuffer->meFormat != ScanlineFormat::NONE); - pBuffer->meFormat = pBIH->biBitCount == 1 ? ScanlineFormat::N1BitMsbPal : - pBIH->biBitCount == 8 ? ScanlineFormat::N8BitPal : - pBIH->biBitCount == 24 ? ScanlineFormat::N24BitTcBgr : - pBIH->biBitCount == 32 ? ScanlineFormat::N32BitTcMask : - ScanlineFormat::NONE; + if (pBuffer->meFormat != ScanlineFormat::NONE) + { + pBuffer->mnWidth = maSize.Width(); + pBuffer->mnHeight = maSize.Height(); + pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->biBitCount ); + pBuffer->mnBitCount = static_cast<sal_uInt16>(pBIH->biBitCount); - if (pBuffer->meFormat != ScanlineFormat::NONE) + if( pBuffer->mnBitCount <= 8 ) { - pBuffer->mnWidth = maSize.Width(); - pBuffer->mnHeight = maSize.Height(); - pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->biBitCount ); - pBuffer->mnBitCount = static_cast<sal_uInt16>(pBIH->biBitCount); + const sal_uInt16 nPalCount = ImplGetDIBColorCount( mhDIB ); - if( pBuffer->mnBitCount <= 8 ) - { - const sal_uInt16 nPalCount = ImplGetDIBColorCount( mhDIB ); - - pBuffer->maPalette.SetEntryCount( nPalCount ); - memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->bmiColors, nPalCount * sizeof( RGBQUAD ) ); - pBuffer->mpBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + nPalCount * sizeof( RGBQUAD ); - } - else if( ( pBIH->biBitCount == 16 ) || ( pBIH->biBitCount == 32 ) ) - { - sal_uLong nOffset = 0; - - if( pBIH->biCompression == BI_BITFIELDS ) - { - nOffset = 3 * sizeof( RGBQUAD ); - ColorMaskElement aRedMask(*reinterpret_cast<UINT32*>(&pBI->bmiColors[ 0 ])); - aRedMask.CalcMaskShift(); - ColorMaskElement aGreenMask(*reinterpret_cast<UINT32*>(&pBI->bmiColors[ 1 ])); - aGreenMask.CalcMaskShift(); - ColorMaskElement aBlueMask(*reinterpret_cast<UINT32*>(&pBI->bmiColors[ 2 ])); - aBlueMask.CalcMaskShift(); - pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); - } - else if( pBIH->biBitCount == 16 ) - { - ColorMaskElement aRedMask(0x00007c00UL); - aRedMask.CalcMaskShift(); - ColorMaskElement aGreenMask(0x000003e0UL); - aGreenMask.CalcMaskShift(); - ColorMaskElement aBlueMask(0x0000001fUL); - aBlueMask.CalcMaskShift(); - pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); - } - else - { - ColorMaskElement aRedMask(0x00ff0000UL); - aRedMask.CalcMaskShift(); - ColorMaskElement aGreenMask(0x0000ff00UL); - aGreenMask.CalcMaskShift(); - ColorMaskElement aBlueMask(0x000000ffUL); - aBlueMask.CalcMaskShift(); - pBuffer->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask); - } - - pBuffer->mpBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + nOffset; - } - else - pBuffer->mpBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize; + pBuffer->maPalette.SetEntryCount( nPalCount ); + memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->bmiColors, nPalCount * sizeof( RGBQUAD ) ); + pBuffer->mpBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize + nPalCount * sizeof( RGBQUAD ); } else - { - GlobalUnlock( mhDIB ); - pBuffer.reset(); - } + pBuffer->mpBits = reinterpret_cast<PBYTE>(pBI) + pBI->bmiHeader.biSize; } else + { GlobalUnlock( mhDIB ); + pBuffer.reset(); + } } + else + GlobalUnlock( mhDIB ); return pBuffer.release(); } diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 06a90a361f18..518b7136aa1d 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -473,38 +473,38 @@ static FontAttributes WinFont2DevFontAttributes( const ENUMLOGFONTEXW& rEnumFont void ImplSalLogFontToFontW( HDC hDC, const LOGFONTW& rLogFont, Font& rFont ) { OUString aFontName( o3tl::toU(rLogFont.lfFaceName) ); - if (!aFontName.isEmpty()) - { - rFont.SetFamilyName( aFontName ); - rFont.SetCharSet( ImplCharSetToSal( rLogFont.lfCharSet ) ); - rFont.SetFamily( ImplFamilyToSal( rLogFont.lfPitchAndFamily ) ); - rFont.SetPitch( ImplLogPitchToSal( rLogFont.lfPitchAndFamily ) ); - rFont.SetWeight( ImplWeightToSal( rLogFont.lfWeight ) ); - - tools::Long nFontHeight = rLogFont.lfHeight; - if ( nFontHeight < 0 ) - nFontHeight = -nFontHeight; - tools::Long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY ); - if( !nDPIY ) - nDPIY = 600; - nFontHeight *= 72; - nFontHeight += nDPIY/2; - nFontHeight /= nDPIY; - rFont.SetFontSize( Size( 0, nFontHeight ) ); - rFont.SetOrientation( Degree10(static_cast<sal_Int16>(rLogFont.lfEscapement)) ); - if ( rLogFont.lfItalic ) - rFont.SetItalic( ITALIC_NORMAL ); - else - rFont.SetItalic( ITALIC_NONE ); - if ( rLogFont.lfUnderline ) - rFont.SetUnderline( LINESTYLE_SINGLE ); - else - rFont.SetUnderline( LINESTYLE_NONE ); - if ( rLogFont.lfStrikeOut ) - rFont.SetStrikeout( STRIKEOUT_SINGLE ); - else - rFont.SetStrikeout( STRIKEOUT_NONE ); - } + if (aFontName.isEmpty()) + return; + + rFont.SetFamilyName( aFontName ); + rFont.SetCharSet( ImplCharSetToSal( rLogFont.lfCharSet ) ); + rFont.SetFamily( ImplFamilyToSal( rLogFont.lfPitchAndFamily ) ); + rFont.SetPitch( ImplLogPitchToSal( rLogFont.lfPitchAndFamily ) ); + rFont.SetWeight( ImplWeightToSal( rLogFont.lfWeight ) ); + + tools::Long nFontHeight = rLogFont.lfHeight; + if ( nFontHeight < 0 ) + nFontHeight = -nFontHeight; + tools::Long nDPIY = GetDeviceCaps( hDC, LOGPIXELSY ); + if( !nDPIY ) + nDPIY = 600; + nFontHeight *= 72; + nFontHeight += nDPIY/2; + nFontHeight /= nDPIY; + rFont.SetFontSize( Size( 0, nFontHeight ) ); + rFont.SetOrientation( Degree10(static_cast<sal_Int16>(rLogFont.lfEscapement)) ); + if ( rLogFont.lfItalic ) + rFont.SetItalic( ITALIC_NORMAL ); + else + rFont.SetItalic( ITALIC_NONE ); + if ( rLogFont.lfUnderline ) + rFont.SetUnderline( LINESTYLE_SINGLE ); + else + rFont.SetUnderline( LINESTYLE_NONE ); + if ( rLogFont.lfStrikeOut ) + rFont.SetStrikeout( STRIKEOUT_SINGLE ); + else + rFont.SetStrikeout( STRIKEOUT_NONE ); } WinFontFace::WinFontFace(const ENUMLOGFONTEXW& rEnumFont, const NEWTEXTMETRICW& rMetric) @@ -648,16 +648,9 @@ hb_blob_t* WinFontFace::GetHbTable(hb_tag_t nTag) const void WinSalGraphics::SetTextColor( Color nColor ) { - COLORREF aCol = PALETTERGB( nColor.GetRed(), - nColor.GetGreen(), - nColor.GetBlue() ); - - if( !mbPrinter && - GetSalData()->mhDitherPal && - ImplIsSysColorEntry( nColor ) ) - { - aCol = PALRGB_TO_RGB( aCol ); - } + COLORREF aCol = RGB( nColor.GetRed(), + nColor.GetGreen(), + nColor.GetBlue() ); ::SetTextColor( getHDC(), aCol ); } @@ -923,20 +916,20 @@ static int lcl_AddFontResource(SalData& rSalData, const OUString& rFontFileURL, int nRet = AddFontResourceExW(o3tl::toW(aFontSystemPath.getStr()), FR_PRIVATE, nullptr); SAL_WARN_IF(nRet <= 0, "vcl.fonts", "AddFontResourceExW failed for " << rFontFileURL); - if (nRet > 0) + if (nRet <= 0) + return nRet; + + TempFontItem* pNewItem = new TempFontItem; + pNewItem->maFontResourcePath = aFontSystemPath; + if (bShared) { - TempFontItem* pNewItem = new TempFontItem; - pNewItem->maFontResourcePath = aFontSystemPath; - if (bShared) - { - pNewItem->mpNextItem = rSalData.mpSharedTempFontItem; - rSalData.mpSharedTempFontItem = pNewItem; - } - else - { - pNewItem->mpNextItem = rSalData.mpOtherTempFontItem; - rSalData.mpOtherTempFontItem = pNewItem; - } + pNewItem->mpNextItem = rSalData.mpSharedTempFontItem; + rSalData.mpSharedTempFontItem = pNewItem; + } + else + { + pNewItem->mpNextItem = rSalData.mpOtherTempFontItem; + rSalData.mpOtherTempFontItem = pNewItem; } return nRet; } diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx index 1040810975c6..634bbb078e38 100644 --- a/vcl/win/gdi/salgdi.cxx +++ b/vcl/win/gdi/salgdi.cxx @@ -43,65 +43,6 @@ #endif -#define DITHER_PAL_DELTA 51 -#define DITHER_PAL_STEPS 6 -#define DITHER_PAL_COUNT (DITHER_PAL_STEPS*DITHER_PAL_STEPS*DITHER_PAL_STEPS) -#define DITHER_MAX_SYSCOLOR 16 -#define DITHER_EXTRA_COLORS 1 - -namespace -{ - -struct SysColorEntry -{ - DWORD nRGB; - SysColorEntry* pNext; -}; - -SysColorEntry* pFirstSysColor = nullptr; -SysColorEntry* pActSysColor = nullptr; - -void DeleteSysColorList() -{ - SysColorEntry* pEntry = pFirstSysColor; - pActSysColor = pFirstSysColor = nullptr; - - while( pEntry ) - { - SysColorEntry* pTmp = pEntry->pNext; - delete pEntry; - pEntry = pTmp; - } -} - -} // namespace - -// Blue7 -static PALETTEENTRY aImplExtraColor1 = -{ - 0, 184, 255, 0 -}; - -static PALETTEENTRY aImplSalSysPalEntryAry[ DITHER_MAX_SYSCOLOR ] = -{ -{ 0, 0, 0, 0 }, -{ 0, 0, 0x80, 0 }, -{ 0, 0x80, 0, 0 }, -{ 0, 0x80, 0x80, 0 }, -{ 0x80, 0, 0, 0 }, -{ 0x80, 0, 0x80, 0 }, -{ 0x80, 0x80, 0, 0 }, -{ 0x80, 0x80, 0x80, 0 }, -{ 0xC0, 0xC0, 0xC0, 0 }, -{ 0, 0, 0xFF, 0 }, -{ 0, 0xFF, 0, 0 }, -{ 0, 0xFF, 0xFF, 0 }, -{ 0xFF, 0, 0, 0 }, -{ 0xFF, 0, 0xFF, 0 }, -{ 0xFF, 0xFF, 0, 0 }, -{ 0xFF, 0xFF, 0xFF, 0 } -}; - // we must create pens with 1-pixel width; otherwise the S3-graphics card // map has many paint problems when drawing polygons/polyLines and a // complex is set @@ -137,152 +78,6 @@ void ImplInitSalGDI() // initialize temporary font lists pSalData->mpSharedTempFontItem = nullptr; pSalData->mpOtherTempFontItem = nullptr; - - // support palettes for 256 color displays - HDC hDC = GetDC( nullptr ); - int nBitsPixel = GetDeviceCaps( hDC, BITSPIXEL ); - int nPlanes = GetDeviceCaps( hDC, PLANES ); - int nRasterCaps = GetDeviceCaps( hDC, RASTERCAPS ); - int nBitCount = nBitsPixel * nPlanes; - - if ( (nBitCount > 8) && (nBitCount < 24) ) - { - // test if we have to dither - HDC hMemDC = ::CreateCompatibleDC( hDC ); - HBITMAP hMemBmp = ::CreateCompatibleBitmap( hDC, 8, 8 ); - HBITMAP hBmpOld = static_cast<HBITMAP>(::SelectObject( hMemDC, hMemBmp )); - HBRUSH hMemBrush = ::CreateSolidBrush( PALETTERGB( 175, 171, 169 ) ); - HBRUSH hBrushOld = static_cast<HBRUSH>(::SelectObject( hMemDC, hMemBrush )); - bool bDither16 = true; - - ::PatBlt( hMemDC, 0, 0, 8, 8, PATCOPY ); - const COLORREF aCol( ::GetPixel( hMemDC, 0, 0 ) ); - - for( int nY = 0; ( nY < 8 ) && bDither16; nY++ ) - for( int nX = 0; ( nX < 8 ) && bDither16; nX++ ) - if( ::GetPixel( hMemDC, nX, nY ) != aCol ) - bDither16 = false; - - ::SelectObject( hMemDC, hBrushOld ); - ::DeleteObject( hMemBrush ); - ::SelectObject( hMemDC, hBmpOld ); - ::DeleteObject( hMemBmp ); - ::DeleteDC( hMemDC ); - - if( bDither16 ) - { - // create DIBPattern for 16Bit dithering - tools::Long n; - - pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, sizeof( BITMAPINFOHEADER ) + 192 ); - pSalData->mpDitherDIB = static_cast<BYTE*>(GlobalLock( pSalData->mhDitherDIB )); - pSalData->mpDitherDiff.reset(new tools::Long[ 256 ]); - pSalData->mpDitherLow.reset(new BYTE[ 256 ]); - pSalData->mpDitherHigh.reset(new BYTE[ 256 ]); - pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ); - memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) ); - - BITMAPINFOHEADER* pBIH = reinterpret_cast<BITMAPINFOHEADER*>(pSalData->mpDitherDIB); - - pBIH->biSize = sizeof( BITMAPINFOHEADER ); - pBIH->biWidth = 8; - pBIH->biHeight = 8; - pBIH->biPlanes = 1; - pBIH->biBitCount = 24; - - for( n = 0; n < 256; n++ ) - pSalData->mpDitherDiff[ n ] = n - ( n & 248L ); - - for( n = 0; n < 256; n++ ) - pSalData->mpDitherLow[ n ] = static_cast<BYTE>( n & 248 ); - - for( n = 0; n < 256; n++ ) - pSalData->mpDitherHigh[ n ] = static_cast<BYTE>(std::min( pSalData->mpDitherLow[ n ] + 8, 255 )); - } - } - else if ( (nRasterCaps & RC_PALETTE) && (nBitCount == 8) ) - { - BYTE nRed, nGreen, nBlue; - BYTE nR, nG, nB; - PALETTEENTRY* pPalEntry; - LOGPALETTE* pLogPal; - const sal_uInt16 nDitherPalCount = DITHER_PAL_COUNT; - sal_uLong nTotalCount = DITHER_MAX_SYSCOLOR + nDitherPalCount + DITHER_EXTRA_COLORS; - - // create logical palette - pLogPal = reinterpret_cast<LOGPALETTE*>(new char[ sizeof( LOGPALETTE ) + ( nTotalCount * sizeof( PALETTEENTRY ) ) ]); - pLogPal->palVersion = 0x0300; - pLogPal->palNumEntries = static_cast<sal_uInt16>(nTotalCount); - pPalEntry = pLogPal->palPalEntry; - - // Standard colors - memcpy( pPalEntry, aImplSalSysPalEntryAry, DITHER_MAX_SYSCOLOR * sizeof( PALETTEENTRY ) ); - pPalEntry += DITHER_MAX_SYSCOLOR; - - // own palette (6/6/6) - for( nB=0, nBlue=0; nB < DITHER_PAL_STEPS; nB++, nBlue += DITHER_PAL_DELTA ) - { - for( nG=0, nGreen=0; nG < DITHER_PAL_STEPS; nG++, nGreen += DITHER_PAL_DELTA ) - { - for( nR=0, nRed=0; nR < DITHER_PAL_STEPS; nR++, nRed += DITHER_PAL_DELTA ) - { - pPalEntry->peRed = nRed; - pPalEntry->peGreen = nGreen; - pPalEntry->peBlue = nBlue; - pPalEntry->peFlags = 0; - pPalEntry++; - } - } - } - - // insert special 'Blue' as standard drawing color - *pPalEntry++ = aImplExtraColor1; - - // create palette - pSalData->mhDitherPal = CreatePalette( pLogPal ); - delete[] reinterpret_cast<char*>(pLogPal); - - if( pSalData->mhDitherPal ) - { - // create DIBPattern for 8Bit dithering - tools::Long const nSize = sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) ) + 64; - tools::Long n; - - pSalData->mhDitherDIB = GlobalAlloc( GMEM_FIXED, nSize ); - pSalData->mpDitherDIB = static_cast<BYTE*>(GlobalLock( pSalData->mhDitherDIB )); - pSalData->mpDitherDiff.reset(new tools::Long[ 256 ]); - pSalData->mpDitherLow.reset(new BYTE[ 256 ]); - pSalData->mpDitherHigh.reset(new BYTE[ 256 ]); - pSalData->mpDitherDIBData = pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) + ( 256 * sizeof( short ) ); - memset( pSalData->mpDitherDIB, 0, sizeof( BITMAPINFOHEADER ) ); - - BITMAPINFOHEADER* pBIH = reinterpret_cast<BITMAPINFOHEADER*>(pSalData->mpDitherDIB); - short* pColors = reinterpret_cast<short*>( pSalData->mpDitherDIB + sizeof( BITMAPINFOHEADER ) ); - - pBIH->biSize = sizeof( BITMAPINFOHEADER ); - pBIH->biWidth = 8; - pBIH->biHeight = 8; - pBIH->biPlanes = 1; - pBIH->biBitCount = 8; - - for( n = 0; n < nDitherPalCount; n++ ) - pColors[ n ] = static_cast<short>( n + DITHER_MAX_SYSCOLOR ); - - for( n = 0; n < 256; n++ ) - pSalData->mpDitherDiff[ n ] = n % 51; - - for( n = 0; n < 256; n++ ) - pSalData->mpDitherLow[ n ] = static_cast<BYTE>( n / 51 ); - - for( n = 0; n < 256; n++ ) - pSalData->mpDitherHigh[ n ] = static_cast<BYTE>(std::min( pSalData->mpDitherLow[ n ] + 1, 5 )); - } - - // get system color entries - ImplUpdateSysColorEntries(); - } - - ReleaseDC( nullptr, hDC ); } void ImplFreeSalGDI() @@ -315,26 +110,6 @@ void ImplFreeSalGDI() ImplClearHDCCache( pSalData ); - // delete Ditherpalette, if existing - if ( pSalData->mhDitherPal ) - { - DeleteObject( pSalData->mhDitherPal ); - pSalData->mhDitherPal = nullptr; - } - - // delete buffers for dithering DIB patterns, if necessary - if ( pSalData->mhDitherDIB ) - { - GlobalUnlock( pSalData->mhDitherDIB ); - GlobalFree( pSalData->mhDitherDIB ); - pSalData->mhDitherDIB = nullptr; - pSalData->mpDitherDiff.reset(); - pSalData->mpDitherLow.reset(); - pSalData->mpDitherHigh.reset(); - } - - DeleteSysColorList(); - // delete icon cache SalIcon* pIcon = pSalData->mpFirstIcon; pSalData->mpFirstIcon = nullptr; @@ -353,98 +128,6 @@ void ImplFreeSalGDI() pSalData->mbResourcesAlreadyFreed = true; } -int ImplIsSysColorEntry( Color nColor ) -{ - SysColorEntry* pEntry = pFirstSysColor; - const DWORD nTestRGB = static_cast<DWORD>(RGB( nColor.GetRed(), - nColor.GetGreen(), - nColor.GetBlue() )); - - while ( pEntry ) - { - if ( pEntry->nRGB == nTestRGB ) - return TRUE; - pEntry = pEntry->pNext; - } - - return FALSE; -} - -static int ImplIsPaletteEntry( BYTE nRed, BYTE nGreen, BYTE nBlue ) -{ - // dither color? - if ( !(nRed % DITHER_PAL_DELTA) && !(nGreen % DITHER_PAL_DELTA) && !(nBlue % DITHER_PAL_DELTA) ) - return TRUE; - - PALETTEENTRY* pPalEntry = aImplSalSysPalEntryAry; - - // standard palette color? - for ( sal_uInt16 i = 0; i < DITHER_MAX_SYSCOLOR; i++, pPalEntry++ ) - { - if( pPalEntry->peRed == nRed && pPalEntry->peGreen == nGreen && pPalEntry->peBlue == nBlue ) - return TRUE; - } - - // extra color? - if ( aImplExtraColor1.peRed == nRed && - aImplExtraColor1.peGreen == nGreen && - aImplExtraColor1.peBlue == nBlue ) - { - return TRUE; - } - - return FALSE; -} - -static void ImplInsertSysColorEntry( int nSysIndex ) -{ - const DWORD nRGB = GetSysColor( nSysIndex ); - - if ( !ImplIsPaletteEntry( GetRValue( nRGB ), GetGValue( nRGB ), GetBValue( nRGB ) ) ) - { - if ( !pFirstSysColor ) - { - pActSysColor = pFirstSysColor = new SysColorEntry; - pFirstSysColor->nRGB = nRGB; - pFirstSysColor->pNext = nullptr; - } - else - { - pActSysColor = pActSysColor->pNext = new SysColorEntry; - pActSysColor->nRGB = nRGB; - pActSysColor->pNext = nullptr; - } - } -} - -void ImplUpdateSysColorEntries() -{ - DeleteSysColorList(); - - // create new sys color list - ImplInsertSysColorEntry( COLOR_ACTIVEBORDER ); - ImplInsertSysColorEntry( COLOR_INACTIVEBORDER ); - ImplInsertSysColorEntry( COLOR_GRADIENTACTIVECAPTION ); - ImplInsertSysColorEntry( COLOR_GRADIENTINACTIVECAPTION ); - ImplInsertSysColorEntry( COLOR_3DFACE ); - ImplInsertSysColorEntry( COLOR_3DHILIGHT ); - ImplInsertSysColorEntry( COLOR_3DLIGHT ); - ImplInsertSysColorEntry( COLOR_3DSHADOW ); - ImplInsertSysColorEntry( COLOR_3DDKSHADOW ); - ImplInsertSysColorEntry( COLOR_INFOBK ); - ImplInsertSysColorEntry( COLOR_INFOTEXT ); - ImplInsertSysColorEntry( COLOR_BTNTEXT ); - ImplInsertSysColorEntry( COLOR_WINDOW ); - ImplInsertSysColorEntry( COLOR_WINDOWTEXT ); - ImplInsertSysColorEntry( COLOR_HIGHLIGHT ); - ImplInsertSysColorEntry( COLOR_HIGHLIGHTTEXT ); - ImplInsertSysColorEntry( COLOR_MENU ); - ImplInsertSysColorEntry( COLOR_MENUTEXT ); - ImplInsertSysColorEntry( COLOR_ACTIVECAPTION ); - ImplInsertSysColorEntry( COLOR_CAPTIONTEXT ); - ImplInsertSysColorEntry( COLOR_INACTIVECAPTION ); - ImplInsertSysColorEntry( COLOR_INACTIVECAPTIONTEXT ); -} void WinSalGraphics::InitGraphics() { @@ -489,7 +172,11 @@ void WinSalGraphics::DeInitGraphics() SelectFont( getHDC(), mhDefFont ); mhDefFont = nullptr; } - setPalette(nullptr); + if (mhDefPal) + { + SelectPalette(getHDC(), mhDefPal, /*bForceBkgd*/TRUE); + mhDefPal = nullptr; + } mpImpl->DeInit(); } @@ -513,12 +200,6 @@ HDC ImplGetCachedDC( sal_uLong nID, HBITMAP hBmp ) // create new DC with DefaultBitmap pC->mhDC = CreateCompatibleDC( hDC ); - if( pSalData->mhDitherPal ) - { - pC->mhDefPal = SelectPalette( pC->mhDC, pSalData->mhDitherPal, TRUE ); - RealizePalette( pC->mhDC ); - } - pC->mhSelBmp = CreateCompatibleBitmap( hDC, CACHED_HDC_DEFEXT, CACHED_HDC_DEFEXT ); pC->mhDefBmp = static_cast<HBITMAP>(SelectObject( pC->mhDC, pC->mhSelBmp )); @@ -706,39 +387,6 @@ HPALETTE WinSalGraphics::getDefPal() const return mhDefPal; } -UINT WinSalGraphics::setPalette(HPALETTE hNewPal, BOOL bForceBkgd) -{ - UINT res = GDI_ERROR; - - if (!getHDC()) - { - assert(!mhDefPal); - return res; - } - - if (hNewPal) - { - HPALETTE hOldPal = SelectPalette(getHDC(), hNewPal, bForceBkgd); - if (hOldPal) - { - if (!mhDefPal) - mhDefPal = hOldPal; - res = RealizePalette(getHDC()); - } - } - else - { - res = 0; - if (mhDefPal) - { - SelectPalette(getHDC(), mhDefPal, bForceBkgd); - mhDefPal = nullptr; - } - } - - return res; -} - HRGN WinSalGraphics::getRegion() const { return mhRegion; @@ -936,63 +584,64 @@ static BYTE* ImplSearchEntry( BYTE* pSource, BYTE const * pDest, sal_uLong nComp static bool ImplGetBoundingBox( double* nNumb, BYTE* pSource, sal_uLong nSize ) { - bool bRetValue = false; BYTE* pDest = ImplSearchEntry( pSource, reinterpret_cast<BYTE const *>("%%BoundingBox:"), nSize, 14 ); - if ( pDest ) - { - nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0; - pDest += 14; + if ( !pDest ) + return false; + + bool bRetValue = false; + + nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0; + pDest += 14; - int nSizeLeft = nSize - ( pDest - pSource ); - if ( nSizeLeft > 100 ) - nSizeLeft = 100; // only 100 bytes following the bounding box will be checked + int nSizeLeft = nSize - ( pDest - pSource ); + if ( nSizeLeft > 100 ) + nSizeLeft = 100; // only 100 bytes following the bounding box will be checked - int i; - for ( i = 0; ( i < 4 ) && nSizeLeft; i++ ) + int i; + for ( i = 0; ( i < 4 ) && nSizeLeft; i++ ) + { + int nDivision = 1; + bool bDivision = false; + bool bNegative = false; + bool bValid = true; + + while ( ( --nSizeLeft ) && ( ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) ) pDest++; + BYTE nByte = *pDest; + while ( nSizeLeft && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) ) { - int nDivision = 1; - bool bDivision = false; - bool bNegative = false; - bool bValid = true; - - while ( ( --nSizeLeft ) && ( ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) ) pDest++; - BYTE nByte = *pDest; - while ( nSizeLeft && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) ) + switch ( nByte ) { - switch ( nByte ) - { - case '.' : + case '.' : + if ( bDivision ) + bValid = false; + else + bDivision = true; + break; + case '-' : + bNegative = true; + break; + default : + if ( ( nByte < '0' ) || ( nByte > '9' ) ) + nSizeLeft = 1; // error parsing the bounding box values + else if ( bValid ) + { if ( bDivision ) - bValid = false; - else - bDivision = true; - break; - case '-' : - bNegative = true; - break; - default : - if ( ( nByte < '0' ) || ( nByte > '9' ) ) - nSizeLeft = 1; // error parsing the bounding box values - else if ( bValid ) - { - if ( bDivision ) - nDivision*=10; - nNumb[i] *= 10; - nNumb[i] += nByte - '0'; - } - break; - } - nSizeLeft--; - nByte = *(++pDest); + nDivision*=10; + nNumb[i] *= 10; + nNumb[i] += nByte - '0'; + } + break; } - if ( bNegative ) - nNumb[i] = -nNumb[i]; - if ( bDivision && ( nDivision != 1 ) ) - nNumb[i] /= nDivision; + nSizeLeft--; + nByte = *(++pDest); } - if ( i == 4 ) - bRetValue = true; + if ( bNegative ) + nNumb[i] = -nNumb[i]; + if ( bDivision && ( nDivision != 1 ) ) + nNumb[i] /= nDivision; } + if ( i == 4 ) + bRetValue = true; return bRetValue; } @@ -1000,138 +649,134 @@ static bool ImplGetBoundingBox( double* nNumb, BYTE* pSource, sal_uLong nSize ) bool WinSalGraphics::drawEPS( tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, void* pPtr, sal_uInt32 nSize ) { - bool bRetValue = false; - if ( mbPrinter ) + if ( !mbPrinter ) + return false; + + int nEscape = POSTSCRIPT_PASSTHROUGH; + if ( !Escape( getHDC(), QUERYESCSUPPORT, sizeof( int ), reinterpret_cast<LPSTR>(&nEscape), nullptr ) ) + return false; + + double nBoundingBox[4]; + if ( !ImplGetBoundingBox( nBoundingBox, static_cast<BYTE*>(pPtr), nSize ) ) + return false; + + OStringBuffer aBuf( POSTSCRIPT_BUFSIZE ); + + // reserve place for a sal_uInt16 + aBuf.append( "aa" ); + + // #107797# Write out EPS encapsulation header + + // directly taken from the PLRM 3.0, p. 726. Note: + // this will definitely cause problems when + // recursively creating and embedding PostScript files + // in OOo, since we use statically-named variables + // here (namely, b4_Inc_state_salWin, dict_count_salWin and + // op_count_salWin). Currently, I have no idea on how to + // work around that, except from scanning and + // interpreting the EPS for unused identifiers. + + // append the real text + aBuf.append( "\n\n/b4_Inc_state_salWin save def\n" + "/dict_count_salWin countdictstack def\n" + "/op_count_salWin count 1 sub def\n" + "userdict begin\n" + "/showpage {} def\n" + "0 setgray 0 setlinecap\n" + "1 setlinewidth 0 setlinejoin\n" + "10 setmiterlimit [] 0 setdash newpath\n" + "/languagelevel where\n" + "{\n" + " pop languagelevel\n" + " 1 ne\n" + " {\n" + " false setstrokeadjust false setoverprint\n" + " } if\n" + "} if\n\n" ); + + // #i10737# Apply clipping manually + + // Windows seems to ignore any clipping at the HDC, + // when followed by a POSTSCRIPT_PASSTHROUGH + + // Check whether we've got a clipping, consisting of + // exactly one rect (other cases should be, but aren't + // handled currently) + + // TODO: Handle more than one rectangle here (take + // care, the buffer can handle only POSTSCRIPT_BUFSIZE + // characters!) + if ( mhRegion != nullptr && + mpStdClipRgnData != nullptr && + mpClipRgnData == mpStdClipRgnData && + mpClipRgnData->rdh.nCount == 1 ) { - int nEscape = POSTSCRIPT_PASSTHROUGH; + RECT* pRect = &(mpClipRgnData->rdh.rcBound); + + aBuf.append( "\nnewpath\n" + + OString::number(pRect->left) + " " + OString::number(pRect->top) + + " moveto\n" + + OString::number(pRect->right) + " " + OString::number(pRect->top) + + " lineto\n" + + OString::number(pRect->right) + " " + + OString::number(pRect->bottom) + " lineto\n" + + OString::number(pRect->left) + " " + + OString::number(pRect->bottom) + " lineto\n" + "closepath\n" + "clip\n" + "newpath\n" ); + } - if ( Escape( getHDC(), QUERYESCSUPPORT, sizeof( int ), reinterpret_cast<LPSTR>(&nEscape), nullptr ) ) - { - double nBoundingBox[4]; + // #107797# Write out buffer - if ( ImplGetBoundingBox( nBoundingBox, static_cast<BYTE*>(pPtr), nSize ) ) - { - OStringBuffer aBuf( POSTSCRIPT_BUFSIZE ); - - // reserve place for a sal_uInt16 - aBuf.append( "aa" ); - - // #107797# Write out EPS encapsulation header - - // directly taken from the PLRM 3.0, p. 726. Note: - // this will definitely cause problems when - // recursively creating and embedding PostScript files - // in OOo, since we use statically-named variables - // here (namely, b4_Inc_state_salWin, dict_count_salWin and - // op_count_salWin). Currently, I have no idea on how to - // work around that, except from scanning and - // interpreting the EPS for unused identifiers. - - // append the real text - aBuf.append( "\n\n/b4_Inc_state_salWin save def\n" - "/dict_count_salWin countdictstack def\n" - "/op_count_salWin count 1 sub def\n" - "userdict begin\n" - "/showpage {} def\n" - "0 setgray 0 setlinecap\n" - "1 setlinewidth 0 setlinejoin\n" - "10 setmiterlimit [] 0 setdash newpath\n" - "/languagelevel where\n" - "{\n" - " pop languagelevel\n" - " 1 ne\n" - " {\n" - " false setstrokeadjust false setoverprint\n" - " } if\n" - "} if\n\n" ); - - // #i10737# Apply clipping manually - - // Windows seems to ignore any clipping at the HDC, - // when followed by a POSTSCRIPT_PASSTHROUGH - - // Check whether we've got a clipping, consisting of - // exactly one rect (other cases should be, but aren't - // handled currently) - - // TODO: Handle more than one rectangle here (take - // care, the buffer can handle only POSTSCRIPT_BUFSIZE - // characters!) - if ( mhRegion != nullptr && - mpStdClipRgnData != nullptr && - mpClipRgnData == mpStdClipRgnData && - mpClipRgnData->rdh.nCount == 1 ) - { - RECT* pRect = &(mpClipRgnData->rdh.rcBound); - - aBuf.append( "\nnewpath\n" - + OString::number(pRect->left) + " " + OString::number(pRect->top) - + " moveto\n" - + OString::number(pRect->right) + " " + OString::number(pRect->top) - + " lineto\n" - + OString::number(pRect->right) + " " - + OString::number(pRect->bottom) + " lineto\n" - + OString::number(pRect->left) + " " - + OString::number(pRect->bottom) + " lineto\n" - "closepath\n" - "clip\n" - "newpath\n" ); - } - - // #107797# Write out buffer - - *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>( aBuf.getLength() - 2 ); - Escape ( getHDC(), nEscape, aBuf.getLength(), aBuf.getStr(), nullptr ); - - // #107797# Write out EPS transformation code - - double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] ); - double dM22 = nHeight / (nBoundingBox[1] - nBoundingBox[3] ); - // reserve a sal_uInt16 again - aBuf.setLength( 2 ); - aBuf.append( "\n\n[" + OString::number(dM11) + " 0 0 " + OString::number(dM22) + " " - + OString::number(nX - ( dM11 * nBoundingBox[0] )) + " " - + OString::number(nY - ( dM22 * nBoundingBox[3] )) + "] concat\n" - "%%BeginDocument:\n" ); - *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>( aBuf.getLength() - 2 ); - Escape ( getHDC(), nEscape, aBuf.getLength(), aBuf.getStr(), nullptr ); - - // #107797# Write out actual EPS content - - sal_uLong nToDo = nSize; - sal_uLong nDoNow; - while ( nToDo ) - { - nDoNow = nToDo; - if ( nToDo > POSTSCRIPT_BUFSIZE - 2 ) - nDoNow = POSTSCRIPT_BUFSIZE - 2; - // the following is based on the string buffer allocation - // of size POSTSCRIPT_BUFSIZE at construction time of aBuf - *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>(nDoNow); - memcpy( const_cast<char *>(aBuf.getStr() + 2), static_cast<BYTE*>(pPtr) + nSize - nToDo, nDoNow ); - sal_uLong nResult = Escape ( getHDC(), nEscape, nDoNow + 2, aBuf.getStr(), nullptr ); - if (!nResult ) - break; - nToDo -= nResult; - } - - // #107797# Write out EPS encapsulation footer - - // reserve a sal_uInt16 again - aBuf.setLength( 2 ); - aBuf.append( "%%EndDocument\n" - "count op_count_salWin sub {pop} repeat\n" - "countdictstack dict_count_salWin sub {end} repeat\n" - "b4_Inc_state_salWin restore\n\n" ); - *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>( aBuf.getLength() - 2 ); - Escape ( getHDC(), nEscape, aBuf.getLength(), aBuf.getStr(), nullptr ); - bRetValue = true; - } - } + *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>( aBuf.getLength() - 2 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), aBuf.getStr(), nullptr ); + + // #107797# Write out EPS transformation code + + double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] ); + double dM22 = nHeight / (nBoundingBox[1] - nBoundingBox[3] ); + // reserve a sal_uInt16 again + aBuf.setLength( 2 ); + aBuf.append( "\n\n[" + OString::number(dM11) + " 0 0 " + OString::number(dM22) + " " + + OString::number(nX - ( dM11 * nBoundingBox[0] )) + " " + + OString::number(nY - ( dM22 * nBoundingBox[3] )) + "] concat\n" + "%%BeginDocument:\n" ); + *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>( aBuf.getLength() - 2 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), aBuf.getStr(), nullptr ); + + // #107797# Write out actual EPS content + + sal_uLong nToDo = nSize; + sal_uLong nDoNow; + while ( nToDo ) + { + nDoNow = nToDo; + if ( nToDo > POSTSCRIPT_BUFSIZE - 2 ) + nDoNow = POSTSCRIPT_BUFSIZE - 2; + // the following is based on the string buffer allocation + // of size POSTSCRIPT_BUFSIZE at construction time of aBuf + *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>(nDoNow); + memcpy( const_cast<char *>(aBuf.getStr() + 2), static_cast<BYTE*>(pPtr) + nSize - nToDo, nDoNow ); + sal_uLong nResult = Escape ( getHDC(), nEscape, nDoNow + 2, aBuf.getStr(), nullptr ); + if (!nResult ) + break; + nToDo -= nResult; } - return bRetValue; + // #107797# Write out EPS encapsulation footer + + // reserve a sal_uInt16 again + aBuf.setLength( 2 ); + aBuf.append( "%%EndDocument\n" + "count op_count_salWin sub {pop} repeat\n" + "countdictstack dict_count_salWin sub {end} repeat\n" + "b4_Inc_state_salWin restore\n\n" ); + *reinterpret_cast<sal_uInt16*>(const_cast<char *>(aBuf.getStr())) = static_cast<sal_uInt16>( aBuf.getLength() - 2 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), aBuf.getStr(), nullptr ); + + return true; } SystemGraphicsData WinSalGraphics::GetGraphicsData() const diff --git a/vcl/win/gdi/salgdi2.cxx b/vcl/win/gdi/salgdi2.cxx index b4aa68fa29cb..ba4afc157bc3 100644 --- a/vcl/win/gdi/salgdi2.cxx +++ b/vcl/win/gdi/salgdi2.cxx @@ -116,10 +116,14 @@ void convertToWinSalBitmap(SalBitmap& rSalBitmap, WinSalBitmap& rWinSalBitmap) rWinSalBitmap.Create(rSalBitmap.GetSize(), vcl::bitDepthToPixelFormat(rSalBitmap.GetBitCount()), aBitmapPalette); BitmapBuffer* pWrite = rWinSalBitmap.AcquireBuffer(BitmapAccessMode::Write); - // convert to bottom-up data - sal_uInt8* pSource = pRead->mpBits + pRead->mnScanlineSize * (pRead->mnHeight - 1); + sal_uInt8* pSource(pRead->mpBits); sal_uInt8* pDestination(pWrite->mpBits); - tools::Long readRowChange = -pRead->mnScanlineSize; + tools::Long readRowChange = pRead->mnScanlineSize; + if (pRead->meDirection == ScanlineDirection::TopDown) + { + pSource += pRead->mnScanlineSize * (pRead->mnHeight - 1); + readRowChange = -readRowChange; + } std::unique_ptr<ColorScanlineConverter> pConverter; diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx b/vcl/win/gdi/salnativewidgets-luna.cxx index 993a0113dcff..878a28003714 100644 --- a/vcl/win/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/gdi/salnativewidgets-luna.cxx @@ -498,10 +498,17 @@ static bool drawThemedControl(HDC hDC, ControlType nType, int iPart, int iState, Color aScrollBarThumbColor = ThemeColors::GetThemeColors().GetBaseColor(); const Color& rBackgroundColor = ThemeColors::GetThemeColors().GetWindowColor(); + bool bUseDarkMode = UseDarkMode(); if (iState == SCRBS_PRESSED) - aScrollBarThumbColor.IncreaseLuminance(60); + if (bUseDarkMode) + aScrollBarThumbColor.IncreaseLuminance(60); + else + aScrollBarThumbColor.DecreaseLuminance(60); else if (iState = SCRBS_HOT) - aScrollBarThumbColor.IncreaseLuminance(30); + if (bUseDarkMode) + aScrollBarThumbColor.IncreaseLuminance(30); + else + aScrollBarThumbColor.DecreaseLuminance(30); ScopedHBRUSH hbrush(CreateSolidBrush(RGB(rBackgroundColor.GetRed(), rBackgroundColor.GetGreen(), diff --git a/vcl/win/gdi/salprn.cxx b/vcl/win/gdi/salprn.cxx index 393c8c7b1f3a..07c5666a46fe 100644 --- a/vcl/win/gdi/salprn.cxx +++ b/vcl/win/gdi/salprn.cxx @@ -161,61 +161,61 @@ void WinSalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList ) DWORD nBytes = 0; DWORD nInfoPrn4 = 0; EnumPrintersW( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, 4, nullptr, 0, &nBytes, &nInfoPrn4 ); - if ( nBytes ) + if ( !nBytes ) + return; + + PRINTER_INFO_4W* pWinInfo4 = static_cast<PRINTER_INFO_4W*>(std::malloc( nBytes )); + assert(pWinInfo4 && "Don't handle OOM conditions"); + if ( EnumPrintersW( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, 4, reinterpret_cast<LPBYTE>(pWinInfo4), nBytes, &nBytes, &nInfoPrn4 ) ) { - PRINTER_INFO_4W* pWinInfo4 = static_cast<PRINTER_INFO_4W*>(std::malloc( nBytes )); - assert(pWinInfo4 && "Don't handle OOM conditions"); - if ( EnumPrintersW( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, 4, reinterpret_cast<LPBYTE>(pWinInfo4), nBytes, &nBytes, &nInfoPrn4 ) ) + for ( i = 0; i < nInfoPrn4; i++ ) { - for ( i = 0; i < nInfoPrn4; i++ ) - { - std::unique_ptr<SalPrinterQueueInfo> pInfo(new SalPrinterQueueInfo); - pInfo->maPrinterName = o3tl::toU(pWinInfo4[i].pPrinterName); - pInfo->mnStatus = PrintQueueFlags::NONE; - pInfo->mnJobs = 0; - pList->Add( std::move(pInfo) ); - } + std::unique_ptr<SalPrinterQueueInfo> pInfo(new SalPrinterQueueInfo); + pInfo->maPrinterName = o3tl::toU(pWinInfo4[i].pPrinterName); + pInfo->mnStatus = PrintQueueFlags::NONE; + pInfo->mnJobs = 0; + pList->Add( std::move(pInfo) ); } - std::free( pWinInfo4 ); } + std::free( pWinInfo4 ); } void WinSalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo ) { HANDLE hPrinter = nullptr; LPWSTR pPrnName = const_cast<LPWSTR>(o3tl::toW(pInfo->maPrinterName.getStr())); - if( OpenPrinterW( pPrnName, &hPrinter, nullptr ) ) + if( !OpenPrinterW( pPrnName, &hPrinter, nullptr ) ) + return; + + DWORD nBytes = 0; + GetPrinterW( hPrinter, 2, nullptr, 0, &nBytes ); + if( nBytes ) { - DWORD nBytes = 0; - GetPrinterW( hPrinter, 2, nullptr, 0, &nBytes ); - if( nBytes ) + PRINTER_INFO_2W* pWinInfo2 = static_cast<PRINTER_INFO_2W*>(std::malloc(nBytes)); + assert(pWinInfo2 && "Don't handle OOM conditions"); + if( GetPrinterW( hPrinter, 2, reinterpret_cast<LPBYTE>(pWinInfo2), nBytes, &nBytes ) ) { - PRINTER_INFO_2W* pWinInfo2 = static_cast<PRINTER_INFO_2W*>(std::malloc(nBytes)); - assert(pWinInfo2 && "Don't handle OOM conditions"); - if( GetPrinterW( hPrinter, 2, reinterpret_cast<LPBYTE>(pWinInfo2), nBytes, &nBytes ) ) - { - if( pWinInfo2->pDriverName ) - pInfo->maDriver = o3tl::toU(pWinInfo2->pDriverName); - OUString aPortName; - if ( pWinInfo2->pPortName ) - aPortName = o3tl::toU(pWinInfo2->pPortName); - // pLocation can be 0 (the Windows docu doesn't describe this) - if ( pWinInfo2->pLocation && *pWinInfo2->pLocation ) - pInfo->maLocation = o3tl::toU(pWinInfo2->pLocation); - else - pInfo->maLocation = aPortName; - // pComment can be 0 (the Windows docu doesn't describe this) - if ( pWinInfo2->pComment ) - pInfo->maComment = o3tl::toU(pWinInfo2->pComment); - pInfo->mnStatus = ImplWinQueueStatusToSal( pWinInfo2->Status ); - pInfo->mnJobs = pWinInfo2->cJobs; - if( ! pInfo->moPortName ) - pInfo->moPortName = aPortName; - } - std::free(pWinInfo2); + if( pWinInfo2->pDriverName ) + pInfo->maDriver = o3tl::toU(pWinInfo2->pDriverName); + OUString aPortName; + if ( pWinInfo2->pPortName ) + aPortName = o3tl::toU(pWinInfo2->pPortName); + // pLocation can be 0 (the Windows docu doesn't describe this) + if ( pWinInfo2->pLocation && *pWinInfo2->pLocation ) + pInfo->maLocation = o3tl::toU(pWinInfo2->pLocation); + else + pInfo->maLocation = aPortName; + // pComment can be 0 (the Windows docu doesn't describe this) + if ( pWinInfo2->pComment ) + pInfo->maComment = o3tl::toU(pWinInfo2->pComment); + pInfo->mnStatus = ImplWinQueueStatusToSal( pWinInfo2->Status ); + pInfo->mnJobs = pWinInfo2->cJobs; + if( ! pInfo->moPortName ) + pInfo->moPortName = aPortName; } - ClosePrinter( hPrinter ); + std::free(pWinInfo2); } + ClosePrinter( hPrinter ); } OUString WinSalInstance::GetDefaultPrinter() @@ -248,79 +248,79 @@ static DWORD ImplDeviceCaps( WinSalInfoPrinter const * pPrinter, WORD nCaps, static bool ImplTestSalJobSetup( WinSalInfoPrinter const * pPrinter, ImplJobSetup* pSetupData, bool bDelete ) { - if ( pSetupData && pSetupData->GetDriverData() ) + if ( !pSetupData || !pSetupData->GetDriverData() ) + return false; + + // signature and size must fit to avoid using + // JobSetups from a wrong system + + // initialize versions from jobsetup + // those will be overwritten with driver's version + DEVMODEW const * pDevModeW = nullptr; + LONG dmSpecVersion = -1; + LONG dmDriverVersion = -1; + SalDriverData const * pSalDriverData = reinterpret_cast<SalDriverData const *>(pSetupData->GetDriverData()); + BYTE const * pDriverData = reinterpret_cast<BYTE const *>(pSalDriverData) + pSalDriverData->mnDriverOffset; + pDevModeW = reinterpret_cast<DEVMODEW const *>(pDriverData); + + LONG nSysJobSize = -1; + if( pPrinter && pDevModeW ) { - // signature and size must fit to avoid using - // JobSetups from a wrong system - - // initialize versions from jobsetup - // those will be overwritten with driver's version - DEVMODEW const * pDevModeW = nullptr; - LONG dmSpecVersion = -1; - LONG dmDriverVersion = -1; - SalDriverData const * pSalDriverData = reinterpret_cast<SalDriverData const *>(pSetupData->GetDriverData()); - BYTE const * pDriverData = reinterpret_cast<BYTE const *>(pSalDriverData) + pSalDriverData->mnDriverOffset; - pDevModeW = reinterpret_cast<DEVMODEW const *>(pDriverData); - - LONG nSysJobSize = -1; - if( pPrinter && pDevModeW ) - { - // just too many driver crashes in that area -> check the dmSpecVersion and dmDriverVersion fields always !!! - // this prevents using the jobsetup between different Windows versions (eg from XP to 9x) but we - // can avoid potential driver crashes as their jobsetups are often not compatible - // #110800#, #111151#, #112381#, #i16580#, #i14173# and perhaps #112375# - HANDLE hPrn; - LPWSTR pPrinterNameW = const_cast<LPWSTR>(o3tl::toW(pPrinter->maDeviceName.getStr())); - if ( !OpenPrinterW( pPrinterNameW, &hPrn, nullptr ) ) - return false; - - // #131642# hPrn==HGDI_ERROR even though OpenPrinter() succeeded! - if( hPrn == HGDI_ERROR ) - return false; - - nSysJobSize = DocumentPropertiesW( nullptr, hPrn, - pPrinterNameW, - nullptr, nullptr, 0 ); - - if( nSysJobSize < 0 ) - { - ClosePrinter( hPrn ); - return false; - } - DEVMODEW *pBuffer = static_cast<DEVMODEW*>(_alloca( nSysJobSize )); - LONG nRet = DocumentPropertiesW( nullptr, hPrn, - pPrinterNameW, - pBuffer, nullptr, DM_OUT_BUFFER ); - if( nRet < 0 ) - { - ClosePrinter( hPrn ); - return false; - } + // just too many driver crashes in that area -> check the dmSpecVersion and dmDriverVersion fields always !!! + // this prevents using the jobsetup between different Windows versions (eg from XP to 9x) but we + // can avoid potential driver crashes as their jobsetups are often not compatible + // #110800#, #111151#, #112381#, #i16580#, #i14173# and perhaps #112375# + HANDLE hPrn; + LPWSTR pPrinterNameW = const_cast<LPWSTR>(o3tl::toW(pPrinter->maDeviceName.getStr())); + if ( !OpenPrinterW( pPrinterNameW, &hPrn, nullptr ) ) + return false; - // the spec version differs between the windows platforms, ie 98,NT,2000/XP - // this allows us to throw away printer settings from other platforms that might crash a buggy driver - // we check the driver version as well - dmSpecVersion = pBuffer->dmSpecVersion; - dmDriverVersion = pBuffer->dmDriverVersion; + // #131642# hPrn==HGDI_ERROR even though OpenPrinter() succeeded! + if( hPrn == HGDI_ERROR ) + return false; - ClosePrinter( hPrn ); - } - SalDriverData const * pSetupDriverData = reinterpret_cast<SalDriverData const *>(pSetupData->GetDriverData()); - if ( (pSetupData->GetSystem() == JOBSETUP_SYSTEM_WINDOWS) && - (pPrinter && pPrinter->maDriverName == pSetupData->GetDriver()) && - (pSetupData->GetDriverDataLen() > sizeof( SalDriverData )) && - static_cast<tools::Long>(pSetupData->GetDriverDataLen() - pSetupDriverData->mnDriverOffset) == nSysJobSize && - pSetupDriverData->mnSysSignature == SAL_DRIVERDATA_SYSSIGN ) + nSysJobSize = DocumentPropertiesW( nullptr, hPrn, + pPrinterNameW, + nullptr, nullptr, 0 ); + + if( nSysJobSize < 0 ) { - if( pDevModeW && - (dmSpecVersion == pDevModeW->dmSpecVersion) && - (dmDriverVersion == pDevModeW->dmDriverVersion) ) - return true; + ClosePrinter( hPrn ); + return false; } - if ( bDelete ) + DEVMODEW *pBuffer = static_cast<DEVMODEW*>(_alloca( nSysJobSize )); + LONG nRet = DocumentPropertiesW( nullptr, hPrn, + pPrinterNameW, + pBuffer, nullptr, DM_OUT_BUFFER ); + if( nRet < 0 ) { - pSetupData->SetDriverData( nullptr, 0 ); + ClosePrinter( hPrn ); + return false; } + + // the spec version differs between the windows platforms, ie 98,NT,2000/XP + // this allows us to throw away printer settings from other platforms that might crash a buggy driver + // we check the driver version as well + dmSpecVersion = pBuffer->dmSpecVersion; + dmDriverVersion = pBuffer->dmDriverVersion; + + ClosePrinter( hPrn ); + } + SalDriverData const * pSetupDriverData = reinterpret_cast<SalDriverData const *>(pSetupData->GetDriverData()); + if ( (pSetupData->GetSystem() == JOBSETUP_SYSTEM_WINDOWS) && + (pPrinter && pPrinter->maDriverName == pSetupData->GetDriver()) && + (pSetupData->GetDriverDataLen() > sizeof( SalDriverData )) && + static_cast<tools::Long>(pSetupData->GetDriverDataLen() - pSetupDriverData->mnDriverOffset) == nSysJobSize && + pSetupDriverData->mnSysSignature == SAL_DRIVERDATA_SYSSIGN ) + { + if( pDevModeW && + (dmSpecVersion == pDevModeW->dmSpecVersion) && + (dmDriverVersion == pDevModeW->dmDriverVersion) ) + return true; + } + if ( bDelete ) + { + pSetupData->SetDriverData( nullptr, 0 ); } return false; @@ -1201,17 +1201,17 @@ OUString WinSalInfoPrinter::GetPaperBinName( const ImplJobSetup* pSetupData, sal sal_uInt16 WinSalInfoPrinter::GetPaperBinBySourceIndex( const ImplJobSetup* pSetupData, sal_uInt16 nPaperSource ) { DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, nullptr, pSetupData ); + if (nBins == GDI_ERROR) + return 0xffff; + + auto pBuffer = std::make_unique<sal_uInt16[]>(nBins); + nBins = ImplDeviceCaps( this, DC_BINS, reinterpret_cast<BYTE*>(pBuffer.get()), pSetupData ); if (nBins != GDI_ERROR) { - auto pBuffer = std::make_unique<sal_uInt16[]>(nBins); - nBins = ImplDeviceCaps( this, DC_BINS, reinterpret_cast<BYTE*>(pBuffer.get()), pSetupData ); - if (nBins != GDI_ERROR) + for (DWORD nBin = 0; nBin < nBins; ++nBin) { - for (DWORD nBin = 0; nBin < nBins; ++nBin) - { - if (nPaperSource == *(pBuffer.get() + nBin)) - return nBin; - } + if (nPaperSource == *(pBuffer.get() + nBin)) + return nBin; } } return 0xffff; @@ -1220,14 +1220,14 @@ sal_uInt16 WinSalInfoPrinter::GetPaperBinBySourceIndex( const ImplJobSetup* pSet sal_uInt16 WinSalInfoPrinter::GetSourceIndexByPaperBin(const ImplJobSetup* pSetupData, sal_uInt16 nPaperBin) { DWORD nBins = ImplDeviceCaps( this, DC_BINNAMES, nullptr, pSetupData ); - if (nBins != GDI_ERROR) + if (nBins == GDI_ERROR) + return 0; + + auto pBuffer = std::make_unique<sal_uInt16[]>(nBins); + nBins = ImplDeviceCaps( this, DC_BINS, reinterpret_cast<BYTE*>(pBuffer.get()), pSetupData ); + if (nBins != GDI_ERROR && nBins > nPaperBin) { - auto pBuffer = std::make_unique<sal_uInt16[]>(nBins); - nBins = ImplDeviceCaps( this, DC_BINS, reinterpret_cast<BYTE*>(pBuffer.get()), pSetupData ); - if (nBins != GDI_ERROR && nBins > nPaperBin) - { - return *(pBuffer.get() + nPaperBin); - } + return *(pBuffer.get() + nPaperBin); } return 0; } @@ -1337,27 +1337,23 @@ static BOOL CALLBACK SalPrintAbortProc( HDC hPrnDC, int /* nError */ ) static DEVMODEW const * ImplSalSetCopies( DEVMODEW const * pDevMode, sal_uInt32 nCopies, bool bCollate ) { - if ( pDevMode && (nCopies > 1) ) - { - if ( nCopies > 32765 ) - nCopies = 32765; - sal_uLong nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra; - LPDEVMODEW pNewDevMode = static_cast<LPDEVMODEW>(std::malloc( nDevSize )); - assert(pNewDevMode); // Don't handle OOM conditions - memcpy( pNewDevMode, pDevMode, nDevSize ); - pNewDevMode->dmFields |= DM_COPIES; - pNewDevMode->dmCopies = static_cast<short>(static_cast<sal_uInt16>(nCopies)); - pNewDevMode->dmFields |= DM_COLLATE; - if ( bCollate ) - pNewDevMode->dmCollate = DMCOLLATE_TRUE; - else - pNewDevMode->dmCollate = DMCOLLATE_FALSE; - return pNewDevMode; - } - else - { + if ( !pDevMode || (nCopies <= 1) ) return pDevMode; - } + + if ( nCopies > 32765 ) + nCopies = 32765; + sal_uLong nDevSize = pDevMode->dmSize+pDevMode->dmDriverExtra; + LPDEVMODEW pNewDevMode = static_cast<LPDEVMODEW>(std::malloc( nDevSize )); + assert(pNewDevMode); // Don't handle OOM conditions + memcpy( pNewDevMode, pDevMode, nDevSize ); + pNewDevMode->dmFields |= DM_COPIES; + pNewDevMode->dmCopies = static_cast<short>(static_cast<sal_uInt16>(nCopies)); + pNewDevMode->dmFields |= DM_COLLATE; + if ( bCollate ) + pNewDevMode->dmCollate = DMCOLLATE_TRUE; + else + pNewDevMode->dmCollate = DMCOLLATE_FALSE; + return pNewDevMode; } @@ -1552,23 +1548,23 @@ void WinSalPrinter::DoEndDoc(HDC hDC) bool WinSalPrinter::EndJob() { HDC hDC = mhDC; - if (isValid()) - { - mxGraphics.reset(); + if (!isValid()) + return true; - // #i54419# Windows fax printer brings up a dialog in EndDoc - // which text previously copied in soffice process can be - // pasted to -> deadlock due to mutex not released. - // it should be safe to release the yield mutex over the EndDoc - // call, however the real solution is supposed to be the threading - // framework yet to come. - { - SolarMutexReleaser aReleaser; - DoEndDoc( hDC ); - } - DeleteDC( hDC ); - mhDC = nullptr; + mxGraphics.reset(); + + // #i54419# Windows fax printer brings up a dialog in EndDoc + // which text previously copied in soffice process can be + // pasted to -> deadlock due to mutex not released. + // it should be safe to release the yield mutex over the EndDoc + // call, however the real solution is supposed to be the threading + // framework yet to come. + { + SolarMutexReleaser aReleaser; + DoEndDoc( hDC ); } + DeleteDC( hDC ); + mhDC = nullptr; return true; } diff --git a/vcl/win/gdi/salvd.cxx b/vcl/win/gdi/salvd.cxx index 9d87ed82425a..d4c9421f44f3 100644 --- a/vcl/win/gdi/salvd.cxx +++ b/vcl/win/gdi/salvd.cxx @@ -33,8 +33,6 @@ HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, tools::Long nDX, tools::Long nDY, sal_uInt16 nBitCount, void **ppData) { - assert(nDX >= 0); - assert(nDY >= 0); HBITMAP hBitmap; if ( nBitCount == 1 ) @@ -54,7 +52,7 @@ HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, tools::Long nDX, to BITMAPINFO aBitmapInfo; aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); aBitmapInfo.bmiHeader.biWidth = nDX; - aBitmapInfo.bmiHeader.biHeight = -nDY; // negative for top-down + aBitmapInfo.bmiHeader.biHeight = nDY; aBitmapInfo.bmiHeader.biPlanes = 1; aBitmapInfo.bmiHeader.biBitCount = nBitCount; aBitmapInfo.bmiHeader.biCompression = BI_RGB; @@ -74,73 +72,63 @@ HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, tools::Long nDX, to } std::unique_ptr<SalVirtualDevice> WinSalInstance::CreateVirtualDevice( SalGraphics& rSGraphics, - tools::Long &nDX, tools::Long &nDY, - DeviceFormat /*eFormat*/, - const SystemGraphicsData* pData ) + tools::Long nDX, tools::Long nDY, + DeviceFormat /*eFormat*/ ) { WinSalGraphics& rGraphics = static_cast<WinSalGraphics&>(rSGraphics); - HDC hDC = nullptr; - if( pData ) - { - hDC = (pData->hDC) ? pData->hDC : GetDC(pData->hWnd); - if (hDC) - { - nDX = GetDeviceCaps( hDC, HORZRES ); - nDY = GetDeviceCaps( hDC, VERTRES ); - } - else - { - nDX = 0; - nDY = 0; - } - } - else - { - hDC = CreateCompatibleDC( rGraphics.getHDC() ); - SAL_WARN_IF( !hDC, "vcl", "CreateCompatibleDC failed: " << WindowsErrorString( GetLastError() ) ); - } + HDC hDC = CreateCompatibleDC( rGraphics.getHDC() ); + SAL_WARN_IF( !hDC, "vcl", "CreateCompatibleDC failed: " << WindowsErrorString( GetLastError() ) ); if (!hDC) return nullptr; - sal_uInt16 nBitCount = 0; - HBITMAP hBmp = nullptr; - if (!pData) - { - // #124826# continue even if hBmp could not be created - // if we would return a failure in this case, the process - // would terminate which is not required - hBmp = WinSalVirtualDevice::ImplCreateVirDevBitmap(rGraphics.getHDC(), + const sal_uInt16 nBitCount = 0; + // #124826# continue even if hBmp could not be created + // if we would return a failure in this case, the process + // would terminate which is not required + HBITMAP hBmp = WinSalVirtualDevice::ImplCreateVirDevBitmap(rGraphics.getHDC(), nDX, nDY, nBitCount, &o3tl::temporary<void*>(nullptr)); - } - const bool bForeignDC = pData != nullptr && pData->hDC != nullptr; - const SalData* pSalData = GetSalData(); + auto pVDev = std::make_unique<WinSalVirtualDevice>(hDC, hBmp, nBitCount, + /*bForeignDC*/false, nDX, nDY, rGraphics.isScreen()); - WinSalVirtualDevice* pVDev = new WinSalVirtualDevice(hDC, hBmp, nBitCount, - bForeignDC, nDX, nDY); - - WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE, - rGraphics.isScreen(), nullptr, pVDev); + return pVDev; +} - // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL() - pVirGraphics->SetLayout( SalLayoutFlags::NONE ); - pVirGraphics->setHDC(hDC); +std::unique_ptr<SalVirtualDevice> WinSalInstance::CreateVirtualDevice( SalGraphics& rSGraphics, + tools::Long &nDX, tools::Long &nDY, + DeviceFormat /*eFormat*/, + const SystemGraphicsData& rData ) +{ + WinSalGraphics& rGraphics = static_cast<WinSalGraphics&>(rSGraphics); - if ( pSalData->mhDitherPal && pVirGraphics->isScreen() ) + HDC hDC = rData.hDC ? rData.hDC : GetDC(rData.hWnd); + if (hDC) + { + nDX = GetDeviceCaps( hDC, HORZRES ); + nDY = GetDeviceCaps( hDC, VERTRES ); + } + else { - pVirGraphics->setPalette(pSalData->mhDitherPal); - RealizePalette( hDC ); + nDX = 0; + nDY = 0; } - pVDev->setGraphics(pVirGraphics); + if (!hDC) + return nullptr; + + const sal_uInt16 nBitCount = 0; + const bool bForeignDC = rData.hDC != nullptr; + + auto pVDev = std::make_unique<WinSalVirtualDevice>(hDC, /*hBmp*/nullptr, nBitCount, + bForeignDC, nDX, nDY, rGraphics.isScreen()); - return std::unique_ptr<SalVirtualDevice>(pVDev); + return pVDev; } -WinSalVirtualDevice::WinSalVirtualDevice(HDC hDC, HBITMAP hBMP, sal_uInt16 nBitCount, bool bForeignDC, tools::Long nWidth, tools::Long nHeight) +WinSalVirtualDevice::WinSalVirtualDevice(HDC hDC, HBITMAP hBMP, sal_uInt16 nBitCount, bool bForeignDC, tools::Long nWidth, tools::Long nHeight, bool bIsScreen) : mhLocalDC(hDC), // HDC or 0 for Cache Device mhBmp(hBMP), // Memory Bitmap mnBitCount(nBitCount), // BitCount (0 or 1) @@ -159,8 +147,19 @@ WinSalVirtualDevice::WinSalVirtualDevice(HDC hDC, HBITMAP hBMP, sal_uInt16 nBitC SalData* pSalData = GetSalData(); mpNext = pSalData->mpFirstVD; pSalData->mpFirstVD = this; + + WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE, + bIsScreen, nullptr, this); + + // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL() + pVirGraphics->SetLayout( SalLayoutFlags::NONE ); + pVirGraphics->setHDC(hDC); + + setGraphics(pVirGraphics); } + + WinSalVirtualDevice::~WinSalVirtualDevice() { // remove VirDev from list of virtual devices diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index 6f5538140a2e..d5bbc048da43 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -139,9 +139,7 @@ WinFontInstance::~WinFontInstance() ::DeleteFont(m_hFont); if (m_hVerticalFont) - { ::DeleteFont(m_hVerticalFont); - } } float WinFontInstance::getHScale() const @@ -156,28 +154,28 @@ void WinFontInstance::ImplInitHbFont(hb_font_t* /*pHbFont*/) { assert(m_pGraphics); // Calculate the AverageWidthFactor, see LogicalFontInstance::GetScale(). - if (GetFontSelectPattern().mnWidth) - { - double nUPEM = GetFontFace()->UnitsPerEm(); + if (!GetFontSelectPattern().mnWidth) + return; - LOGFONTW aLogFont; - GetObjectW(m_hFont, sizeof(LOGFONTW), &aLogFont); + double nUPEM = GetFontFace()->UnitsPerEm(); - // Set the height (font size) to EM to minimize rounding errors. - aLogFont.lfHeight = -nUPEM; - // Set width to the default to get the original value in the metrics. - aLogFont.lfWidth = 0; + LOGFONTW aLogFont; + GetObjectW(m_hFont, sizeof(LOGFONTW), &aLogFont); - TEXTMETRICW aFontMetric; - { - // Get the font metrics. - HDC hDC = m_pGraphics->getHDC(); - ScopedSelectedHFONT hFont(hDC, CreateFontIndirectW(&aLogFont)); - GetTextMetricsW(hDC, &aFontMetric); - } + // Set the height (font size) to EM to minimize rounding errors. + aLogFont.lfHeight = -nUPEM; + // Set width to the default to get the original value in the metrics. + aLogFont.lfWidth = 0; - SetAverageWidthFactor(nUPEM / aFontMetric.tmAveCharWidth); + TEXTMETRICW aFontMetric; + { + // Get the font metrics. + HDC hDC = m_pGraphics->getHDC(); + ScopedSelectedHFONT hFont(hDC, CreateFontIndirectW(&aLogFont)); + GetTextMetricsW(hDC, &aFontMetric); } + + SetAverageWidthFactor(nUPEM / aFontMetric.tmAveCharWidth); } void WinFontInstance::SetGraphics(WinSalGraphics* pGraphics) |