Mercurial > hg > xemacs-beta
comparison src/redisplay-x.c @ 3895:a3c2418313d5
[xemacs-hg @ 2007-04-05 02:09:06 by stephent]
Refactor separate_textual_runs, part 1 <87648fwhqx.fsf@uwakimon.sk.tsukuba.ac.jp>
author | stephent |
---|---|
date | Thu, 05 Apr 2007 02:09:08 +0000 |
parents | ec0171167c5d |
children | 7bde3a686fda |
comparison
equal
deleted
inserted
replaced
3894:714d319f4739 | 3895:a3c2418313d5 |
---|---|
131 | 131 |
132 Returns the number of runs actually used. */ | 132 Returns the number of runs actually used. */ |
133 | 133 |
134 /* Notes on Xft implementation | 134 /* Notes on Xft implementation |
135 | 135 |
136 - Xft Reloaded, v.4, uses a function like that in redisplay-msw.c to | |
137 handle all characters. However, instead of using an appropriate | |
138 character width for each run, it just uses UTF-8 for all runs. This | |
139 is not obviously a bad idea, but (for Han characters etc) the estimate | |
140 of TEXT_STORAGE allocation needed is (3 * len), and for characters not | |
141 in the BMP, it's (4 * len). | |
142 - With Unicode, we're no longer going to have repertoires reified as | 136 - With Unicode, we're no longer going to have repertoires reified as |
143 charsets. (Not that we ever really did, what with corporate variants, | 137 charsets. (Not that we ever really did, what with corporate variants, |
144 and so on.) So we really should be querying the face for the desired | 138 and so on.) So we really should be querying the face for the desired |
145 font, rather than the character for the charset, and that's what would | 139 font, rather than the character for the charset, and that's what would |
146 determine the separation into runs. | 140 determine the separation into runs. |
148 seem to be just bigendian Unicode. So there's actually no need to use | 142 seem to be just bigendian Unicode. So there's actually no need to use |
149 the 8-bit versions in computing runs and runes, it would seem. | 143 the 8-bit versions in computing runs and runes, it would seem. |
150 - Mule won't "just work"; substantially more effort seems needed. | 144 - Mule won't "just work"; substantially more effort seems needed. |
151 */ | 145 */ |
152 | 146 |
147 #if !defined(USE_XFT) && !defined(MULE) | |
153 static int | 148 static int |
154 separate_textual_runs (unsigned char *text_storage, | 149 separate_textual_runs_nomule (unsigned char *text_storage, |
155 struct textual_run *run_storage, | 150 struct textual_run *run_storage, |
156 const Ichar *str, Charcount len, | 151 const Ichar *str, Charcount len, |
157 struct face_cachel *cachel) | 152 struct face_cachel *UNUSED(cachel)) |
153 { | |
154 int i; | |
155 if (!len) | |
156 return 0; | |
157 | |
158 run_storage[0].ptr = text_storage; | |
159 run_storage[0].len = len; | |
160 run_storage[0].dimension = 1; | |
161 run_storage[0].charset = Qnil; | |
162 | |
163 memcpy (text_storage, str, len); | |
164 return 1; | |
165 } | |
166 #endif | |
167 | |
168 #if defined(USE_XFT) && !defined(MULE) | |
169 static int | |
170 separate_textual_runs_xft_nomule (unsigned char *text_storage, | |
171 struct textual_run *run_storage, | |
172 const Ichar *str, Charcount len, | |
173 struct face_cachel *UNUSED(cachel)) | |
174 { | |
175 int i; | |
176 if (!len) | |
177 return 0; | |
178 | |
179 run_storage[0].ptr = text_storage; | |
180 run_storage[0].len = len; | |
181 run_storage[0].dimension = 2; | |
182 run_storage[0].charset = Qnil; | |
183 | |
184 for (i = 0; i < len; i++) | |
185 { | |
186 *(XftChar16 *)text_storage = str[i]; | |
187 text_storage += sizeof(XftChar16); | |
188 } | |
189 return 1; | |
190 } | |
191 #endif | |
192 | |
193 #if defined(USE_XFT) && defined(MULE) | |
194 static int | |
195 separate_textual_runs_xft_mule (unsigned char *text_storage, | |
196 struct textual_run *run_storage, | |
197 const Ichar *str, Charcount len, | |
198 struct face_cachel *UNUSED(cachel)) | |
199 { | |
200 Lisp_Object prev_charset = Qnil; | |
201 int runs_so_far = 0, i; | |
202 | |
203 run_storage[0].ptr = text_storage; | |
204 run_storage[0].len = len; | |
205 run_storage[0].dimension = 2; | |
206 run_storage[0].charset = Qnil; | |
207 | |
208 for (i = 0; i < len; i++) | |
209 { | |
210 Ichar ch = str[i]; | |
211 Lisp_Object charset = ichar_charset(ch); | |
212 int ucs = ichar_to_unicode(ch); | |
213 | |
214 /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to | |
215 REPLACMENT CHARACTER. */ | |
216 /* That means we can't handle characters outside of the BMP for now */ | |
217 ucs = (ucs & ~0xFFFF) ? 0xFFFD : ucs; | |
218 | |
219 if (!EQ (charset, prev_charset)) | |
220 { | |
221 if (runs_so_far) | |
222 run_storage[runs_so_far-1].len = (text_storage - run_storage[runs_so_far-1].ptr) >> 1; | |
223 run_storage[runs_so_far].ptr = text_storage; | |
224 run_storage[runs_so_far].dimension = 2; | |
225 run_storage[runs_so_far].charset = charset; | |
226 prev_charset = charset; | |
227 runs_so_far++; | |
228 } | |
229 | |
230 *(XftChar16 *)text_storage = ucs; | |
231 text_storage += sizeof(XftChar16); | |
232 } | |
233 | |
234 if (runs_so_far) | |
235 run_storage[runs_so_far-1].len = (text_storage - run_storage[runs_so_far-1].ptr) >> 1; | |
236 return runs_so_far; | |
237 } | |
238 #endif | |
239 | |
240 #if !defined(USE_XFT) && defined(MULE) | |
241 static int | |
242 separate_textual_runs_mule (unsigned char *text_storage, | |
243 struct textual_run *run_storage, | |
244 const Ichar *str, Charcount len, | |
245 struct face_cachel *cachel) | |
158 { | 246 { |
159 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a | 247 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a |
160 possible valid charset when | 248 possible valid charset when |
161 MULE is not defined */ | 249 MULE is not defined */ |
162 int runs_so_far = 0, i; | 250 int runs_so_far = 0, i; |
163 Ibyte charset_leading_byte = LEADING_BYTE_ASCII; | 251 Ibyte charset_leading_byte = LEADING_BYTE_ASCII; |
164 int dimension = 1, graphic = 0, need_ccl_conversion = 0; | 252 int dimension = 1, graphic = 0, need_ccl_conversion = 0; |
165 Lisp_Object ccl_prog; | 253 Lisp_Object ccl_prog; |
166 struct ccl_program char_converter; | 254 struct ccl_program char_converter; |
167 | 255 |
168 #ifdef USE_XFT | |
169 #define translate_to_ucs_2 1 /* Translate to UTF-16 unconditionally. */ | |
170 #define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) (void)(arg) /* Empty, | |
171 may avoid some | |
172 warnings. */ | |
173 #else /* USE_XFT */ | |
174 #ifndef MULE | |
175 #define translate_to_ucs_2 0 /* We don't support falling back to | |
176 iso10646-1 without MULE */ | |
177 #define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) (void)(arg) | |
178 #else /* if MULE */ | |
179 int translate_to_ucs_2 = 0; | 256 int translate_to_ucs_2 = 0; |
180 #define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) translate_to_ucs_2 = (arg) | |
181 #endif /* MULE */ | |
182 #endif /* !USE_XFT */ | |
183 | 257 |
184 for (i = 0; i < len; i++) | 258 for (i = 0; i < len; i++) |
185 { | 259 { |
186 Ichar ch = str[i]; | 260 Ichar ch = str[i]; |
187 Lisp_Object charset; | 261 Lisp_Object charset; |
204 if (2 == dimension) run_storage[runs_so_far - 1].len >>= 1; | 278 if (2 == dimension) run_storage[runs_so_far - 1].len >>= 1; |
205 } | 279 } |
206 | 280 |
207 charset_leading_byte = XCHARSET_LEADING_BYTE(charset); | 281 charset_leading_byte = XCHARSET_LEADING_BYTE(charset); |
208 | 282 |
209 MAYBE_ASSIGN_TRANSLATE_TO_UCS_2 | 283 translate_to_ucs_2 = |
210 (bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE | 284 bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE |
211 (cachel), | 285 (cachel), |
212 charset_leading_byte - MIN_LEADING_BYTE)); | 286 charset_leading_byte - MIN_LEADING_BYTE); |
213 | 287 |
214 if (translate_to_ucs_2) | 288 if (translate_to_ucs_2) |
215 { | 289 { |
216 dimension = 2; | 290 dimension = 2; |
217 run_storage[runs_so_far].dimension = 2; | 291 run_storage[runs_so_far].dimension = 2; |
218 } | 292 } |
219 else | 293 else |
220 { | 294 { |
221 dimension = XCHARSET_DIMENSION (charset); | 295 dimension = XCHARSET_DIMENSION (charset); |
222 run_storage[runs_so_far].dimension = dimension; | 296 run_storage[runs_so_far].dimension = dimension; |
223 #ifdef MULE | 297 |
224 ccl_prog = XCHARSET_CCL_PROGRAM (charset); | 298 ccl_prog = XCHARSET_CCL_PROGRAM (charset); |
225 if ((!NILP (ccl_prog)) | 299 if ((!NILP (ccl_prog)) |
226 && (setup_ccl_program (&char_converter, ccl_prog) >= 0)) | 300 && (setup_ccl_program (&char_converter, ccl_prog) >= 0)) |
227 { | 301 { |
228 need_ccl_conversion = 1; | 302 need_ccl_conversion = 1; |
233 doing the CCL conversion nor doing the UTF-16 | 307 doing the CCL conversion nor doing the UTF-16 |
234 conversion; it's irrelevant otherwise. */ | 308 conversion; it's irrelevant otherwise. */ |
235 graphic = XCHARSET_GRAPHIC (charset); | 309 graphic = XCHARSET_GRAPHIC (charset); |
236 need_ccl_conversion = 0; | 310 need_ccl_conversion = 0; |
237 } | 311 } |
238 #endif /* MULE */ | |
239 } | 312 } |
240 prev_charset = charset; | 313 prev_charset = charset; |
241 | 314 |
242 runs_so_far++; | 315 runs_so_far++; |
243 } | 316 } |
244 | 317 |
245 if (translate_to_ucs_2) | 318 if (translate_to_ucs_2) |
246 { | 319 { |
247 UINT_16_BIT ucs2; | |
248 #ifdef MULE | |
249 int ucs = ichar_to_unicode(ch); | 320 int ucs = ichar_to_unicode(ch); |
250 #else | |
251 int ucs = ch; | |
252 #endif | |
253 /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to | 321 /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to |
254 REPLACMENT CHARACTER. */ | 322 REPLACMENT CHARACTER. */ |
255 ucs2 = (ucs & ~0xFFFF) ? 0xFFFD : ucs; | 323 ucs = (ucs & ~0xFFFF) ? 0xFFFD : ucs; |
256 | 324 |
257 /* Ignoring the "graphic" handling. */ | 325 /* Ignoring the "graphic" handling. */ |
258 #ifdef USE_XFT | 326 byte1 = ucs >> 8; |
259 byte1 = ((unsigned char *) (&ucs2))[0]; | 327 byte2 = ucs; |
260 byte2 = ((unsigned char *) (&ucs2))[1]; | 328 } |
261 #else | |
262 byte1 = ((unsigned char *) (&ucs2))[1]; | |
263 byte2 = ((unsigned char *) (&ucs2))[0]; | |
264 #endif /* USE_XFT */ | |
265 } | |
266 #ifdef MULE | |
267 else if (need_ccl_conversion) | 329 else if (need_ccl_conversion) |
268 { | 330 { |
269 char_converter.reg[0] = charset_leading_byte; | 331 char_converter.reg[0] = charset_leading_byte; |
270 char_converter.reg[1] = byte1; | 332 char_converter.reg[1] = byte1; |
271 char_converter.reg[2] = byte2; | 333 char_converter.reg[2] = byte2; |
281 else | 343 else |
282 { | 344 { |
283 byte1 |= 0x80; | 345 byte1 |= 0x80; |
284 byte2 |= 0x80; | 346 byte2 |= 0x80; |
285 } | 347 } |
286 #endif /* MULE */ | |
287 | 348 |
288 *text_storage++ = (unsigned char)byte1; | 349 *text_storage++ = (unsigned char)byte1; |
289 | 350 |
290 /* dimension can be two in non-Mule if we're translating to | |
291 Unicode. */ | |
292 if (2 == dimension) *text_storage++ = (unsigned char)byte2; | 351 if (2 == dimension) *text_storage++ = (unsigned char)byte2; |
293 } | 352 } |
294 | 353 |
295 if (runs_so_far) | 354 if (runs_so_far) |
296 { | 355 { |
300 if (2 == dimension) | 359 if (2 == dimension) |
301 run_storage[runs_so_far - 1].len >>= 1; | 360 run_storage[runs_so_far - 1].len >>= 1; |
302 } | 361 } |
303 | 362 |
304 return runs_so_far; | 363 return runs_so_far; |
364 } | |
365 #endif | |
366 | |
367 static int | |
368 separate_textual_runs (unsigned char *text_storage, | |
369 struct textual_run *run_storage, | |
370 const Ichar *str, Charcount len, | |
371 struct face_cachel *cachel) | |
372 { | |
373 #if defined(USE_XFT) && defined(MULE) | |
374 return separate_textual_runs_xft_mule(text_storage, run_storage, str, len, cachel); | |
375 #endif | |
376 #if defined(USE_XFT) && !defined(MULE) | |
377 return separate_textual_runs_xft_nomule(text_storage, run_storage, str, len, cachel); | |
378 #endif | |
379 #if !defined(USE_XFT) && defined(MULE) | |
380 return separate_textual_runs_mule(text_storage, run_storage, str, len, cachel); | |
381 #endif | |
382 #if !defined(USE_XFT) && !defined(MULE) | |
383 return separate_textual_runs_nomule(text_storage, run_storage, str, len, cachel); | |
384 #endif | |
305 } | 385 } |
306 | 386 |
307 /****************************************************************************/ | 387 /****************************************************************************/ |
308 /* */ | 388 /* */ |
309 /* X output routines */ | 389 /* X output routines */ |