1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_canvas.hxx" 26 27 #include <boost/bind.hpp> 28 #include <basegfx/polygon/b2dpolygoncutandtouch.hxx> 29 #include <basegfx/polygon/b2dpolygontriangulator.hxx> 30 #include <basegfx/polygon/b2dpolypolygontools.hxx> 31 #include "surfaceproxy.hxx" 32 33 namespace canvas 34 { 35 ////////////////////////////////////////////////////////////////////////////////// 36 // SurfaceProxy::SurfaceProxy 37 ////////////////////////////////////////////////////////////////////////////////// 38 39 SurfaceProxy::SurfaceProxy( const canvas::IColorBufferSharedPtr& pBuffer, 40 const PageManagerSharedPtr& pPageManager ) : 41 mpPageManager( pPageManager ), 42 maSurfaceList(), 43 mpBuffer( pBuffer ) 44 { 45 const ::basegfx::B2ISize aImageSize(mpBuffer->getWidth(),mpBuffer->getHeight()); 46 const ::basegfx::B2ISize aPageSize(mpPageManager->getPageSize()); 47 const sal_Int32 aPageSizeX(aPageSize.getX()); 48 const sal_Int32 aPageSizeY(aPageSize.getY()); 49 const sal_Int32 aImageSizeX(aImageSize.getX()); 50 const sal_Int32 aImageSizeY(aImageSize.getY()); 51 52 // see if the size of the colorbuffer is larger than the size 53 // of a single page. if this is the case we divide the 54 // colorbuffer into as many surfaces as we need to get the 55 // whole area distributed. otherwise (the colorbuffer is 56 // smaller than the size of a single page) we search for free 57 // pages or create a new one. 58 // the incoming image is too large to fit into a single 59 // page. strategy: we split the image into rectangular 60 // areas that are as large as the maximum page size 61 // dictates and follow the strategy for fitting images. 62 size_t dwNumSurfaces(0); 63 for(sal_Int32 y=0; y<aImageSizeY; y+=aPageSizeY) 64 for(sal_Int32 x=0; x<aImageSizeX; x+=aPageSizeX) 65 ++dwNumSurfaces; 66 maSurfaceList.reserve(dwNumSurfaces); 67 68 for(sal_Int32 y=0; y<aImageSizeY; y+=aPageSizeY) 69 { 70 for(sal_Int32 x=0; x<aImageSizeX; x+=aPageSizeX) 71 { 72 // the current surface is located at the position [x,y] 73 // and has the size [min(restx,pagesizex),min(resty,pagesizey) 74 ::basegfx::B2IPoint aOffset(x,y); 75 ::basegfx::B2ISize aSize( ::std::min( aImageSize.getX()-x, 76 aPageSize.getX() ), 77 ::std::min( aImageSize.getY()-y, 78 aPageSize.getY() ) ); 79 80 maSurfaceList.push_back( 81 SurfaceSharedPtr( 82 new Surface( 83 mpPageManager, 84 mpBuffer, 85 aOffset, 86 aSize))); 87 } 88 } 89 } 90 91 ////////////////////////////////////////////////////////////////////////////////// 92 // SurfaceProxy::setColorBufferDirty 93 ////////////////////////////////////////////////////////////////////////////////// 94 95 void SurfaceProxy::setColorBufferDirty() 96 { 97 ::std::for_each( maSurfaceList.begin(), 98 maSurfaceList.end(), 99 ::boost::mem_fn(&Surface::setColorBufferDirty)); 100 } 101 102 ////////////////////////////////////////////////////////////////////////////////// 103 // SurfaceProxy::draw 104 ////////////////////////////////////////////////////////////////////////////////// 105 106 bool SurfaceProxy::draw( double fAlpha, 107 const ::basegfx::B2DPoint& rPos, 108 const ::basegfx::B2DHomMatrix& rTransform ) 109 { 110 ::std::for_each( maSurfaceList.begin(), 111 maSurfaceList.end(), 112 ::boost::bind( &Surface::draw, 113 _1, 114 fAlpha, 115 ::boost::cref(rPos), 116 ::boost::cref(rTransform))); 117 118 return true; 119 } 120 121 ////////////////////////////////////////////////////////////////////////////////// 122 // SurfaceProxy::draw 123 ////////////////////////////////////////////////////////////////////////////////// 124 125 bool SurfaceProxy::draw( double fAlpha, 126 const ::basegfx::B2DPoint& rPos, 127 const ::basegfx::B2DRange& rArea, 128 const ::basegfx::B2DHomMatrix& rTransform ) 129 { 130 ::std::for_each( maSurfaceList.begin(), 131 maSurfaceList.end(), 132 ::boost::bind(&Surface::drawRectangularArea, 133 _1, 134 fAlpha, 135 ::boost::cref(rPos), 136 ::boost::cref(rArea), 137 ::boost::cref(rTransform))); 138 139 return true; 140 } 141 142 ////////////////////////////////////////////////////////////////////////////////// 143 // SurfaceProxy::draw 144 ////////////////////////////////////////////////////////////////////////////////// 145 146 bool SurfaceProxy::draw( double fAlpha, 147 const ::basegfx::B2DPoint& rPos, 148 const ::basegfx::B2DPolyPolygon& rClipPoly, 149 const ::basegfx::B2DHomMatrix& rTransform ) 150 { 151 const ::basegfx::B2DPolygon& rTriangulatedPolygon( 152 ::basegfx::triangulator::triangulate(rClipPoly)); 153 154 #if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0 155 // dump polygons 156 OSL_TRACE( "Original clip polygon: %s\n" 157 "Triangulated polygon: %s\n", 158 rtl::OUStringToOString( 159 basegfx::tools::exportToSvgD( rClipPoly ), 160 RTL_TEXTENCODING_ASCII_US).getStr(), 161 rtl::OUStringToOString( 162 basegfx::tools::exportToSvgD( 163 basegfx::B2DPolyPolygon(rTriangulatedPolygon) ), 164 RTL_TEXTENCODING_ASCII_US).getStr() ); 165 #endif 166 167 ::std::for_each( maSurfaceList.begin(), 168 maSurfaceList.end(), 169 ::boost::bind(&Surface::drawWithClip, 170 _1, 171 fAlpha, 172 ::boost::cref(rPos), 173 ::boost::cref(rTriangulatedPolygon), 174 ::boost::cref(rTransform))); 175 176 return true; 177 } 178 } 179