2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 /* ---------------------------- included header files ---------------------- */
30 #include "FlocaleCharset.h"
31 #include "FftInterface.h"
32 #include "FRenderInit.h"
33 #include "PictureBase.h"
35 /* ---------------------------- local definitions -------------------------- */
37 /* ---------------------------- local macros ------------------------------- */
39 #define FFT_SET_ROTATED_90_MATRIX(m) \
40 ((m)->xx = (m)->yy = 0, (m)->xy = 1, (m)->yx = -1)
42 #define FFT_SET_ROTATED_270_MATRIX(m) \
43 ((m)->xx = (m)->yy = 0, (m)->xy = -1, (m)->yx = 1)
45 #define FFT_SET_ROTATED_180_MATRIX(m) \
46 ((m)->xx = (m)->yy = -1, (m)->xy = (m)->yx = 0)
48 /* ---------------------------- imports ------------------------------------ */
50 /* ---------------------------- included code files ------------------------ */
52 /* ---------------------------- local types -------------------------------- */
54 /* ---------------------------- forward declarations ----------------------- */
56 /* ---------------------------- local variables ---------------------------- */
58 static Display
*fftdpy
= NULL
;
60 static int fft_initialized
= False
;
62 /* ---------------------------- exported variables (globals) --------------- */
64 /* ---------------------------- local functions ---------------------------- */
67 void init_fft(Display
*dpy
)
70 fftscreen
= DefaultScreen(dpy
);
71 fft_initialized
= True
;
75 FftChar16
*FftUtf8ToFftString16(unsigned char *str
, int len
, int *nl
)
80 new = (FftChar16
*)safemalloc((len
+1)*sizeof(FftChar16
));
81 while(i
< len
&& str
[i
] != 0)
87 else if (str
[i
] <= 0xdf && i
+1 < len
)
89 new[j
] = ((str
[i
] & 0x1f) << 6) + (str
[i
+1] & 0x3f);
94 new[j
] = ((str
[i
] & 0x0f) << 12) +
95 ((str
[i
+1] & 0x3f) << 6) +
106 void FftSetupEncoding(
107 Display
*dpy
, FftFontType
*fftf
, char *encoding
, char *module
)
111 if (!FftSupport
|| fftf
== NULL
)
114 fftf
->encoding
= NULL
;
115 fftf
->str_encoding
= NULL
;
117 if (encoding
!= NULL
)
119 fftf
->str_encoding
= encoding
;
121 if (FftSupportUseXft2
)
123 if (encoding
!= NULL
)
125 fftf
->encoding
= encoding
;
128 FlocaleCharsetGetDefaultCharset(dpy
,NULL
)) != NULL
&&
129 StrEquals(fc
->x
,FLC_FFT_ENCODING_ISO8859_1
))
131 fftf
->encoding
= FLC_FFT_ENCODING_ISO8859_1
;
135 fftf
->encoding
= FLC_FFT_ENCODING_ISO10646_1
;
144 f
= (Fft1Font
*)fftf
->fftfont
;
145 while(i
< f
->pattern
->num
)
147 e
= &f
->pattern
->elts
[i
];
148 if (StrEquals(e
->object
, FFT_ENCODING
) &&
149 e
->values
->value
.u
.s
!= NULL
)
151 fftf
->encoding
= e
->values
->value
.u
.s
;
160 FftFont
*FftGetRotatedFont(
161 Display
*dpy
, FftFont
*f
, rotation_t rotation
)
163 FftPattern
*rotated_pat
;
165 FftMatrix
*pm
= NULL
;
171 rotated_pat
= FftPatternDuplicate(f
->pattern
);
173 if (rotated_pat
== NULL
)
178 if (rotation
== ROTATION_90
)
180 FFT_SET_ROTATED_90_MATRIX(&r
);
182 else if (rotation
== ROTATION_180
)
184 FFT_SET_ROTATED_180_MATRIX(&r
);
186 else if (rotation
== ROTATION_270
)
188 FFT_SET_ROTATED_270_MATRIX(&r
);
195 if ((FftPatternGetMatrix(
196 rotated_pat
, FFT_MATRIX
, 0, &pm
) == FftResultMatch
) && pm
)
198 /* rotate the matrice */
199 b
.xx
= r
.xx
* pm
->xx
+ r
.xy
* pm
->yx
;
200 b
.xy
= r
.xx
* pm
->xy
+ r
.xy
* pm
->yy
;
201 b
.yx
= r
.yx
* pm
->xx
+ r
.yy
* pm
->yx
;
202 b
.yy
= r
.yx
* pm
->xy
+ r
.yy
* pm
->yy
;
211 if (FftPatternDel(rotated_pat
, FFT_MATRIX
))
215 if (!FftPatternAddMatrix(rotated_pat
, FFT_MATRIX
, &b
))
219 rf
= FftFontOpenPattern(dpy
, rotated_pat
);
222 if (!rf
&& rotated_pat
)
224 FftPatternDestroy(rotated_pat
);
229 void FftPDumyFunc(void)
233 /* ---------------------------- interface functions ------------------------ */
235 void FftGetFontHeights(
236 FftFontType
*fftf
, int *height
, int *ascent
, int *descent
)
238 /* fft font height may be > fftfont->ascent + fftfont->descent, this
239 * depends on the minspace value */
240 *height
= fftf
->fftfont
->height
;
241 *ascent
= fftf
->fftfont
->ascent
;
242 *descent
= fftf
->fftfont
->descent
;
247 void FftGetFontWidths(
248 FlocaleFont
*flf
, int *max_char_width
)
252 /* FIXME: max_char_width should not be use in the all fvwm! */
253 if (FftUtf8Support
&& FLC_ENCODING_TYPE_IS_UTF_8(flf
->fc
))
255 FftTextExtentsUtf8(fftdpy
, flf
->fftf
.fftfont
, (FftChar8
*)"W",
260 FftTextExtents8(fftdpy
, flf
->fftf
.fftfont
, (FftChar8
*)"W", 1,
263 *max_char_width
= extents
.xOff
;
268 FftFontType
*FftGetFont(Display
*dpy
, char *fontname
, char *module
)
270 FftFont
*fftfont
= NULL
;
271 FftFontType
*fftf
= NULL
;
272 char *fn
= NULL
, *str_enc
= NULL
;
274 FftPattern
*src_pat
= NULL
, *load_pat
= NULL
;
279 if (!FftSupport
|| !(FRenderGetExtensionSupported() || 1))
287 if (!fft_initialized
)
291 /* Xft2 always load an USC-4 fonts, that we consider as an USC-2 font
292 * (i.e., an ISO106464-1 font) or an ISO8859-1 if the user ask for this
293 * or the locale charset is ISO8859-1.
294 * Xft1 support ISO106464-1, ISO8859-1 and others we load an
295 * ISO8859-1 font by default if the locale charset is ISO8859-1 and
296 * an ISO106464-1 one if this not the case */
297 if (matchWildcards("*?8859-1*", fontname
))
299 str_enc
= FLC_FFT_ENCODING_ISO8859_1
;
301 else if (matchWildcards("*?10646-1*", fontname
))
303 str_enc
= FLC_FFT_ENCODING_ISO10646_1
;
305 if (!FftSupportUseXft2
&& str_enc
== NULL
)
307 if ((fc
= FlocaleCharsetGetFLCXOMCharset()) != NULL
&&
308 StrEquals(fc
->x
,FLC_FFT_ENCODING_ISO8859_1
))
310 fn
= CatString2(fontname
,":encoding=ISO8859-1");
314 fn
= CatString2(fontname
,":encoding=ISO10646-1");
321 if ((src_pat
= FftNameParse(fn
)) == NULL
)
325 if ((load_pat
= FftFontMatch(dpy
, fftscreen
, src_pat
, &result
)) == NULL
)
330 if (FftPatternGetMatrix(
331 load_pat
, FFT_MATRIX
, 0, &a
) == FftResultMatch
&& a
)
352 if (FftPatternDel(load_pat
, FFT_MATRIX
))
356 if (!FftPatternAddMatrix(load_pat
, FFT_MATRIX
, &b
))
362 /* FIXME: other safety checking ? */
363 fftfont
= FftFontOpenPattern(dpy
, load_pat
);
369 fftf
= (FftFontType
*)safemalloc(sizeof(FftFontType
));
370 fftf
->fftfont
= fftfont
;
371 fftf
->fftfont_rotated_90
= NULL
;
372 fftf
->fftfont_rotated_180
= NULL
;
373 fftf
->fftfont_rotated_270
= NULL
;
374 FftSetupEncoding(dpy
, fftf
, str_enc
, module
);
379 FftPatternDestroy(src_pat
);
381 if (!fftf
&& load_pat
)
383 FftPatternDestroy(load_pat
);
389 Display
*dpy
, FlocaleFont
*flf
, FlocaleWinString
*fws
,
390 Pixel fg
, Pixel fgsh
, Bool has_fg_pixels
, int len
, unsigned long flags
)
392 FftDraw
*fftdraw
= NULL
;
393 typedef void (*DrawStringFuncType
)(
394 FftDraw
*fftdraw
, FftColor
*fft_fg
, FftFont
*uf
, int xt
,
395 int yt
, char *str
, int len
);
396 DrawStringFuncType DrawStringFunc
;
398 Bool free_str
= False
;
401 FftColor fft_fg
, fft_fgsh
;
406 flocale_gstp_args gstp_args
;
414 if (fws
->flags
.text_rotation
== ROTATION_90
) /* CW */
416 if (fftf
->fftfont_rotated_90
== NULL
)
418 fftf
->fftfont_rotated_90
=
419 FftGetRotatedFont(dpy
, fftf
->fftfont
,
420 fws
->flags
.text_rotation
);
422 uf
= fftf
->fftfont_rotated_90
;
423 #ifdef FFT_BUGGY_FREETYPE
424 y
= fws
->y
+ FftTextWidth(flf
, fws
->e_str
, len
);
428 x
= fws
->x
- FLF_SHADOW_BOTTOM_SIZE(flf
);
430 else if (fws
->flags
.text_rotation
== ROTATION_180
)
432 if (fftf
->fftfont_rotated_180
== NULL
)
434 fftf
->fftfont_rotated_180
=
435 FftGetRotatedFont(dpy
, fftf
->fftfont
,
436 fws
->flags
.text_rotation
);
438 uf
= fftf
->fftfont_rotated_180
;
440 x
= fws
->x
+ FftTextWidth(flf
, fws
->e_str
, len
);
442 else if (fws
->flags
.text_rotation
== ROTATION_270
)
444 if (fftf
->fftfont_rotated_270
== NULL
)
446 fftf
->fftfont_rotated_270
=
447 FftGetRotatedFont(dpy
, fftf
->fftfont
,
448 fws
->flags
.text_rotation
);
450 uf
= fftf
->fftfont_rotated_270
;
451 #ifdef FFT_BUGGY_FREETYPE
454 y
= fws
->y
+ FftTextWidth(flf
, fws
->e_str
, len
);
456 x
= fws
->x
- FLF_SHADOW_UPPER_SIZE(flf
);
468 fftdraw
= FftDrawCreate(dpy
, (Drawable
)fws
->win
, Pvisual
, Pcmap
);
469 if (fws
->flags
.has_clip_region
)
471 if (FftDrawSetClip(fftdraw
, fws
->clip_region
) == False
)
473 /* just to suppress a compiler warning */
482 XGetGCValues(dpy
, fws
->gc
, GCForeground
, &vr
))
484 xfg
.pixel
= vr
.foreground
;
489 fprintf(stderr
, "[fvwmlibs][FftDrawString]: ERROR --"
490 " cannot find color\n");
492 xfg
.pixel
= PictureBlackPixel();
495 XQueryColor(dpy
, Pcmap
, &xfg
);
496 alpha_factor
= ((fws
->flags
.has_colorset
)?
497 ((float)fws
->colorset
->fg_alpha_percent
/100) : 1);
498 /* Render uses premultiplied alpha */
499 fft_fg
.color
.red
= xfg
.red
* alpha_factor
;
500 fft_fg
.color
.green
= xfg
.green
* alpha_factor
;
501 fft_fg
.color
.blue
= xfg
.blue
* alpha_factor
;
502 fft_fg
.color
.alpha
= 0xffff * alpha_factor
;
503 fft_fg
.pixel
= xfg
.pixel
;
504 if (flf
->shadow_size
!= 0 && has_fg_pixels
)
506 XQueryColor(dpy
, Pcmap
, &xfgsh
);
507 fft_fgsh
.color
.red
= xfgsh
.red
* alpha_factor
;
508 fft_fgsh
.color
.green
= xfgsh
.green
* alpha_factor
;
509 fft_fgsh
.color
.blue
= xfgsh
.blue
* alpha_factor
;
510 fft_fgsh
.color
.alpha
= 0xffff * alpha_factor
;
511 fft_fgsh
.pixel
= xfgsh
.pixel
;
518 if (FftUtf8Support
&& FLC_ENCODING_TYPE_IS_UTF_8(flf
->fc
))
520 DrawStringFunc
= (DrawStringFuncType
)FftPDrawStringUtf8
;
522 else if (FLC_ENCODING_TYPE_IS_UTF_8(flf
->fc
))
524 DrawStringFunc
= (DrawStringFuncType
)FftPDrawString16
;
525 str
= (char *)FftUtf8ToFftString16(
526 (unsigned char *)fws
->e_str
, len
, &len
);
529 else if (FLC_ENCODING_TYPE_IS_USC_2(flf
->fc
))
531 DrawStringFunc
= (DrawStringFuncType
)FftPDrawString16
;
533 else if (FLC_ENCODING_TYPE_IS_USC_4(flf
->fc
))
535 DrawStringFunc
= (DrawStringFuncType
)FftPDrawString32
;
539 DrawStringFunc
= (DrawStringFuncType
)FftPDrawString8
;
542 FlocaleInitGstpArgs(&gstp_args
, flf
, fws
, x
, y
);
543 if (flf
->shadow_size
!= 0 && has_fg_pixels
)
545 while (FlocaleGetShadowTextPosition(&xt
, &yt
, &gstp_args
))
548 fftdraw
, &fft_fgsh
, uf
, xt
, yt
, str
, len
);
551 xt
= gstp_args
.orig_x
;
552 yt
= gstp_args
.orig_y
;
553 DrawStringFunc(fftdraw
, &fft_fg
, uf
, xt
, yt
, str
, len
);
555 if (free_str
&& str
!= NULL
)
559 FftDrawDestroy(fftdraw
);
564 int FftTextWidth(FlocaleFont
*flf
, char *str
, int len
)
573 if (FftUtf8Support
&& FLC_ENCODING_TYPE_IS_UTF_8(flf
->fc
))
576 fftdpy
, flf
->fftf
.fftfont
, (FftChar8
*)str
, len
,
578 result
= extents
.xOff
;
580 else if (FLC_ENCODING_TYPE_IS_UTF_8(flf
->fc
))
585 new = FftUtf8ToFftString16((unsigned char *)str
, len
, &nl
);
589 fftdpy
, flf
->fftf
.fftfont
, new, nl
, &extents
);
590 result
= extents
.xOff
;
594 else if (FLC_ENCODING_TYPE_IS_USC_2(flf
->fc
))
597 fftdpy
, flf
->fftf
.fftfont
, (FftChar16
*)str
, len
,
599 result
= extents
.xOff
;
601 else if (FLC_ENCODING_TYPE_IS_USC_4(flf
->fc
))
604 fftdpy
, flf
->fftf
.fftfont
, (FftChar32
*)str
, len
,
606 result
= extents
.xOff
;
611 fftdpy
, flf
->fftf
.fftfont
, (FftChar8
*)str
, len
,
613 result
= extents
.xOff
;
620 void FftPrintPatternInfo(FftFont
*f
, Bool vertical
)
622 /* FftPatternPrint use stdout */
624 printf("\n height: %i, ascent: %i, descent: %i, maw: %i\n",
625 f
->height
, f
->ascent
, f
->descent
, f
->max_advance_width
);
629 FftPatternPrint(f
->pattern
);
633 FftMatrix
*pm
= NULL
;
635 if (FftPatternGetMatrix(
636 f
->pattern
, FFT_MATRIX
, 0, &pm
) == FftResultMatch
&& pm
)
638 printf(" matrix: (%f %f %f %f)\n",
639 pm
->xx
, pm
->xy
, pm
->yx
, pm
->yy
);