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 */