Merge "Fix resource leaks in layouting." into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / text / color-segmentation.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // FILE HEADER
19 #include <dali-toolkit/internal/text/color-segmentation.h>
20
21 // EXTERNAL INCLUDES
22
23 // INTERNAL INCLUDES
24
25 #include <iostream>
26
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace Text
34 {
35
36 /**
37  * @brief Finds a color in the vector of colors.
38  *        It inserts the color in the vector if it's not in.
39  *
40  * @param[in,out] colors The vector of colors.
41  * @param[in] color The color to find.
42  *
43  * @return The index + 1 where the color is in the vector. The index zero is reserved for the default color.
44  */
45 ColorIndex FindColor( Vector<Vector4>& colors,
46                       const Vector4& color )
47 {
48   ColorIndex index = 1u; // The index zero is reserved for the default color.
49   for( Vector<Vector4>::Iterator it = colors.Begin(),
50          endIt = colors.End();
51        it != endIt;
52        ++it )
53   {
54     if( color == *it )
55     {
56       return index;
57     }
58
59     ++index;
60   }
61
62   colors.PushBack( color );
63
64   return index;
65 }
66
67 void SetColorSegmentationInfo( const Vector<ColorRun>& colorRuns,
68                                const Vector<GlyphIndex>& charactersToGlyph,
69                                const Vector<Length>& glyphsPerCharacter,
70                                CharacterIndex startCharacterIndex,
71                                GlyphIndex startGlyphIndex,
72                                Length numberOfCharacters,
73                                Vector<Vector4>& colors,
74                                Vector<ColorIndex>& colorIndices )
75 {
76   if( 0u == charactersToGlyph.Count() )
77   {
78     // Nothing to do if there is no text.
79     return;
80   }
81
82   // Get pointers to the buffers.
83   const GlyphIndex* const charactersToGlyphBuffer = charactersToGlyph.Begin();
84   const Length* const glyphsPerCharacterBuffer = glyphsPerCharacter.Begin();
85
86   // Calculate the number of glyphs to insert.
87   const CharacterIndex lastCharacterIndex = startCharacterIndex + numberOfCharacters - 1u;
88   const Length numberOfNewGlyphs = *( charactersToGlyphBuffer + lastCharacterIndex ) + *( glyphsPerCharacterBuffer + lastCharacterIndex ) - *( charactersToGlyphBuffer + startCharacterIndex );
89
90   // Reserve space for the new color indices.
91   Vector<ColorIndex> newColorIndices;
92   newColorIndices.Resize( numberOfNewGlyphs );
93
94   ColorIndex* newColorIndicesBuffer = newColorIndices.Begin();
95
96   // Convert from characters to glyphs.
97   Length index = 0u;
98   for( Vector<ColorRun>::ConstIterator it = colorRuns.Begin(),
99          endIt = colorRuns.End();
100        it != endIt;
101        ++it, ++index )
102   {
103     const ColorRun& colorRun = *it;
104
105     if( ( startCharacterIndex < colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters ) &&
106         ( colorRun.characterRun.characterIndex < startCharacterIndex + numberOfCharacters ) )
107     {
108       if( 0u < colorRun.characterRun.numberOfCharacters )
109       {
110         // Find the color index.
111         const ColorIndex colorIndex = FindColor( colors, colorRun.color );
112
113         // Get the index to the last character of the run.
114         const CharacterIndex lastIndex = colorRun.characterRun.characterIndex + colorRun.characterRun.numberOfCharacters - 1u;
115
116         const GlyphIndex glyphIndex = std::max( startGlyphIndex, *( charactersToGlyphBuffer + colorRun.characterRun.characterIndex ) ) - startGlyphIndex;
117         // Get the number of glyphs of the run.
118         const Length lastGlyphIndexPlusOne = std::min( numberOfNewGlyphs, *( charactersToGlyphBuffer + lastIndex ) + *( glyphsPerCharacterBuffer + lastIndex ) - startGlyphIndex );
119
120         // Set the indices.
121         for( GlyphIndex i = glyphIndex; i < lastGlyphIndexPlusOne; ++i )
122         {
123           *( newColorIndicesBuffer + i ) = colorIndex;
124         }
125       }
126     }
127   }
128
129   // Insert the new indices.
130   colorIndices.Insert( colorIndices.Begin() + startGlyphIndex,
131                        newColorIndices.Begin(),
132                        newColorIndices.End() );
133 }
134
135 } // namespace Text
136
137 } // namespace Toolkit
138
139 } // namespace Dali