1 /* Copyright (C) 2000, 2003  Free Software Foundation
2 
3    This file is part of libgcj.
4 
5 This software is copyrighted work licensed under the terms of the
6 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7 details.  */
8 
9 #include <X11/Xlib.h>
10 
11 #include <gcj/cni.h>
12 #include <gnu/gcj/RawData.h>
13 #include <java/lang/String.h>
14 
15 #include <gnu/gcj/xlib/Display.h>
16 #include <gnu/gcj/xlib/Font.h>
17 #include <gnu/gcj/xlib/XException.h>
18 
loadFontImpl(Display * display,jstring lfdNamePattern)19 gnu::gcj::RawData* gnu::gcj::xlib::Font::loadFontImpl(Display* display,
20 						  jstring lfdNamePattern)
21 {
22   ::Display* dpy = (::Display*) display->display;
23   int len = JvGetStringUTFLength(lfdNamePattern);
24   char cName[len+1];
25   JvGetStringUTFRegion(lfdNamePattern, 0, lfdNamePattern->length(),
26 		       cName);
27   cName[len] = '\0';
28 
29   XFontStruct* fontStruct = XLoadQueryFont(dpy, cName);
30   if (fontStruct == 0)
31     {
32       throw new XException(JvNewStringLatin1("font not found"));
33     }
34 
35   return reinterpret_cast<gnu::gcj::RawData*>(fontStruct);
36 }
37 
getXIDFromStruct(gnu::gcj::RawData * structure)38 jint gnu::gcj::xlib::Font::getXIDFromStruct(gnu::gcj::RawData* structure)
39 {
40   XFontStruct* fontStruct = (XFontStruct*) structure;
41   return fontStruct->fid;
42 }
43 
getMaxAscent()44 jint gnu::gcj::xlib::Font::getMaxAscent()
45 {
46   XFontStruct* fontStruct = (XFontStruct*) structure;
47   return fontStruct->max_bounds.ascent+1;   // +1 to include the baseline
48 }
49 
getMaxDescent()50 jint gnu::gcj::xlib::Font::getMaxDescent()
51 {
52   XFontStruct* fontStruct = (XFontStruct*) structure;
53   return fontStruct->max_bounds.descent-1;  // -1 to exclude the baseline
54 }
55 
getAscent()56 jint gnu::gcj::xlib::Font::getAscent()
57 {
58   XFontStruct* fontStruct = (XFontStruct*) structure;
59   jint returnValue = fontStruct->ascent;
60   if (fontStruct->min_byte1==0 && fontStruct->min_char_or_byte2<=(unsigned)'O')
61     returnValue = fontStruct
62         ->per_char[(unsigned)'O'-fontStruct->min_char_or_byte2]
63         .ascent;
64   return returnValue+1;  // +1 to include the baseline
65 }
66 
getDescent()67 jint gnu::gcj::xlib::Font::getDescent()
68 {
69   XFontStruct* fontStruct = (XFontStruct*) structure;
70   jint returnValue = fontStruct->descent;
71   if (fontStruct->min_byte1==0 && fontStruct->min_char_or_byte2<=(unsigned)'y')
72     returnValue = fontStruct
73         ->per_char[(unsigned)'y'-fontStruct->min_char_or_byte2]
74         .descent;
75   return returnValue-1;  // -1 to exclude the baseline
76 }
77 
getStringWidth(::java::lang::String * text)78 jint gnu::gcj::xlib::Font::getStringWidth(::java::lang::String* text)
79 {
80   XFontStruct* fontStruct = (XFontStruct*) structure;
81 
82   // FIXME: Convert to the character set used in the font, which may
83   // or may not be unicode. For now, treat everything as 16-bit and
84   // use character codes directly, which should be OK for unicode or
85   // 8-bit ascii fonts.
86   jint length = text->length();
87   jchar* txt = JvGetStringChars(text);
88   XChar2b xwchars[length];
89   for (int i=0; i<length; i++)
90     {
91       XChar2b* xc = &(xwchars[i]);
92       jchar jc = txt[i];
93       xc->byte1 = (jc >> 8) & 0xff;
94       xc->byte2 = jc & 0xff;
95     }
96   return XTextWidth16(fontStruct, xwchars, length);
97 }
98 
finalize()99 void gnu::gcj::xlib::Font::finalize()
100 {
101   if (structure != 0)
102     {
103       ::Display* dpy = (::Display*) display->display;
104       XFontStruct* fontStruct = (XFontStruct*) structure;
105       int result = XFreeFont(dpy, fontStruct);
106 
107       if (result == BadFont)
108 	throw new XException(display, result);
109 
110       structure = 0; xid = 0;
111     }
112 }
113 
114