1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 // We need this to enable namespace support in libgrengine headers.
32 #define GR_NAMESPACE
33 
34 // Header files
35 //
36 // Standard Library
37 #include <string>
38 #include <cassert>
39 #include "graphite_textsrc.hxx"
40 #include <graphite_features.hxx>
41 
42 // class TextSourceAdaptor implementation.
43 //
44 TextSourceAdaptor::~TextSourceAdaptor()
45 {
46     delete mpFeatures;
47 }
48 
49 gr::UtfType TextSourceAdaptor::utfEncodingForm() {
50     return gr::kutf16;
51 }
52 
53 
54 size_t TextSourceAdaptor::getLength()
55 {
56     return maLayoutArgs.mnLength;
57 }
58 
59 
60 size_t  TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf32 *)
61 {
62     assert(false);
63     return 0;
64 }
65 
66 
67 size_t  TextSourceAdaptor::fetch(gr::toffset offset, size_t char_count, gr::utf16 * char_buffer)
68 {
69   assert(char_buffer);
70 
71   size_t copy_count =  std::min(size_t(maLayoutArgs.mnLength), char_count);
72   std::copy(maLayoutArgs.mpStr + offset, maLayoutArgs.mpStr + offset + copy_count, char_buffer);
73 
74   return copy_count;
75 }
76 
77 
78 size_t TextSourceAdaptor::fetch(gr::toffset, size_t, gr::utf8  *)
79 {
80     assert(false);
81     return 0;
82 }
83 
84 
85 inline void TextSourceAdaptor::getCharProperties(const int nCharIdx, int & min, int & lim, size_t & depth)
86 {
87     maLayoutArgs.ResetPos();
88     bool rtl = maLayoutArgs.mnFlags & SAL_LAYOUT_BIDI_RTL;
89     for(depth = ((rtl)? 1:0); maLayoutArgs.maRuns.GetRun(&min, &lim, &rtl); maLayoutArgs.maRuns.NextRun())
90     {
91         if (min > nCharIdx)
92             break;
93         // Only increase the depth when a change of direction occurs.
94         depth += int(rtl ^ bool(depth & 0x1));
95         if (min <= nCharIdx && nCharIdx < lim)
96             break;
97     }
98     // If there is no run for this position increment the depth, but don't
99     // change if this is out of bounds context
100     if (lim > 0 && nCharIdx >= lim && nCharIdx < maLayoutArgs.mnEndCharPos)
101         depth++;
102 }
103 
104 
105 bool TextSourceAdaptor::getRightToLeft(gr::toffset nCharIdx)
106 {
107     size_t depth;
108     int min, lim = 0;
109     getCharProperties(nCharIdx, min, lim, depth);
110     //printf("getRtl %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth & 0x1);
111     return depth & 0x1;
112 }
113 
114 
115 unsigned int TextSourceAdaptor::getDirectionDepth(gr::toffset nCharIdx)
116 {
117     size_t depth;
118     int min, lim;
119     getCharProperties(nCharIdx, min, lim, depth);
120     //printf("getDirectionDepth %d,%x=%d\n", nCharIdx, maLayoutArgs.mpStr[nCharIdx], depth);
121     return depth;
122 }
123 
124 
125 float TextSourceAdaptor::getVerticalOffset(gr::toffset)
126 {
127     return 0.0f;    //TODO: Implement correctly
128 }
129 
130 gr::isocode TextSourceAdaptor::getLanguage(gr::toffset)
131 {
132     if (mpFeatures && mpFeatures->hasLanguage())
133         return mpFeatures->getLanguage();
134     gr::isocode unknown = {{0,0,0,0}};
135     return unknown;
136 }
137 
138 ext_std::pair<gr::toffset, gr::toffset> TextSourceAdaptor::propertyRange(gr::toffset nCharIdx)
139 {
140 
141     if (nCharIdx < unsigned(maLayoutArgs.mnMinCharPos))
142         return ext_std::make_pair(0, maLayoutArgs.mnMinCharPos);
143 
144     if (nCharIdx < mnEnd)
145         return ext_std::make_pair(maLayoutArgs.mnMinCharPos, mnEnd);
146 
147     return ext_std::make_pair(mnEnd, maLayoutArgs.mnLength);
148 }
149 
150 size_t TextSourceAdaptor::getFontFeatures(gr::toffset, gr::FeatureSetting * settings)
151 {
152     if (mpFeatures) return mpFeatures->getFontFeatures(settings);
153     return 0;
154 }
155 
156 
157 bool TextSourceAdaptor::sameSegment(gr::toffset char_idx1, gr::toffset char_idx2)
158 {
159     const ext_std::pair<gr::toffset, gr::toffset>
160     range1 = propertyRange(char_idx1),
161     range2 = propertyRange(char_idx2);
162 
163     return range1 == range2;
164 }
165 
166 void TextSourceAdaptor::setFeatures(const grutils::GrFeatureParser * pFeatures)
167 {
168     mpFeatures = new grutils::GrFeatureParser(*pFeatures);
169 }
170