1 : /* GRAPHITE2 LICENSING
2 :
3 : Copyright 2010, SIL International
4 : All rights reserved.
5 :
6 : This library is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU Lesser General Public License as published
8 : by the Free Software Foundation; either version 2.1 of License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : Lesser General Public License for more details.
15 :
16 : You should also have received a copy of the GNU Lesser General Public
17 : License along with this library in the file named "LICENSE".
18 : If not, write to the Free Software Foundation, 51 Franklin Street,
19 : Suite 500, Boston, MA 02110-1335, USA or visit their web page on the
20 : internet at http://www.fsf.org/licenses/lgpl.html.
21 :
22 : Alternatively, the contents of this file may be used under the terms of the
23 : Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
24 : License, as published by the Free Software Foundation, either version 2
25 : of the License or (at your option) any later version.
26 : */
27 : #include "graphite2/Segment.h"
28 : #include "inc/UtfCodec.h"
29 : #include "inc/Segment.h"
30 :
31 : using namespace graphite2;
32 :
33 : namespace
34 : {
35 :
36 0 : gr_segment* makeAndInitialize(const Font *font, const Face *face, uint32 script, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void* pStart, size_t nChars, int dir)
37 : {
38 0 : if (script == 0x20202020) script = 0;
39 0 : else if ((script & 0x00FFFFFF) == 0x00202020) script = script & 0xFF000000;
40 0 : else if ((script & 0x0000FFFF) == 0x00002020) script = script & 0xFFFF0000;
41 0 : else if ((script & 0x000000FF) == 0x00000020) script = script & 0xFFFFFF00;
42 : // if (!font) return NULL;
43 0 : Segment* pRes=new Segment(nChars, face, script, dir);
44 :
45 0 : pRes->read_text(face, pFeats, enc, pStart, nChars);
46 0 : if (!pRes->runGraphite())
47 : {
48 0 : delete pRes;
49 0 : return NULL;
50 : }
51 : // run the line break passes
52 : // run the substitution passes
53 0 : pRes->prepare_pos(font);
54 : // run the positioning passes
55 0 : pRes->finalise(font);
56 :
57 0 : return static_cast<gr_segment*>(pRes);
58 : }
59 :
60 :
61 : }
62 :
63 :
64 : template <typename utf_iter>
65 0 : inline size_t count_unicode_chars(utf_iter first, const utf_iter last, const void **error)
66 : {
67 0 : size_t n_chars = 0;
68 0 : uint32 usv = 0;
69 :
70 0 : if (last)
71 : {
72 0 : for (;first != last; ++first, ++n_chars)
73 0 : if ((usv = *first) == 0 || first.error()) break;
74 : }
75 : else
76 : {
77 0 : while ((usv = *first) != 0 && !first.error())
78 : {
79 0 : ++first;
80 0 : ++n_chars;
81 : }
82 : }
83 :
84 0 : if (error) *error = first.error() ? first : 0;
85 0 : return n_chars;
86 : }
87 :
88 : extern "C" {
89 :
90 0 : size_t gr_count_unicode_characters(gr_encform enc, const void* buffer_begin, const void* buffer_end/*don't go on or past end, If NULL then ignored*/, const void** pError) //Also stops on nul. Any nul is not in the count
91 : {
92 0 : assert(buffer_begin);
93 :
94 0 : switch (enc)
95 : {
96 0 : case gr_utf8: return count_unicode_chars<utf8::const_iterator>(buffer_begin, buffer_end, pError); break;
97 0 : case gr_utf16: return count_unicode_chars<utf16::const_iterator>(buffer_begin, buffer_end, pError); break;
98 0 : case gr_utf32: return count_unicode_chars<utf32::const_iterator>(buffer_begin, buffer_end, pError); break;
99 0 : default: return 0;
100 : }
101 : }
102 :
103 :
104 0 : gr_segment* gr_make_seg(const gr_font *font, const gr_face *face, gr_uint32 script, const gr_feature_val* pFeats, gr_encform enc, const void* pStart, size_t nChars, int dir)
105 : {
106 0 : const gr_feature_val * tmp_feats = 0;
107 0 : if (pFeats == 0)
108 0 : pFeats = tmp_feats = static_cast<const gr_feature_val*>(face->theSill().cloneFeatures(0));
109 0 : gr_segment * seg = makeAndInitialize(font, face, script, pFeats, enc, pStart, nChars, dir);
110 0 : delete tmp_feats;
111 :
112 0 : return seg;
113 : }
114 :
115 :
116 0 : void gr_seg_destroy(gr_segment* p)
117 : {
118 0 : delete p;
119 0 : }
120 :
121 :
122 0 : float gr_seg_advance_X(const gr_segment* pSeg/*not NULL*/)
123 : {
124 0 : assert(pSeg);
125 0 : return pSeg->advance().x;
126 : }
127 :
128 :
129 0 : float gr_seg_advance_Y(const gr_segment* pSeg/*not NULL*/)
130 : {
131 0 : assert(pSeg);
132 0 : return pSeg->advance().y;
133 : }
134 :
135 :
136 0 : unsigned int gr_seg_n_cinfo(const gr_segment* pSeg/*not NULL*/)
137 : {
138 0 : assert(pSeg);
139 0 : return pSeg->charInfoCount();
140 : }
141 :
142 :
143 0 : const gr_char_info* gr_seg_cinfo(const gr_segment* pSeg/*not NULL*/, unsigned int index/*must be <number_of_CharInfo*/)
144 : {
145 0 : assert(pSeg);
146 0 : return static_cast<const gr_char_info*>(pSeg->charinfo(index));
147 : }
148 :
149 0 : unsigned int gr_seg_n_slots(const gr_segment* pSeg/*not NULL*/)
150 : {
151 0 : assert(pSeg);
152 0 : return pSeg->slotCount();
153 : }
154 :
155 0 : const gr_slot* gr_seg_first_slot(gr_segment* pSeg/*not NULL*/)
156 : {
157 0 : assert(pSeg);
158 0 : return static_cast<const gr_slot*>(pSeg->first());
159 : }
160 :
161 0 : const gr_slot* gr_seg_last_slot(gr_segment* pSeg/*not NULL*/)
162 : {
163 0 : assert(pSeg);
164 0 : return static_cast<const gr_slot*>(pSeg->last());
165 : }
166 :
167 0 : void gr_seg_justify(gr_segment* pSeg/*not NULL*/, gr_slot* pSlot/*not NULL*/, const gr_font *pFont, double width, enum gr_justFlags flags, gr_slot *pFirst, gr_slot *pLast)
168 : {
169 0 : assert(pSeg);
170 0 : assert(pSlot);
171 0 : pSeg->justify(pSlot, pFont, width, justFlags(flags), pFirst, pLast);
172 0 : }
173 :
174 : } // extern "C"
|