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_vcl.hxx"
26 
27 // We need this to enable namespace support in libgrengine headers.
28 #define GR_NAMESPACE
29 
30 // Header files
31 //
32 // Standard Library
33 #include <string>
34 #include <cassert>
35 #include "graphite_textsrc.hxx"
36 #include <graphite_features.hxx>
37 
38 // class TextSourceAdaptor implementation.
39 //
~TextSourceAdaptor()40 TextSourceAdaptor::~TextSourceAdaptor()
41 {
42     delete mpFeatures;
43 }
44 
utfEncodingForm()45 gr::UtfType TextSourceAdaptor::utfEncodingForm() {
46     return gr::kutf16;
47 }
48 
49 
getLength()50 size_t TextSourceAdaptor::getLength()
51 {
52     return maLayoutArgs.mnLength;
53 }
54 
55 
fetch(gr::toffset,size_t,gr::utf32 *)56 size_t  TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf32 *)
57 {
58     assert(false);
59     return 0;
60 }
61 
62 
fetch(gr::toffset offset,size_t char_count,gr::utf16 * char_buffer)63 size_t  TextSourceAdaptor::fetch(gr::toffset offset, size_t char_count, gr::utf16 * char_buffer)
64 {
65   assert(char_buffer);
66 
67   size_t copy_count =  std::min(size_t(maLayoutArgs.mnLength), char_count);
68   std::copy(maLayoutArgs.mpStr + offset, maLayoutArgs.mpStr + offset + copy_count, char_buffer);
69 
70   return copy_count;
71 }
72 
73 
fetch(gr::toffset,size_t,gr::utf8 *)74 size_t TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf8  *)
75 {
76     assert(false);
77     return 0;
78 }
79 
80 
getCharProperties(const int nCharIdx,int & min,int & lim,size_t & depth)81 inline void TextSourceAdaptor::getCharProperties(const int nCharIdx, int & min, int & lim, size_t & depth)
82 {
83     maLayoutArgs.ResetPos();
84     bool rtl = maLayoutArgs.mnFlags & SAL_LAYOUT_BIDI_RTL;
85     for(depth = ((rtl)? 1:0); maLayoutArgs.maRuns.GetRun(&min, &lim, &rtl); maLayoutArgs.maRuns.NextRun())
86     {
87         if (min > nCharIdx)
88             break;
89         // Only increase the depth when a change of direction occurs.
90         depth += int(rtl ^ bool(depth & 0x1));
91         if (min <= nCharIdx && nCharIdx < lim)
92             break;
93     }
94     // If there is no run for this position increment the depth, but don't
95     // change if this is out of bounds context
96     if (lim > 0 && nCharIdx >= lim && nCharIdx < maLayoutArgs.mnEndCharPos)
97         depth++;
98 }
99 
100 
getRightToLeft(gr::toffset nCharIdx)101 bool TextSourceAdaptor::getRightToLeft(gr::toffset nCharIdx)
102 {
103     size_t depth;
104     int min, lim = 0;
105     getCharProperties(nCharIdx, min, lim, depth);
106     //printf("getRtl %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth & 0x1);
107     return depth & 0x1;
108 }
109 
110 
getDirectionDepth(gr::toffset nCharIdx)111 unsigned int TextSourceAdaptor::getDirectionDepth(gr::toffset nCharIdx)
112 {
113     size_t depth;
114     int min, lim;
115     getCharProperties(nCharIdx, min, lim, depth);
116     //printf("getDirectionDepth %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth);
117     return depth;
118 }
119 
120 
getVerticalOffset(gr::toffset)121 float TextSourceAdaptor::getVerticalOffset(gr::toffset)
122 {
123     return 0.0f;    //TODO: Implement correctly
124 }
125 
getLanguage(gr::toffset)126 gr::isocode TextSourceAdaptor::getLanguage(gr::toffset)
127 {
128     if (mpFeatures && mpFeatures->hasLanguage())
129         return mpFeatures->getLanguage();
130     gr::isocode unknown = {{0,0,0,0}};
131     return unknown;
132 }
133 
propertyRange(gr::toffset nCharIdx)134 ext_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx)
135 {
136 
137     if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos))
138         return ext_std::make_pair(0, maLayoutArgs.mnMinCharPos);
139 
140     if (nCharIdx < mnEnd)
141         return ext_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd);
142 
143     return ext_std::make_pair(mnEnd, maLayoutArgs.mnLength);
144 }
145 
getFontFeatures(gr::toffset,gr::FeatureSetting * settings)146 size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings)
147 {
148     if (mpFeatures) return mpFeatures->getFontFeatures(settings);
149     return 0;
150 }
151 
152 
sameSegment(gr::toffset char_idx1,gr::toffset char_idx2)153 bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2)
154 {
155     const ext_std::pair<gr::toffset, gr::toffset>
156     range1 = propertyRange(char_idx1),
157     range2 = propertyRange(char_idx2);
158 
159     return range1 == range2;
160 }
161 
setFeatures(const grutils::GrFeatureParser * pFeatures)162 void TextSourceAdaptor::setFeatures(const grutils::GrFeatureParser * pFeatures)
163 {
164     mpFeatures = new grutils::GrFeatureParser(*pFeatures);
165 }
166