Mercurial > hg > xemacs-beta
comparison src/redisplay-x.c @ 3659:98af8a976fc3
[xemacs-hg @ 2006-11-05 22:31:31 by aidan]
Support specifying fonts for particular character sets in Mule; support
translation to ISO 10646-1 for Mule character sets without an otherwise
matching font; move to a vector of X11-charset-X11-registry instead of a
regex for the charset-registry property.
author | aidan |
---|---|
date | Sun, 05 Nov 2006 22:31:46 +0000 |
parents | 2b84dd8eb906 |
children | ec0171167c5d |
comparison
equal
deleted
inserted
replaced
3658:0db1aaedbbef | 3659:98af8a976fc3 |
---|---|
39 #include "gutter.h" | 39 #include "gutter.h" |
40 #include "redisplay.h" | 40 #include "redisplay.h" |
41 #include "sysdep.h" | 41 #include "sysdep.h" |
42 #include "window.h" | 42 #include "window.h" |
43 | 43 |
44 #ifdef MULE | |
45 #include "mule-ccl.h" | 44 #include "mule-ccl.h" |
46 #endif | 45 #include "charset.h" |
47 | 46 |
48 #include "console-x-impl.h" | 47 #include "console-x-impl.h" |
49 #include "glyphs-x.h" | 48 #include "glyphs-x.h" |
50 #include "objects-x-impl.h" | 49 #include "objects-x-impl.h" |
51 #include "xgccache.h" | 50 #include "xgccache.h" |
152 */ | 151 */ |
153 | 152 |
154 static int | 153 static int |
155 separate_textual_runs (unsigned char *text_storage, | 154 separate_textual_runs (unsigned char *text_storage, |
156 struct textual_run *run_storage, | 155 struct textual_run *run_storage, |
157 const Ichar *str, Charcount len) | 156 const Ichar *str, Charcount len, |
157 struct face_cachel *cachel) | |
158 { | 158 { |
159 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a | 159 Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a |
160 possible valid charset when | 160 possible valid charset when |
161 MULE is not defined */ | 161 MULE is not defined */ |
162 int runs_so_far = 0; | 162 int runs_so_far = 0, i; |
163 int i; | 163 Ibyte charset_leading_byte = LEADING_BYTE_ASCII; |
164 #ifdef MULE | 164 int dimension = 1, graphic = 0, need_ccl_conversion = 0; |
165 Lisp_Object ccl_prog; | |
165 struct ccl_program char_converter; | 166 struct ccl_program char_converter; |
166 int need_ccl_conversion = 0; | 167 |
167 #endif | 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; | |
180 #define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) translate_to_ucs_2 = (arg) | |
181 #endif /* MULE */ | |
182 #endif /* !USE_XFT */ | |
168 | 183 |
169 for (i = 0; i < len; i++) | 184 for (i = 0; i < len; i++) |
170 { | 185 { |
171 Ichar ch = str[i]; | 186 Ichar ch = str[i]; |
172 Lisp_Object charset; | 187 Lisp_Object charset; |
173 int byte1, byte2; /* #### why aren't these UExtbytes? */ | 188 int byte1, byte2; /* Not UExbytes because BREAKUP_ICHAR takes |
174 int dimension; | 189 the addresses of its arguments and |
175 int graphic; | 190 dereferences those addresses as integer |
176 | 191 pointers. */ |
177 BREAKUP_ICHAR (ch, charset, byte1, byte2); | 192 BREAKUP_ICHAR (ch, charset, byte1, byte2); |
178 dimension = XCHARSET_DIMENSION (charset); | |
179 graphic = XCHARSET_GRAPHIC (charset); | |
180 | 193 |
181 if (!EQ (charset, prev_charset)) | 194 if (!EQ (charset, prev_charset)) |
182 { | 195 { |
183 run_storage[runs_so_far].ptr = text_storage; | 196 run_storage[runs_so_far].ptr = text_storage; |
184 run_storage[runs_so_far].charset = charset; | 197 run_storage[runs_so_far].charset = charset; |
185 #ifdef USE_XFT | |
186 run_storage[runs_so_far].dimension = 2; | |
187 #else | |
188 run_storage[runs_so_far].dimension = dimension; | |
189 #endif | |
190 | 198 |
191 if (runs_so_far) | 199 if (runs_so_far) |
192 { | 200 { |
193 run_storage[runs_so_far - 1].len = | 201 run_storage[runs_so_far - 1].len = |
194 text_storage - run_storage[runs_so_far - 1].ptr; | 202 text_storage - run_storage[runs_so_far - 1].ptr; |
195 if (run_storage[runs_so_far - 1].dimension == 2) | 203 /* Checks the value for dimension from the previous run. */ |
196 run_storage[runs_so_far - 1].len >>= 1; | 204 if (2 == dimension) run_storage[runs_so_far - 1].len >>= 1; |
197 } | 205 } |
206 | |
207 charset_leading_byte = XCHARSET_LEADING_BYTE(charset); | |
208 | |
209 MAYBE_ASSIGN_TRANSLATE_TO_UCS_2 | |
210 (bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE | |
211 (cachel), | |
212 charset_leading_byte - MIN_LEADING_BYTE)); | |
213 | |
214 if (translate_to_ucs_2) | |
215 { | |
216 dimension = 2; | |
217 run_storage[runs_so_far].dimension = 2; | |
218 } | |
219 else | |
220 { | |
221 dimension = XCHARSET_DIMENSION (charset); | |
222 run_storage[runs_so_far].dimension = dimension; | |
223 #ifdef MULE | |
224 ccl_prog = XCHARSET_CCL_PROGRAM (charset); | |
225 if ((!NILP (ccl_prog)) | |
226 && (setup_ccl_program (&char_converter, ccl_prog) >= 0)) | |
227 { | |
228 need_ccl_conversion = 1; | |
229 } | |
230 else | |
231 { | |
232 /* The graphic property is only relevant if we're neither | |
233 doing the CCL conversion nor doing the UTF-16 | |
234 conversion; it's irrelevant otherwise. */ | |
235 graphic = XCHARSET_GRAPHIC (charset); | |
236 need_ccl_conversion = 0; | |
237 } | |
238 #endif /* MULE */ | |
239 } | |
240 prev_charset = charset; | |
241 | |
198 runs_so_far++; | 242 runs_so_far++; |
199 prev_charset = charset; | 243 } |
244 | |
245 if (translate_to_ucs_2) | |
246 { | |
247 UINT_16_BIT ucs2; | |
248 int ucs = ichar_to_unicode(ch); | |
249 | |
250 /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to | |
251 REPLACMENT CHARACTER. */ | |
252 ucs2 = (ucs & ~0xFFFF) ? 0xFFFD : ucs; | |
253 | |
254 /* Ignoring the "graphic" handling. */ | |
255 #ifdef USE_XFT | |
256 byte1 = ((unsigned char *) (&ucs2))[0]; | |
257 byte2 = ((unsigned char *) (&ucs2))[1]; | |
258 #else | |
259 byte1 = ((unsigned char *) (&ucs2))[1]; | |
260 byte2 = ((unsigned char *) (&ucs2))[0]; | |
261 #endif /* USE_XFT */ | |
262 } | |
200 #ifdef MULE | 263 #ifdef MULE |
201 { | 264 else if (need_ccl_conversion) |
202 Lisp_Object ccl_prog = XCHARSET_CCL_PROGRAM (charset); | 265 { |
203 if ((!NILP (ccl_prog)) | 266 char_converter.reg[0] = charset_leading_byte; |
204 && (setup_ccl_program (&char_converter, ccl_prog) >= 0)) | |
205 need_ccl_conversion = 1; | |
206 } | |
207 #endif | |
208 } | |
209 | |
210 #ifndef USE_XFT | |
211 if (graphic == 0) | |
212 { | |
213 byte1 &= 0x7F; | |
214 byte2 &= 0x7F; | |
215 } | |
216 else if (graphic == 1) | |
217 { | |
218 byte1 |= 0x80; | |
219 byte2 |= 0x80; | |
220 } | |
221 #ifdef MULE | |
222 if (need_ccl_conversion) | |
223 { | |
224 char_converter.reg[0] = XCHARSET_ID (charset); | |
225 char_converter.reg[1] = byte1; | 267 char_converter.reg[1] = byte1; |
226 char_converter.reg[2] = byte2; | 268 char_converter.reg[2] = byte2; |
227 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); | 269 ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING); |
228 byte1 = char_converter.reg[1]; | 270 byte1 = char_converter.reg[1]; |
229 byte2 = char_converter.reg[2]; | 271 byte2 = char_converter.reg[2]; |
230 } | 272 } |
273 else if (graphic == 0) | |
274 { | |
275 byte1 &= 0x7F; | |
276 byte2 &= 0x7F; | |
277 } | |
278 else | |
279 { | |
280 byte1 |= 0x80; | |
281 byte2 |= 0x80; | |
282 } | |
231 #endif /* MULE */ | 283 #endif /* MULE */ |
232 *text_storage++ = (unsigned char) byte1; | 284 |
233 /* This dimension stuff is broken if you want to use a two-dimensional | 285 *text_storage++ = (unsigned char)byte1; |
234 X11 font to display a single-dimensional character set, as is | 286 |
235 appropriate for the IPA (use one of the -iso10646-1 fonts) or some | 287 /* dimension can be two in non-Mule if we're translating to |
236 of the other non-standard character sets. */ | 288 Unicode. */ |
237 if (dimension == 2) | 289 if (2 == dimension) *text_storage++ = (unsigned char)byte2; |
238 *text_storage++ = (unsigned char) byte2; | |
239 #else /* USE_XFT */ | |
240 /* #### This is bogus as hell. XftChar16, aka FcChar16, is actually | |
241 unsigned short, and therefore is not suitable for indexing matrix | |
242 fonts such as the JIS fonts supplied with X11. But if this were | |
243 consistent, the XftDraw*8 and XftDraw*16 functions are pretty | |
244 incoherent, as then we not should allow anything but ISO 8859/1 | |
245 (ie, the first 256 code points of Unicode) in XftDraw*8. So it | |
246 looks like this depends on the font, not the charset. */ | |
247 { | |
248 XftChar16 xftchar16 = 0xFFFD; /* unsigned short */ | |
249 #ifndef MULE | |
250 int unicode = ch; | |
251 #else | |
252 int unicode = ichar_to_unicode (ch); | |
253 if (unicode < 0) | |
254 /* abort(); */ /* #### serious error, tables are corrupt | |
255 Unfortunately, not a valid assumption; this can happen with | |
256 composite characters. Fake it. */ | |
257 unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */ | |
258 else if (need_ccl_conversion) | |
259 /* #### maybe we should just ignore this and hope the font wins? */ | |
260 unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */ | |
261 else if (unicode > 65535) | |
262 unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */ | |
263 else | |
264 #endif | |
265 xftchar16 = (XftChar16) unicode; | |
266 /* #### endianness dependency? No, | |
267 apparently xft handles endianness for us; | |
268 the "big-endian" code works on Intel and PPC */ | |
269 #if 1 | |
270 /* big-endian or auto-endian */ | |
271 byte1 = ((unsigned char *) (&xftchar16))[0]; | |
272 byte2 = ((unsigned char *) (&xftchar16))[1]; | |
273 #else | |
274 /* little-endian */ | |
275 byte1 = ((unsigned char *) (&xftchar16))[1]; | |
276 byte2 = ((unsigned char *) (&xftchar16))[0]; | |
277 #endif | |
278 } | |
279 *text_storage++ = (unsigned char) byte1; | |
280 *text_storage++ = (unsigned char) byte2; | |
281 #endif /* USE_XFT */ | |
282 } | 290 } |
283 | 291 |
284 if (runs_so_far) | 292 if (runs_so_far) |
285 { | 293 { |
286 run_storage[runs_so_far - 1].len = | 294 run_storage[runs_so_far - 1].len = |
287 text_storage - run_storage[runs_so_far - 1].ptr; | 295 text_storage - run_storage[runs_so_far - 1].ptr; |
288 if (run_storage[runs_so_far - 1].dimension == 2) | 296 /* Dimension retains the relevant value for the run before it. */ |
297 if (2 == dimension) | |
289 run_storage[runs_so_far - 1].len >>= 1; | 298 run_storage[runs_so_far - 1].len >>= 1; |
290 } | 299 } |
291 | 300 |
292 return runs_so_far; | 301 return runs_so_far; |
293 } | 302 } |
359 unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); | 368 unsigned char *text_storage = (unsigned char *) ALLOCA (2 * len); |
360 struct textual_run *runs = alloca_array (struct textual_run, len); | 369 struct textual_run *runs = alloca_array (struct textual_run, len); |
361 int nruns; | 370 int nruns; |
362 int i; | 371 int i; |
363 | 372 |
364 nruns = separate_textual_runs (text_storage, runs, str, len); | 373 nruns = separate_textual_runs (text_storage, runs, str, len, |
374 cachel); | |
365 | 375 |
366 for (i = 0; i < nruns; i++) | 376 for (i = 0; i < nruns; i++) |
367 width_so_far += x_text_width_single_run (f, cachel, runs + i); | 377 width_so_far += x_text_width_single_run (f, cachel, runs + i); |
368 | 378 |
369 return width_so_far; | 379 return width_so_far; |
1012 ypos, clip_end - clip_start, | 1022 ypos, clip_end - clip_start, |
1013 height); | 1023 height); |
1014 } | 1024 } |
1015 | 1025 |
1016 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), | 1026 nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0), |
1017 Dynarr_length (buf)); | 1027 Dynarr_length (buf), cachel); |
1018 | 1028 |
1019 for (i = 0; i < nruns; i++) | 1029 for (i = 0; i < nruns; i++) |
1020 { | 1030 { |
1021 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); | 1031 Lisp_Object font = FACE_CACHEL_FONT (cachel, runs[i].charset); |
1022 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); | 1032 Lisp_Font_Instance *fi = XFONT_INSTANCE (font); |