xref: /trunk/main/canvas/inc/canvas/canvastools.hxx (revision b63233d8)
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 #ifndef INCLUDED_CANVAS_CANVASTOOLS_HXX
25 #define INCLUDED_CANVAS_CANVASTOOLS_HXX
26 
27 #include <rtl/math.hxx>
28 #include <com/sun/star/uno/Reference.hxx>
29 #include <com/sun/star/uno/Sequence.hxx>
30 #include <com/sun/star/uno/RuntimeException.hpp>
31 #include <com/sun/star/lang/IllegalArgumentException.hpp>
32 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33 #include <osl/diagnose.h>
34 #include <rtl/ustring.hxx>
35 
36 #include <string.h> // for strcmp
37 #include <vector>
38 #include <limits>
39 #include <algorithm>
40 
41 #include <canvas/canvastoolsdllapi.h>
42 
43 namespace basegfx
44 {
45     class B2DHomMatrix;
46     class B2DRange;
47     class B2IRange;
48     class B2IPoint;
49     class B2DPolyPolygon;
50 }
51 
52 namespace com { namespace sun { namespace star { namespace geometry
53 {
54     struct RealSize2D;
55     struct IntegerSize2D;
56     struct AffineMatrix2D;
57     struct Matrix2D;
58 } } } }
59 
60 namespace com { namespace sun { namespace star { namespace rendering
61 {
62     struct RenderState;
63     struct ViewState;
64     struct IntegerBitmapLayout;
65     class  XCanvas;
66     struct Texture;
67     class  XIntegerBitmapColorSpace;
68     class  XPolyPolygon2D;
69 
70     bool operator==( const RenderState&	rLHS,
71                      const RenderState& rRHS );
72 
73     bool operator==( const ViewState& rLHS,
74                      const ViewState& rRHS );
75 } } } }
76 
77 namespace com { namespace sun { namespace star { namespace awt
78 {
79     struct Rectangle;
80     class  XWindow2;
81 } } } }
82 
83 class Color;
84 
85 namespace canvas
86 {
87     namespace tools
88     {
89         /** Compute the next highest power of 2 of a 32-bit value
90 
91         	Code devised by Sean Anderson, in good ole HAKMEM
92         	tradition.
93 
94             @return 1 << (lg(x - 1) + 1)
95         */
nextPow2(sal_uInt32 x)96         inline sal_uInt32 nextPow2( sal_uInt32 x )
97         {
98             --x;
99             x |= x >> 1;
100             x |= x >> 2;
101             x |= x >> 4;
102             x |= x >> 8;
103             x |= x >> 16;
104 
105             return ++x;
106         }
107 
108 		/**
109 		 *
110 		 * Count the number of 1-bits of an n-bit value
111 		 *
112 		 */
113 
114 		// mickey's math tricks...
pow2(unsigned int c)115 		inline unsigned int pow2( unsigned int c ) { return 0x1 << c; }
mask(unsigned int c)116 		inline unsigned int mask( unsigned int c ) { return ((unsigned int)(-1)) / (pow2(pow2(c)) + 1); }
count(unsigned int x,unsigned int c)117 		inline unsigned int count( unsigned int x, unsigned int c ) { return ((x) & mask(c)) + (((x) >> (pow2(c))) & mask(c)); }
118 		template<typename T>
bitcount(T c)119 		inline unsigned int bitcount( T c ) {
120 			unsigned int nByteIndex = 0;
121 			unsigned int nNumBytes = sizeof(T)<<2;
122 			do {
123 				c=count(c,nByteIndex++);
124 				nNumBytes >>= 1;
125 			} while(nNumBytes);
126 			return c;
127 		}
bitcount32(sal_uInt32 c)128 		inline sal_uInt32 bitcount32( sal_uInt32 c ) {
129 			c=count(c,0);
130 			c=count(c,1);
131 			c=count(c,2);
132 			c=count(c,3);
133 			c=count(c,4);
134 			return c;
135 		}
136 
137         /** Round given floating point value down to next integer
138          */
roundDown(const double & rVal)139         inline sal_Int32 roundDown( const double& rVal )
140         {
141             return static_cast< sal_Int32 >( floor( rVal ) );
142         }
143 
144         /** Round given floating point value up to next integer
145          */
roundUp(const double & rVal)146         inline sal_Int32 roundUp( const double& rVal )
147         {
148             return static_cast< sal_Int32 >( ceil( rVal ) );
149         }
150 
151         /** Create a RealSize2D with both coordinate values set to +infinity
152          */
153         CANVASTOOLS_DLLPUBLIC ::com::sun::star::geometry::RealSize2D createInfiniteSize2D();
154 
155 
156         // View- and RenderState utilities
157         // ===================================================================
158 
159         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState&
160         	initRenderState( ::com::sun::star::rendering::RenderState&						renderState );
161 
162         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState&
163         	initViewState( ::com::sun::star::rendering::ViewState&							viewState );
164 
165         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix&
166 	        getViewStateTransform( ::basegfx::B2DHomMatrix&									transform,
167                                    const ::com::sun::star::rendering::ViewState&			viewState );
168 
169         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState&
170         	setViewStateTransform( ::com::sun::star::rendering::ViewState& 					viewState,
171                                    const ::basegfx::B2DHomMatrix&							transform );
172 
173         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix&
174         	getRenderStateTransform( ::basegfx::B2DHomMatrix&								transform,
175                                      const ::com::sun::star::rendering::RenderState&		renderState );
176 
177         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState&
178         	setRenderStateTransform( ::com::sun::star::rendering::RenderState& 				renderState,
179                                      const ::basegfx::B2DHomMatrix&							transform );
180 
181         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState&
182         	appendToViewState( ::com::sun::star::rendering::ViewState&						viewState,
183                                const ::basegfx::B2DHomMatrix&								transform );
184 
185         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState&
186         	appendToRenderState( ::com::sun::star::rendering::RenderState&					renderState,
187                                  const ::basegfx::B2DHomMatrix&								transform );
188 
189         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState&
190         	prependToViewState( ::com::sun::star::rendering::ViewState&						viewState,
191                                 const ::basegfx::B2DHomMatrix&								transform );
192 
193         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::RenderState&
194         	prependToRenderState( ::com::sun::star::rendering::RenderState&					renderState,
195                                   const ::basegfx::B2DHomMatrix&							transform );
196 
197         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix&
198         	mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix&							transform,
199                                          const ::com::sun::star::rendering::ViewState&		viewState,
200                                          const ::com::sun::star::rendering::RenderState&	renderState );
201 
202         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::ViewState&
203 	        mergeViewAndRenderState( ::com::sun::star::rendering::ViewState&				resultViewState,
204                                      const ::com::sun::star::rendering::ViewState&			viewState,
205                                      const ::com::sun::star::rendering::RenderState&		renderState,
206                                      const ::com::sun::star::uno::Reference<
207                                      	::com::sun::star::rendering::XCanvas >& 			xCanvas );
208 
209 
210         // Matrix utilities
211         // ===================================================================
212 
213         CANVASTOOLS_DLLPUBLIC ::com::sun::star::geometry::AffineMatrix2D&
214         	setIdentityAffineMatrix2D( ::com::sun::star::geometry::AffineMatrix2D&	matrix );
215 
216         CANVASTOOLS_DLLPUBLIC ::com::sun::star::geometry::Matrix2D&
217         	setIdentityMatrix2D( ::com::sun::star::geometry::Matrix2D&			    matrix );
218 
219 
220         // Special utilities
221         // ===================================================================
222 
223         /** Calc the bounding rectangle of a transformed rectangle.
224 
225 			The method applies the given transformation to the
226 			specified input rectangle, and returns the bounding box of
227 			the resulting output area.
228 
229             @param o_Rect
230             Output rectangle
231 
232             @param i_Rect
233             Input rectangle
234 
235             @param i_Transformation
236             Transformation to apply to the input rectangle
237 
238             @see calcRectToRectTransform()
239 
240             @return a reference to the resulting rectangle
241          */
242         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DRange& calcTransformedRectBounds( ::basegfx::B2DRange&			o_Rect,
243                                                         const ::basegfx::B2DRange&		i_Rect,
244                                                         const ::basegfx::B2DHomMatrix&	i_Transformation );
245 
246         /** Calc a transform that maps one rectangle on top of
247             another.
248 
249         	The method is a kissing cousin to
250         	calcTransformedRectBounds(). It can be used to modify the
251         	given transformation matrix, such that it transforms the
252         	given input rectangle to the given output rectangle,
253         	changing only translation and scale (if necessary). Thus,
254         	if you've calculated an output rectangle via
255         	calcTransformedRectBounds(), you can move and scale that
256         	rectangle as you like, and have this method calculate the
257         	required total transformation for it.
258 
259             @param o_transform
260             Output parameter, to receive the resulting transformation
261             matrix.
262 
263             @param i_destRect
264             Input parameter, specifies the requested destination
265             rectangle. The resulting transformation will exactly map
266             the source rectangle to the destination rectangle.
267 
268             @param i_srcRect
269             Input parameter, specifies the original source
270             rectangle. The resulting transformation will exactly map
271             the source rectangle to the destination rectangle.
272 
273             @param i_transformation
274             The original transformation matrix. This is changed with
275             translations and scalings (if necessary), to exactly map
276             the source rectangle to the destination rectangle.
277 
278             @return a reference to the resulting transformation matrix
279 
280             @see calcTransformedRectBounds()
281         */
282         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix& calcRectToRectTransform( ::basegfx::B2DHomMatrix&			o_transform,
283                                                           const ::basegfx::B2DRange&		i_destRect,
284                                                           const ::basegfx::B2DRange&		i_srcRect,
285                                                           const ::basegfx::B2DHomMatrix&	i_transformation );
286 
287         /** Calc a transform that maps the upper, left corner of a
288          	rectangle to the origin.
289 
290         	The method is a specialized version of
291         	calcRectToRectTransform(), mapping the input rectangle's
292         	the upper, left corner to the origin, and leaving the size
293         	untouched.
294 
295             @param o_transform
296             Output parameter, to receive the resulting transformation
297             matrix.
298 
299             @param i_srcRect
300             Input parameter, specifies the original source
301             rectangle. The resulting transformation will exactly map
302             the source rectangle's upper, left corner to the origin.
303 
304             @param i_transformation
305             The original transformation matrix. This is changed with
306             translations (if necessary), to exactly map the source
307             rectangle to the origin.
308 
309             @return a reference to the resulting transformation matrix
310 
311             @see calcRectToRectTransform()
312             @see calcTransformedRectBounds()
313         */
314         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DHomMatrix& calcRectToOriginTransform( ::basegfx::B2DHomMatrix&		o_transform,
315                                                             const ::basegfx::B2DRange&		i_srcRect,
316                                                             const ::basegfx::B2DHomMatrix&	i_transformation );
317 
318         /** Check whether a given rectangle is within another
319             transformed rectangle.
320 
321             This method checks for polygonal containedness, i.e. the
322             transformed rectangle is not represented as an axis-alignd
323             rectangle anymore (like calcTransformedRectBounds()), but
324             polygonal. Thus, the insideness test is based on tight
325             bounds.
326 
327             @param rContainedRect
328             This rectangle is checked, whether it is fully within the
329             transformed rTransformRect.
330 
331             @param rTransformRect
332             This rectangle is transformed, and then checked whether it
333             fully contains rContainedRect.
334 
335             @param rTransformation
336             This transformation is applied to rTransformRect
337          */
338 		CANVASTOOLS_DLLPUBLIC bool isInside( const ::basegfx::B2DRange& 		rContainedRect,
339                        const ::basegfx::B2DRange& 		rTransformRect,
340                        const ::basegfx::B2DHomMatrix&	rTransformation );
341 
342         /** Clip a scroll to the given bound rect
343 
344             @param io_rSourceArea
345             Source area to scroll. The resulting clipped source area
346             is returned therein.
347 
348             @param io_rDestPoint
349             Destination point of the scroll (upper, left corner of
350             rSourceArea after the scroll). The new, resulting
351             destination point is returned therein.q
352 
353             @param o_ClippedAreas
354             Vector of rectangles in the <em>destination</em> area
355             coordinate system, which are clipped away from the source
356             area, and thus need extra updates (i.e. they are not
357             correctly copy from the scroll operation, since there was
358             no information about them in the source).
359 
360             @param rBounds
361             Bounds to clip against.
362 
363             @return false, if the resulting scroll area is empty
364          */
365         CANVASTOOLS_DLLPUBLIC bool clipScrollArea( ::basegfx::B2IRange&                  io_rSourceArea,
366                              ::basegfx::B2IPoint&                  io_rDestPoint,
367                              ::std::vector< ::basegfx::B2IRange >& o_ClippedAreas,
368                              const ::basegfx::B2IRange&            rBounds );
369 
370         /** Clip a blit between two differently surfaces.
371 
372             This method clips source and dest rect for a clip between
373             two differently clipped surfaces, such that the resulting
374             blit rects are fully within both clip areas.
375 
376             @param io_rSourceArea
377             Source area of the blit. Returned therein is the computed
378             clipped source area.
379 
380             @param io_rDestPoint
381             Dest area of the blit. Returned therein is the computed
382             clipped dest area.
383 
384             @param rSourceBounds
385             Clip bounds of the source surface
386 
387             @param rDestBounds
388             Clip bounds of the dest surface
389 
390             @return false, if the resulting blit is empty, i.e. fully
391             clipped away.
392          */
393         CANVASTOOLS_DLLPUBLIC bool clipBlit( ::basegfx::B2IRange&       io_rSourceArea,
394                        ::basegfx::B2IPoint&       io_rDestPoint,
395                        const ::basegfx::B2IRange& rSourceBounds,
396                        const ::basegfx::B2IRange& rDestBounds );
397 
398         /** Return range of integer pixel, which will cover the sprite
399             given by the floating point range.
400 
401             This method assumes that sprite sizes are always integer,
402             and that the sprite position (top, left edge of the
403             sprite) is rounded to the nearest integer before
404             rendering.
405 
406 			@param rRange
407             Input range. Values must be within the representable
408             bounds of sal_Int32
409 
410             @return the integer range, which is covered by the sprite
411             given by rRange.
412          */
413         CANVASTOOLS_DLLPUBLIC ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange );
414 
415         /** Retrieve various internal properties of the actual canvas implementation.
416 
417         	This method retrieves a bunch of internal, implementation-
418         	and platform-dependent values from the canvas
419         	implementation. Among them are for example operating
420         	system window handles. The actual layout and content of
421         	the returned sequence is dependent on the component
422         	implementation, undocumented and subject to change.
423 
424             @param i_rxCanvas
425             Input parameter, the canvas representation for which the device information
426 			is to be retrieveds
427 
428             @param o_rxParams
429             Output parameter, the sequence of Anys that hold the device parameters. Layout is as described above
430 
431             @return A reference to the resulting sequence of parameters
432 		*/
433 		CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& getDeviceInfo(
434 			const ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas >& i_rxCanvas,
435 			::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& o_rxParams );
436 
437         /** Return a color space for a default RGBA integer format
438 
439             Use this method for dead-simple bitmap implementations,
440             that map all their formats to 8888 RGBA color.
441          */
442         CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XIntegerBitmapColorSpace> getStdColorSpace();
443 
444         /** Return a memory layout for a default RGBA integer format
445 
446             Use this method for dead-simple bitmap implementations,
447             that map all their formats to 8888 RGBA color.
448          */
449         CANVASTOOLS_DLLPUBLIC ::com::sun::star::rendering::IntegerBitmapLayout getStdMemoryLayout(
450             const ::com::sun::star::geometry::IntegerSize2D& rBitmapSize );
451 
452         /// Convert standard 8888 RGBA color to vcl color
453         CANVASTOOLS_DLLPUBLIC ::Color stdIntSequenceToColor( const ::com::sun::star::uno::Sequence<sal_Int8>& rColor );
454 
455         /// Convert standard 8888 RGBA color to vcl color
456         CANVASTOOLS_DLLPUBLIC ::com::sun::star::uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor );
457 
458         // Modelled closely after boost::numeric_cast, only that we
459         // issue some trace output here and throw a RuntimeException
460 
461         /** Cast numeric value into another (numeric) data type
462 
463         	Apart from converting the numeric value, this template
464         	also checks if any overflow, underflow, or sign
465         	information is lost (if yes, it throws an
466         	uno::RuntimeException.
467          */
numeric_cast(Source arg)468         template< typename Target, typename Source > inline Target numeric_cast( Source arg )
469         {
470             // typedefs abbreviating respective trait classes
471             typedef ::std::numeric_limits< Source > SourceLimits;
472             typedef ::std::numeric_limits< Target > TargetLimits;
473 
474             if( ( arg<0 && !TargetLimits::is_signed) || 					// losing the sign here
475                 ( SourceLimits::is_signed && arg<TargetLimits::min()) ||	// underflow will happen
476                 ( arg>TargetLimits::max() ) ) 					            // overflow will happen
477             {
478 #if defined(VERBOSE) && defined(DBG_UTIL)
479                 OSL_TRACE("numeric_cast detected data loss");
480 #endif
481                 throw ::com::sun::star::uno::RuntimeException(
482                     ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "numeric_cast detected data loss" )),
483                     NULL );
484             }
485 
486             return static_cast<Target>(arg);
487         }
488 
489         CANVASTOOLS_DLLPUBLIC ::com::sun::star::awt::Rectangle getAbsoluteWindowRect(
490             const ::com::sun::star::awt::Rectangle&                                    rRect,
491             const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow2 >& xWin  );
492 
493         /** Retrieve for small bound marks around each corner of the given rectangle
494          */
495         CANVASTOOLS_DLLPUBLIC ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange );
496 
497         /** Calculate number of gradient "strips" to generate (takes
498            into account device resolution)
499 
500            @param nColorSteps
501            Maximal integer difference between all color stops, needed
502            for smooth gradient color differences
503          */
504         CANVASTOOLS_DLLPUBLIC int calcGradientStepCount( ::basegfx::B2DHomMatrix&                        rTotalTransform,
505                                    const ::com::sun::star::rendering::ViewState&   viewState,
506                                    const ::com::sun::star::rendering::RenderState& renderState,
507                                    const ::com::sun::star::rendering::Texture&     texture,
508                                    int                                             nColorSteps );
509 
510         /** A very simplistic map for ASCII strings and arbitrary value
511             types.
512 
513             This class internally references a constant, static array of
514             sorted MapEntries, and performs a binary search to look up
515             values for a given query string. Note that this map is static,
516             i.e. not meant to be extented at runtime.
517 
518             @tpl ValueType
519             The value type this map should store, associated with an ASCII
520             string.
521         */
522         template< typename ValueType > class ValueMap
523         {
524         public:
525             struct MapEntry
526             {
527                 const char*		maKey;
528                 ValueType		maValue;
529             };
530 
531             /** Create a ValueMap for the given array of MapEntries.
532 
533                 @param pMap
534                 Pointer to a <em>static</em> array of MapEntries. Must
535                 live longer than this object! Make absolutely sure that
536                 the string entries passed via pMap are ASCII-only -
537                 everything else might not yield correct string
538                 comparisons, and thus will result in undefined behaviour.
539 
540                 @param nEntries
541                 Number of entries for pMap
542 
543                 @param bCaseSensitive
544                 Whether the map query should be performed case sensitive
545                 or not. When bCaseSensitive is false, all MapEntry strings
546                 must be lowercase!
547             */
ValueMap(const MapEntry * pMap,::std::size_t nEntries,bool bCaseSensitive)548             ValueMap( const MapEntry* 	pMap,
549                       ::std::size_t		nEntries,
550                       bool				bCaseSensitive ) :
551                 mpMap( pMap ),
552                 mnEntries( nEntries ),
553                 mbCaseSensitive( bCaseSensitive )
554             {
555 #ifdef DBG_UTIL
556                 // Ensure that map entries are sorted (and all lowercase, if this
557                 // map is case insensitive)
558                 const ::rtl::OString aStr( pMap->maKey );
559                 if( !mbCaseSensitive &&
560                     aStr != aStr.toAsciiLowerCase() )
561                 {
562                     OSL_TRACE("ValueMap::ValueMap(): Key %s is not lowercase",
563                               pMap->maKey);
564                     OSL_ENSURE( false, "ValueMap::ValueMap(): Key is not lowercase" );
565                 }
566 
567                 if( mnEntries > 1 )
568                 {
569                     for( ::std::size_t i=0; i<mnEntries-1; ++i, ++pMap )
570                     {
571                         if( !mapComparator(pMap[0], pMap[1]) &&
572                             mapComparator(pMap[1], pMap[0]) )
573                         {
574                             OSL_TRACE("ValueMap::ValueMap(): Map is not sorted, keys %s and %s are wrong",
575                                       pMap[0].maKey,
576                                       pMap[1].maKey);
577                             OSL_ENSURE( false,
578                                         "ValueMap::ValueMap(): Map is not sorted" );
579                         }
580 
581                         const ::rtl::OString aStr2( pMap[1].maKey );
582                         if( !mbCaseSensitive &&
583                             aStr2 != aStr2.toAsciiLowerCase() )
584                         {
585                             OSL_TRACE("ValueMap::ValueMap(): Key %s is not lowercase",
586                                       pMap[1].maKey);
587                             OSL_ENSURE( false, "ValueMap::ValueMap(): Key is not lowercase" );
588                         }
589                     }
590                 }
591 #endif
592             }
593 
594             /** Lookup a value for the given query string
595 
596                 @param rName
597                 The string to lookup. If the map was created with the case
598                 insensitive flag, the lookup is performed
599                 case-insensitive, otherwise, case-sensitive.
600 
601                 @param o_rResult
602                 Output parameter, which receives the value associated with
603                 the query string. If no value was found, the referenced
604                 object is kept unmodified.
605 
606                 @return true, if a matching entry was found.
607             */
lookup(const::rtl::OUString & rName,ValueType & o_rResult) const608             bool lookup( const ::rtl::OUString& rName,
609                          ValueType&				o_rResult ) const
610             {
611                 // rName is required to contain only ASCII characters.
612                 // TODO(Q1): Enforce this at upper layers
613                 ::rtl::OString aKey( ::rtl::OUStringToOString( mbCaseSensitive ? rName : rName.toAsciiLowerCase(),
614                                                                RTL_TEXTENCODING_ASCII_US ) );
615                 MapEntry aSearchKey =
616                     {
617                         aKey.getStr(),
618                         ValueType()
619                     };
620 
621                 const MapEntry* pRes;
622                 const MapEntry* pEnd = mpMap+mnEntries;
623                 if( (pRes=::std::lower_bound( mpMap,
624                                               pEnd,
625                                               aSearchKey,
626                                               &mapComparator )) != pEnd )
627                 {
628                     // place to _insert before_ found - is it equal to
629                     // the search key?
630                     if( strcmp( pRes->maKey, aSearchKey.maKey ) == 0 )
631                     {
632                         // yep, correct entry found
633                         o_rResult = pRes->maValue;
634                         return true;
635                     }
636                 }
637 
638                 // not found
639                 return false;
640             }
641 
642         private:
mapComparator(const MapEntry & rLHS,const MapEntry & rRHS)643             static bool mapComparator( const MapEntry& rLHS,
644                                        const MapEntry& rRHS )
645             {
646                 return strcmp( rLHS.maKey,
647                                rRHS.maKey ) < 0;
648             }
649 
650             const MapEntry* 	mpMap;
651             ::std::size_t		mnEntries;
652             bool				mbCaseSensitive;
653         };
654     }
655 }
656 
657 #endif /* INCLUDED_CANVAS_CANVASTOOLS_HXX */
658 // eof
659