1 /* QuesoGLC
2  * A free implementation of the OpenGL Character Renderer (GLC)
3  * Copyright (c) 2002, 2004-2008, Bertrand Coconnier
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 /* $Id: internal.h 830 2008-08-19 23:29:41Z bcoconni $ */
20 
21 /** \file
22  *  header of all private functions that are used throughout the library.
23  */
24 
25 #ifndef __glc_internal_h
26 #define __glc_internal_h
27 
28 #include <stdlib.h>
29 
30 #ifndef DEBUGMODE
31 #define NDEBUG
32 #endif
33 #include <assert.h>
34 
35 #ifdef HAVE_LIBGLEW
36 #include <GL/glew.h>
37 #else
38 #include "GL/glew.h"
39 #endif
40 #define GLCAPI GLEWAPI
41 #include "GL/glc.h"
42 #ifdef HAVE_CONFIG_H
43 #include "qglc_config.h"
44 #include <ft2build.h>
45 #include FT_FREETYPE_H
46 #if defined(HAVE_FT_CACHE) && defined(FT_CACHE_H)
47 #define GLC_FT_CACHE
48 #endif
49 #endif
50 
51 #define GLCchar8  FcChar8
52 #define GLCchar16  FcChar16
53 #define GLCchar32 FcChar32
54 #define GLCuint   FT_UInt
55 #define GLClong   FT_Long
56 #define GLCulong  FT_ULong
57 
58 #include "ofont.h"
59 
60 #define GLC_OUT_OF_RANGE_LEN	11
61 #define GLC_EPSILON		1E-6
62 #define GLC_POINT_SIZE		128
63 #define GLC_TEXTURE_SIZE        64
64 
65 #if defined(__GNUC__)
66 # define GLC_UNUSED_ARG(_arg) GLC_UNUSED_ ## _arg __attribute__((unused))
67 #elif defined(__LCLINT__)
68 # define GLC_UNUSED_ARG(_arg) /*@unused@*/ GLC_UNUSED_ ## _arg
69 #else
70 # define GLC_UNUSED_ARG(_arg) GLC_UNUSED_ ## _arg
71 #endif
72 
73 /* Definition of the GLC_INIT_THREAD macro : it is some sort of an equivalent to
74  * XInitThreads(). It allows to get rid of pthread_get_specific()/TlsGetValue()
75  * when only one thread is used and to fallback to the usual thread management
76  * if more than one thread is used.
77  * If Thread Local Storage is used the macro does nothing.
78  */
79 #ifdef __WIN32__
80 # define GLC_INIT_THREAD() \
81   if (!InterlockedCompareExchange(&__glcCommonArea.__glcInitThreadOnce, 1, 0)) \
82     __glcInitThread();
83 #elif !defined(HAVE_TLS)
84 # define GLC_INIT_THREAD() \
85   pthread_once(&__glcCommonArea.__glcInitThreadOnce, __glcInitThread);
86 #else
87 #define GLC_INIT_THREAD()
88 #endif
89 
90 /* Definition of the GLC_GET_THREAD_AREA macro */
91 #ifdef __WIN32__
92 # define GLC_GET_THREAD_AREA() \
93   (((__glcCommonArea.threadID == GetCurrentThreadId()) && __glcThreadArea) ? \
94     __glcThreadArea : __glcGetThreadArea())
95 #elif !defined(HAVE_TLS)
96 # define GLC_GET_THREAD_AREA() \
97   ((pthread_equal(__glcCommonArea.threadID, pthread_self()) && __glcThreadArea) ? \
98     __glcThreadArea : __glcGetThreadArea())
99 #else
100 # define GLC_GET_THREAD_AREA() &__glcTlsThreadArea
101 #endif
102 
103 /* Definition of the GLC_GET_CURRENT_CONTEXT macro */
104 #ifdef __WIN32__
105 # define GLC_GET_CURRENT_CONTEXT() \
106   (((__glcCommonArea.threadID == GetCurrentThreadId()) && __glcThreadArea) ? \
107     __glcThreadArea->currentContext : __glcGetCurrent())
108 #elif !defined(HAVE_TLS)
109 # define GLC_GET_CURRENT_CONTEXT() \
110   ((pthread_equal(__glcCommonArea.threadID, pthread_self()) && __glcThreadArea) ? \
111     __glcThreadArea->currentContext : __glcGetCurrent())
112 #else
113 #define GLC_GET_CURRENT_CONTEXT() __glcTlsThreadArea.currentContext
114 #endif
115 
116 /* ceil() and floor() macros for 26.6 fixed integers */
117 #define GLC_CEIL_26_6(x) (((x) < 0) ? ((x) & -64) : ((x) + 63) & -64)
118 #define GLC_FLOOR_26_6(x) (((x) < 0) ? (((x) - 63) & -64) : ((x) & -64))
119 
120 typedef struct __GLCdataCodeFromNameRec __GLCdataCodeFromName;
121 typedef struct __GLCgeomBatchRec __GLCgeomBatch;
122 typedef struct __GLCcharacterRec __GLCcharacter;
123 
124 struct __GLCrendererDataRec {
125   GLfloat vector[8];			/* Current coordinates */
126   GLfloat tolerance;			/* Chordal tolerance */
127   __GLCarray* vertexArray;		/* Array of vertices */
128   __GLCarray* controlPoints;		/* Array of control points */
129   __GLCarray* endContour;		/* Array of contour limits */
130   __GLCarray* vertexIndices;		/* Array of vertex indices */
131   __GLCarray* geomBatches;		/* Array of geometric batches */
132   GLfloat* transformMatrix;		/* Transformation matrix from the
133 					   object space to the viewport */
134   GLfloat halfWidth;
135   GLfloat halfHeight;
136 };
137 
138 struct __GLCdataCodeFromNameRec {
139   GLint code;
140   const char* name;
141 };
142 
143 struct __GLCgeomBatchRec {
144   GLenum mode;
145   GLint length;
146   GLuint start;
147   GLuint end;
148 };
149 
150 struct __GLCcharacterRec {
151   GLint code;
152   __GLCfont* font;
153   __GLCglyph* glyph;
154   GLfloat advance[2];
155 };
156 
157 /* Those functions are used to protect against race conditions whenever we try
158  * to access the common area or functions which are not multi-threaded.
159  */
160 void __glcLock(void);
161 void __glcUnlock(void);
162 
163 /* Callback function type that is called by __glcProcessChar().
164  * It allows to unify the character processing before the rendering or the
165  * measurement of a character : __glcProcessChar() is called first (see below)
166  * then the callback function of type __glcProcessCharFunc is called by
167  * __glcProcessChar(). Two functions are defined according to this type :
168  * __glcRenderChar() for rendering and __glcGetCharMetric() for measurement.
169  */
170 typedef void* (*__glcProcessCharFunc)(GLint inCode, GLint inPrevCode,
171 				      GLboolean inIsRTL, __GLCfont* inFont,
172 				      __GLCcontext* inContext,
173 				      void* inProcessCharData,
174 				      GLboolean inMultipleChars);
175 
176 /* Process the character in order to find a font that maps the code and to
177  * render the corresponding glyph. Replacement code or the '\<hexcode>'
178  * character sequence is issued if necessary.
179  * 'inCode' must be given in UCS-4 format
180  */
181 extern void* __glcProcessChar(__GLCcontext *inContext, GLint inCode,
182 			      __GLCcharacter* inPrevCode, GLboolean inIsRTL,
183 			      __glcProcessCharFunc inProcessCharFunc,
184 			      void* inProcessCharData);
185 
186 /* Render scalable characters using either the GLC_LINE style or the
187  * GLC_TRIANGLE style
188  */
189 extern void __glcRenderCharScalable(__GLCfont* inFont, __GLCcontext* inContext,
190 				    GLfloat* inTransformMatrix,
191 				    GLfloat scale_x, GLfloat scale_y,
192 				    __GLCglyph* inGlyph);
193 
194 /* QuesoGLC own memory management routines */
195 extern void* __glcMalloc(size_t size);
196 extern void __glcFree(void* ptr);
197 extern void* __glcRealloc(void* ptr, size_t size);
198 
199 /* Find a token in a list of tokens separated by 'separator' */
200 extern GLCchar8* __glcFindIndexList(GLCchar8* inList, GLuint inIndex,
201 				    const GLCchar8* inSeparator);
202 
203 /* Arrays that contain the Unicode name of characters */
204 extern const __GLCdataCodeFromName __glcCodeFromNameArray[];
205 extern const GLint __glcNameFromCodeArray[];
206 extern const GLint __glcMaxCode;
207 extern const GLint __glcCodeFromNameSize;
208 
209 /* Find a Unicode name from its code */
210 extern const GLCchar8* __glcNameFromCode(GLint code);
211 
212 /* Find a Unicode code from its name */
213 extern GLint __glcCodeFromName(GLCchar8* name);
214 
215 /* Duplicate a string and convert if from any Unicode format to UTF-8 format */
216 extern GLCchar8* __glcConvertToUtf8(const GLCchar* inString,
217 				    const GLint inStringType);
218 
219 /* Duplicate a string to the context buffer and convert it from UTF-8 format to
220  * any Unicode format.
221  */
222 extern GLCchar* __glcConvertFromUtf8ToBuffer(__GLCcontext* This,
223 					     const GLCchar8* inString,
224 					     const GLint inStringType);
225 
226 /* Duplicate a counted string to the context buffer and convert it from any
227  * Unicode format to UTF-8 format.
228  */
229 extern GLCchar8* __glcConvertCountedStringToUtf8(const GLint inCount,
230 						 const GLCchar* inString,
231 						 const GLint inStringType);
232 
233 /* Convert a UCS-4 character code into the current string type. The result is
234  * stored in a GLint. This function is needed since the GLC specs store
235  * individual character codes in GLint whatever is their string type.
236  */
237 extern GLint __glcConvertUcs4ToGLint(__GLCcontext *inContext, GLint inCode);
238 
239 /* Convert a character encoded in the current string type to the UCS-4 format.
240  * This function is needed since the GLC specs store individual character
241  * codes in GLint whatever is their string type.
242  */
243 extern GLint __glcConvertGLintToUcs4(__GLCcontext *inContext, GLint inCode);
244 
245 /* Verify that the thread has a current context and that the master identified
246  * by 'inMaster' exists. Returns a FontConfig pattern corresponding to the
247  * master ID 'inMaster'.
248  */
249 extern __GLCmaster* __glcVerifyMasterParameters(GLint inMaster);
250 
251 /* Verify that the thread has a current context and that the font identified
252  * by 'inFont' exists.
253  */
254 extern __GLCfont* __glcVerifyFontParameters(GLint inFont);
255 
256 /* Do the actual job of glcAppendFont(). This function can be called as an
257  * internal version of glcAppendFont() where the current GLC context is already
258  * determined and the font ID has been resolved in its corresponding __GLCfont
259  * object.
260  */
261 extern void __glcAppendFont(__GLCcontext* inContext, __GLCfont* inFont);
262 
263 /* This internal function deletes the font identified by inFont (if any) and
264  * creates a new font based on the pattern 'inPattern'. The resulting font is
265  * added to the list GLC_FONT_LIST.
266  */
267 extern __GLCfont* __glcNewFontFromMaster(GLint inFontID, __GLCmaster* inMaster,
268 					 __GLCcontext *inContext, GLint inCode);
269 
270 /* This internal function tries to open the face file which name is identified
271  * by 'inFace'. If it succeeds, it closes the previous face and stores the new
272  * face attributes in the __GLCfont object "inFont". Otherwise, it leaves the
273  * font unchanged. GL_TRUE or GL_FALSE are returned to indicate if the function
274  * succeeded or not.
275  */
276 extern GLboolean __glcFontFace(__GLCfont* inFont, const GLCchar8* inFace,
277 			__GLCcontext *inContext);
278 
279 #ifndef HAVE_TLS
280 /* Return a struct which contains thread specific info. If the platform supports
281  * pointers for thread-local storage (TLS) then __glcGetThreadArea is replaced
282  * by a macro that returns a thread-local pointer. Otherwise, a function is
283  * called to return the structure using pthread_get_specific (POSIX) or
284  * TlsGetValue (WIN32) which are much slower.
285  */
286 extern __GLCthreadArea* __glcGetThreadArea(void);
287 #endif
288 
289 /* Raise an error.
290  * See also remarks above about TLS pointers.
291  */
292 #ifdef HAVE_TLS
293 #define __glcRaiseError(inError) \
294 if (!__glcTlsThreadArea.errorState || ! (inError)) \
295   __glcTlsThreadArea.errorState = (inError)
296 #else
297 extern void __glcRaiseError(GLCenum inError);
298 #endif
299 
300 #ifndef HAVE_TLS
301 /* Return the current context state.
302  * See also remarks above about TLS pointers.
303  */
304 extern __GLCcontext* __glcGetCurrent(void);
305 #endif
306 
307 /* Compute an optimal size for the glyph to be rendered on the screen (if no
308  * display list is currently building).
309  */
310 extern void __glcGetScale(__GLCcontext* inContext, GLfloat* outTransformMatrix,
311 			  GLfloat* outScaleX, GLfloat* outScaleY);
312 
313 /* Convert 'inString' (stored in logical order) to UCS4 format and return a
314  * copy of the converted string in visual order.
315  */
316 extern GLCchar32* __glcConvertToVisualUcs4(__GLCcontext* inContext,
317 					   GLboolean *outIsRTL,
318 					   GLint *outLength,
319 					   const GLCchar* inString);
320 
321 /* Convert 'inCount' characters of 'inString' (stored in logical order) to UCS4
322  * format and return a copy of the converted string in visual order.
323  */
324 extern GLCchar32* __glcConvertCountedStringToVisualUcs4(__GLCcontext* inContext,
325 							GLboolean *outIsRTL,
326 							const GLCchar* inString,
327 							const GLint inCount);
328 
329 #ifdef GLC_FT_CACHE
330 /* Callback function used by the FreeType cache manager to open a given face */
331 extern FT_Error __glcFileOpen(FTC_FaceID inFile, FT_Library inLibrary,
332 			      FT_Pointer inData, FT_Face* outFace);
333 
334 /* Rename FTC_Manager_LookupFace for old freetype versions */
335 # if FREETYPE_MAJOR == 2 \
336      && (FREETYPE_MINOR < 1 \
337          || (FREETYPE_MINOR == 1 && FREETYPE_PATCH < 8))
338 #   define FTC_Manager_LookupFace FTC_Manager_Lookup_Face
339 # endif
340 #endif
341 
342 /* Save the GL State in a structure */
343 extern void __glcSaveGLState(__GLCglState* inGLState, __GLCcontext* inContext,
344 			     GLboolean inAll);
345 
346 /* Restore the GL State from a structure */
347 extern void __glcRestoreGLState(__GLCglState* inGLState,
348 				__GLCcontext* inContext, GLboolean inAll);
349 
350 /* Function for GLEW so that it can get a context */
351 GLEWAPI GLEWContext* glewGetContext(void);
352 
353 #ifndef HAVE_TLS
354 /* This function initializes the thread management of QuesoGLC when TLS is not
355  * available. It must be called once (see the macro GLC_INIT_THREAD)
356  */
357 extern void __glcInitThread(void);
358 #endif
359 
360 extern int __glcdeCasteljauConic(void *inUserData);
361 extern int __glcdeCasteljauCubic(void *inUserData);
362 #endif /* __glc_internal_h */
363