Skip to content
Newer
Older
100644 375 lines (307 sloc) 11.2 KB
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
797c555 @mgdm Happy new year
mgdm authored Apr 19, 2011
5 | Copyright (c) 1997-2011 The PHP Group |
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Elizabeth Smith <auroraeosrose@php.net> |
16 | Michael Maclean <mgdm@php.net> |
17 | Akshat Gupta <g.akshat@gmail.com> |
18 +----------------------------------------------------------------------+
19 */
20
21 /* $Id$ */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <cairo.h>
28 #include "php.h"
29 #include "php_cairo.h"
30 #include "zend_exceptions.h"
31
32 #if defined(CAIRO_HAS_FT_FONT) && defined(HAVE_FREETYPE)
33 #include <fontconfig/fontconfig.h>
34 #include <ft2build.h>
35 #include FT_FREETYPE_H
36 #include <cairo/cairo-ft.h>
37
38 zend_class_entry *cairo_ce_cairoftfont;
39
40 ZEND_BEGIN_ARG_INFO_EX(CairoFtFontFace_construct_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 1)
41 ZEND_ARG_INFO(0, face)
42 ZEND_ARG_INFO(0, load_flags)
43 ZEND_END_ARG_INFO()
44
45
46 /* Functions for stream handling */
47 static unsigned long php_cairo_ft_read_func(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) {
48 stream_closure *closure;
49 #ifdef ZTS
50 TSRMLS_D;
51 #endif
52
53 closure = (stream_closure *)stream->descriptor.pointer;
54 #ifdef ZTS
55 TSRMLS_C = closure->TSRMLS_C;
56 #endif
57 php_stream_seek(closure->stream, offset, SEEK_SET);
58 return php_stream_read(closure->stream, (char *)buffer, count);
59 }
60
61 void php_cairo_ft_close_stream(FT_Stream stream)
62 {
63 #ifdef ZTS
64 TSRMLS_D;
65 #endif
66
67 stream_closure *closure;
68
69 closure = (stream_closure *)stream->descriptor.pointer;
70 #ifdef ZTS
71 TSRMLS_C = closure->TSRMLS_C;
72 #endif
73 /* Don't close the stream unless we created it */
74 if(closure->owned_stream) {
75 php_stream_close((php_stream *)closure->stream);
76 }
77 efree(closure);
78 efree(stream);
79 }
80
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
81 static zend_bool php_cairo_create_ft_font_face(cairo_ft_font_face_object *font_face_object, php_stream *stream, zend_bool owned_stream, int load_flags, zend_bool throw_exceptions TSRMLS_DC) {
82 FT_Library *ft_lib;
83 FT_Stream ft_stream;
84 FT_Face face;
85 stream_closure *closure;
86 php_stream_statbuf ssbuf;
87 FT_Open_Args open_args;
88 int error;
89
20c6a1e @auroraeosrose Fix for issue #1 - stat stream
auroraeosrose authored Aug 8, 2012
90 if (php_stream_stat(stream,&ssbuf) < 0) {
91 return 1;
92 }
93
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
94 ft_lib = &CAIROG(ft_lib);
95 font_face_object->ft_face = NULL;
96 font_face_object->ft_stream = NULL;
97
98 closure = ecalloc(1, sizeof(stream_closure));
99 closure->stream = stream;
100 closure->owned_stream = owned_stream;
101 #ifdef ZTS
102 closure->TSRMLS_C = TSRMLS_C;
103 #endif
104
105 ft_stream = ecalloc(1, sizeof(*ft_stream));
106 ft_stream->descriptor.pointer = (void *)closure;
107 ft_stream->pos = php_stream_tell(stream);
108 ft_stream->size = ssbuf.sb.st_size;
109 ft_stream->read = php_cairo_ft_read_func;
110 /* ft_stream->close = php_cairo_ft_close_stream; */
111 open_args.flags = FT_OPEN_STREAM;
112 open_args.stream = ft_stream;
113
114 error = FT_Open_Face(*ft_lib, &open_args, 0, &face);
115
116 if (error) {
117 if (owned_stream) {
118 php_stream_close(stream);
119 }
120 efree(closure);
121 efree(ft_stream);
122
123 return error;
124 }
125
126 font_face_object->ft_stream = ft_stream;
127 font_face_object->font_face = (cairo_font_face_t *)cairo_ft_font_face_create_for_ft_face(face, (int)load_flags);
128
129 /* Set Cairo to automatically destroy the FT_Face when the cairo_font_face_t is destroyed */
130 error = cairo_font_face_set_user_data (
131 font_face_object->font_face,
132 &font_face_object->key,
133 face,
134 (cairo_destroy_func_t) FT_Done_Face);
135
136 if (error) {
137 cairo_font_face_destroy (font_face_object->font_face);
138 FT_Done_Face(face);
139 return error;
140 }
141
142 return 0;
143 }
144
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
145 /* {{{ proto CairoFtFontFace cairo_ft_font_face_create(string face, long load_flags)
146 Creates a new font face for the FreeType font backend from a pre-opened FreeType face. */
147
148 /* FIXME: Adapt this to use streams, to handle open_basedir etc */
149 PHP_FUNCTION(cairo_ft_font_face_create)
150 {
151 FT_Library *ft_lib;
152 long load_flags = 0;
153 int error = 0;
154 zval *stream_zval = NULL;
155 cairo_ft_font_face_object *font_face_object;
156
157 php_stream *stream;
158 php_stream_statbuf ssbuf;
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
159 zend_bool owned_stream = 0;
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
160
161 PHP_CAIRO_ERROR_HANDLING(FALSE)
162 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l",
163 &stream_zval, &load_flags) == FAILURE)
164 {
165 PHP_CAIRO_RESTORE_ERRORS(FALSE)
166 return;
167 }
168 PHP_CAIRO_RESTORE_ERRORS(FALSE)
169
170 ft_lib = &CAIROG(ft_lib);
171 if(*ft_lib == NULL) {
172 error = FT_Init_FreeType(ft_lib);
173 if(error) {
174 zend_error(E_WARNING, "Failed to initialize the Freetype library");
175 return;
176 }
177 }
178
179 if(Z_TYPE_P(stream_zval) == IS_STRING) {
180 stream = php_stream_open_wrapper(Z_STRVAL_P(stream_zval), "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
181 owned_stream = 1;
182 } else if(Z_TYPE_P(stream_zval) == IS_RESOURCE) {
183 php_stream_from_zval(stream, &stream_zval);
184 } else {
185 zend_error(E_WARNING, "cairo_ft_font_face_create expects parameter 1 to be a string or a stream resource");
186 return;
187 }
188
189 if(!stream) {
190 return;
191 }
192
193 if(php_stream_stat(stream, &ssbuf) != 0) {
167f440 @mgdm Make FreeType error handling give sensible error descriptions
mgdm authored Dec 28, 2011
194 zend_error(E_WARNING, "cairo_ft_font_face_create(): Cannot determine size of stream");
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
195 if(owned_stream) {
196 php_stream_close(stream);
197 }
198 return;
199 }
200
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
201 object_init_ex(return_value, cairo_ce_cairoftfont);
202 font_face_object = (cairo_ft_font_face_object *)zend_object_store_get_object(return_value TSRMLS_CC);
203 error = php_cairo_create_ft_font_face(font_face_object, stream, owned_stream, load_flags, 0 TSRMLS_CC);
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
204
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
205 if (error) {
167f440 @mgdm Make FreeType error handling give sensible error descriptions
mgdm authored Dec 28, 2011
206 char *err_string = php_cairo_get_ft_error(error TSRMLS_CC);
207 zend_error(E_WARNING, "cairo_ft_font_face_create(): An error occurred opening the file: %s", err_string);
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
208 RETURN_NULL();
167f440 @mgdm Make FreeType error handling give sensible error descriptions
mgdm authored Dec 28, 2011
209 }
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
210
211 PHP_CAIRO_ERROR(cairo_font_face_status(font_face_object->font_face));
212 }
213
214 /* }}} */
215
216
217 /* {{{ proto CairoFtFontFace::__construct(string fontFilename, long load_flags)
218 Creates a new font face for the FreeType font backend from a pre-opened FreeType face. */
219
220 /* FIXME: Adapt this to use streams, to handle open_basedir etc */
221 PHP_METHOD(CairoFtFontFace, __construct)
222 {
223 FT_Library *ft_lib;
224 long load_flags = 0;
225 int error = 0;
226 zval *stream_zval = NULL;
227 cairo_ft_font_face_object *font_face_object;
228
229 php_stream *stream;
230 zend_bool owned_stream = 0;
231 php_stream_statbuf ssbuf;
232
233 PHP_CAIRO_ERROR_HANDLING(TRUE)
234 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l",
235 &stream_zval, &load_flags) == FAILURE)
236 {
237 PHP_CAIRO_RESTORE_ERRORS(TRUE)
238 return;
239 }
240
241 ft_lib = &CAIROG(ft_lib);
242 if(*ft_lib == NULL) {
243 error = FT_Init_FreeType(ft_lib);
244 if(error) {
245 PHP_CAIRO_RESTORE_ERRORS(TRUE)
246 zend_throw_exception(cairo_ce_cairoexception, "Failed to initalise FreeType library", 0 TSRMLS_CC);
247 return;
248 }
249 }
250
251 if(Z_TYPE_P(stream_zval) == IS_STRING) {
252 stream = php_stream_open_wrapper(Z_STRVAL_P(stream_zval), "rb", REPORT_ERRORS|ENFORCE_SAFE_MODE, NULL);
253 owned_stream = 1;
254 } else if(Z_TYPE_P(stream_zval) == IS_RESOURCE) {
255 php_stream_from_zval(stream, &stream_zval);
256 } else {
257 PHP_CAIRO_RESTORE_ERRORS(TRUE)
258 zend_throw_exception(cairo_ce_cairoexception, "CairoFtFontFace::__construct() expects parameter 1 to be a string or a stream resource", 0 TSRMLS_CC);
259 return;
260 }
261 PHP_CAIRO_RESTORE_ERRORS(TRUE)
262
263 if(!stream) {
264 /* If there isn't a stream, the exception should already have been thrown
265 by php_stream_open_wrapper, so just bail */
266 return;
267 }
268
269
270 if(php_stream_stat(stream, &ssbuf) != 0) {
271 zend_throw_exception(cairo_ce_cairoexception, "Cannot determine size of stream", 0 TSRMLS_CC);
272 return;
273 }
274
275 font_face_object = (cairo_ft_font_face_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
8052e8c @mgdm Fix memory management in FreeType fonts. Get Cairo to handle the life…
mgdm authored Aug 13, 2011
276 error = php_cairo_create_ft_font_face(font_face_object, stream, owned_stream, load_flags, 1 TSRMLS_CC);
277
278 if (error) {
279 if (error == FT_Err_Unknown_File_Format) {
280 zend_throw_exception(cairo_ce_cairoexception, "CairoFtFontFace::__construct(): unknown file format", error TSRMLS_CC);
281 return;
282 } else {
283 zend_throw_exception(cairo_ce_cairoexception, "CairoFtFontFace::__construct(): An error occurred opening the file", error TSRMLS_CC);
284 return;
285 }
286 }
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
287
288 php_cairo_throw_exception(cairo_font_face_status(font_face_object->font_face) TSRMLS_CC);
289 }
290
291 /* }}} */
292
293 /* {{{ cairo_ft_font_methods */
294 const zend_function_entry cairo_ft_font_methods[] = {
295 PHP_ME(CairoFtFontFace, __construct, CairoFtFontFace_construct_args, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
296 {NULL, NULL, NULL}
297 };
298 /* }}} */
299
300
301 /* {{{ cairo_ft_font_face_object_destroy
302 */
303 static void cairo_ft_font_face_object_destroy(void *object TSRMLS_DC)
304 {
305 stream_closure *closure;
306 cairo_ft_font_face_object *font_face = (cairo_ft_font_face_object *)object;
307 zend_hash_destroy(font_face->std.properties);
308 FREE_HASHTABLE(font_face->std.properties);
309 if(font_face->font_face){
310 cairo_font_face_destroy(font_face->font_face);
311 }
312
313 if(font_face->ft_stream != NULL) {
314 closure = (stream_closure *)font_face->ft_stream->descriptor.pointer;
315 php_stream_close(closure->stream);
316 efree(closure);
317 efree(font_face->ft_stream);
318 }
319
320 efree(object);
321 }
322
323 /* }}} */
324
325 /* {{{ cairo_ft_font_face_object_new
326 */
327 zend_object_value cairo_ft_font_face_object_new(zend_class_entry *ce TSRMLS_DC)
328 {
329 zend_object_value retval;
330 cairo_ft_font_face_object *font_face;
331 zval *temp;
332
333 font_face = ecalloc(1, sizeof(cairo_ft_font_face_object));
334 font_face->ft_stream = NULL;
335
336 font_face->std.ce = ce;
337
338 ALLOC_HASHTABLE(font_face->std.properties);
339 zend_hash_init(font_face->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
3b35211 @mahcuz Use object_properties_init() instead of zend_hash_copy()
mahcuz authored Jun 1, 2010
340 #if PHP_VERSION_ID < 50399
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
341 zend_hash_copy(font_face->std.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &temp, sizeof(zval *));
3b35211 @mahcuz Use object_properties_init() instead of zend_hash_copy()
mahcuz authored Jun 1, 2010
342 #else
343 object_properties_init(&font_face->std, ce);
344 #endif
8a15711 @mgdm Merge Freetype features in from the branch
mgdm authored Feb 3, 2010
345 retval.handle = zend_objects_store_put(font_face, NULL, (zend_objects_free_object_storage_t)cairo_ft_font_face_object_destroy, NULL TSRMLS_CC);
346 retval.handlers = zend_get_std_object_handlers();
347 return retval;
348 }
349
350 /* }}} */
351
352
353 /* {{{ PHP_MINIT_FUNCTION */
354 PHP_MINIT_FUNCTION(cairo_ft_font)
355 {
356 zend_class_entry ftfont_ce;
357
358 INIT_CLASS_ENTRY(ftfont_ce, "CairoFtFontFace", cairo_ft_font_methods);
359 cairo_ce_cairoftfont = zend_register_internal_class_ex(&ftfont_ce, cairo_ce_cairofontface, "CairoFontFace" TSRMLS_CC);
360 cairo_ce_cairoftfont->create_object = cairo_ft_font_face_object_new;
361
362 return SUCCESS;
363 }
364
365 #endif
366
367 /*
368 * Local variables:
369 * tab-width: 4
370 * c-basic-offset: 4
371 * End:
372 * vim600: noet sw=4 ts=4 fdm=marker
373 * vim<600: noet sw=4 ts=4
374 */
Something went wrong with that request. Please try again.