]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - QRScanner/mobile/jni/thirdparty/freetype/src/pcf/pcfdrivr.c
Add MuPDF native source codes
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / jni / thirdparty / freetype / src / pcf / pcfdrivr.c
1 /*  pcfdrivr.c
2
3     FreeType font driver for pcf files
4
5     Copyright (C) 2000-2004, 2006-2011 by
6     Francesco Zappa Nardelli
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 */
26
27
28 #include <ft2build.h>
29
30 #include FT_INTERNAL_DEBUG_H
31 #include FT_INTERNAL_STREAM_H
32 #include FT_INTERNAL_OBJECTS_H
33 #include FT_GZIP_H
34 #include FT_LZW_H
35 #include FT_BZIP2_H
36 #include FT_ERRORS_H
37 #include FT_BDF_H
38 #include FT_TRUETYPE_IDS_H
39
40 #include "pcf.h"
41 #include "pcfdrivr.h"
42 #include "pcfread.h"
43
44 #include "pcferror.h"
45 #include "pcfutil.h"
46
47 #undef  FT_COMPONENT
48 #define FT_COMPONENT  trace_pcfread
49
50 #include FT_SERVICE_BDF_H
51 #include FT_SERVICE_XFREE86_NAME_H
52
53
54   /*************************************************************************/
55   /*                                                                       */
56   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
57   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
58   /* messages during execution.                                            */
59   /*                                                                       */
60 #undef  FT_COMPONENT
61 #define FT_COMPONENT  trace_pcfdriver
62
63
64   typedef struct  PCF_CMapRec_
65   {
66     FT_CMapRec    root;
67     FT_UInt       num_encodings;
68     PCF_Encoding  encodings;
69
70   } PCF_CMapRec, *PCF_CMap;
71
72
73   FT_CALLBACK_DEF( FT_Error )
74   pcf_cmap_init( FT_CMap     pcfcmap,   /* PCF_CMap */
75                  FT_Pointer  init_data )
76   {
77     PCF_CMap  cmap = (PCF_CMap)pcfcmap;
78     PCF_Face  face = (PCF_Face)FT_CMAP_FACE( pcfcmap );
79
80     FT_UNUSED( init_data );
81
82
83     cmap->num_encodings = (FT_UInt)face->nencodings;
84     cmap->encodings     = face->encodings;
85
86     return PCF_Err_Ok;
87   }
88
89
90   FT_CALLBACK_DEF( void )
91   pcf_cmap_done( FT_CMap  pcfcmap )         /* PCF_CMap */
92   {
93     PCF_CMap  cmap = (PCF_CMap)pcfcmap;
94
95
96     cmap->encodings     = NULL;
97     cmap->num_encodings = 0;
98   }
99
100
101   FT_CALLBACK_DEF( FT_UInt )
102   pcf_cmap_char_index( FT_CMap    pcfcmap,  /* PCF_CMap */
103                        FT_UInt32  charcode )
104   {
105     PCF_CMap      cmap      = (PCF_CMap)pcfcmap;
106     PCF_Encoding  encodings = cmap->encodings;
107     FT_UInt       min, max, mid;
108     FT_UInt       result    = 0;
109
110
111     min = 0;
112     max = cmap->num_encodings;
113
114     while ( min < max )
115     {
116       FT_ULong  code;
117
118
119       mid  = ( min + max ) >> 1;
120       code = encodings[mid].enc;
121
122       if ( charcode == code )
123       {
124         result = encodings[mid].glyph + 1;
125         break;
126       }
127
128       if ( charcode < code )
129         max = mid;
130       else
131         min = mid + 1;
132     }
133
134     return result;
135   }
136
137
138   FT_CALLBACK_DEF( FT_UInt )
139   pcf_cmap_char_next( FT_CMap    pcfcmap,   /* PCF_CMap */
140                       FT_UInt32  *acharcode )
141   {
142     PCF_CMap      cmap      = (PCF_CMap)pcfcmap;
143     PCF_Encoding  encodings = cmap->encodings;
144     FT_UInt       min, max, mid;
145     FT_ULong      charcode  = *acharcode + 1;
146     FT_UInt       result    = 0;
147
148
149     min = 0;
150     max = cmap->num_encodings;
151
152     while ( min < max )
153     {
154       FT_ULong  code;
155
156
157       mid  = ( min + max ) >> 1;
158       code = encodings[mid].enc;
159
160       if ( charcode == code )
161       {
162         result = encodings[mid].glyph + 1;
163         goto Exit;
164       }
165
166       if ( charcode < code )
167         max = mid;
168       else
169         min = mid + 1;
170     }
171
172     charcode = 0;
173     if ( min < cmap->num_encodings )
174     {
175       charcode = encodings[min].enc;
176       result   = encodings[min].glyph + 1;
177     }
178
179   Exit:
180     if ( charcode > 0xFFFFFFFFUL )
181     {
182       FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));
183       *acharcode = 0;
184       /* XXX: result should be changed to indicate an overflow error */
185     }
186     else
187       *acharcode = (FT_UInt32)charcode;
188     return result;
189   }
190
191
192   FT_CALLBACK_TABLE_DEF
193   const FT_CMap_ClassRec  pcf_cmap_class =
194   {
195     sizeof ( PCF_CMapRec ),
196     pcf_cmap_init,
197     pcf_cmap_done,
198     pcf_cmap_char_index,
199     pcf_cmap_char_next,
200
201     NULL, NULL, NULL, NULL, NULL
202   };
203
204
205   FT_CALLBACK_DEF( void )
206   PCF_Face_Done( FT_Face  pcfface )         /* PCF_Face */
207   {
208     PCF_Face   face = (PCF_Face)pcfface;
209     FT_Memory  memory;
210
211
212     if ( !face )
213       return;
214
215     memory = FT_FACE_MEMORY( face );
216
217     FT_FREE( face->encodings );
218     FT_FREE( face->metrics );
219
220     /* free properties */
221     {
222       PCF_Property  prop;
223       FT_Int        i;
224
225
226       if ( face->properties )
227       {
228         for ( i = 0; i < face->nprops; i++ )
229         {
230           prop = &face->properties[i];
231
232           if ( prop )
233           {
234             FT_FREE( prop->name );
235             if ( prop->isString )
236               FT_FREE( prop->value.atom );
237           }
238         }
239       }
240       FT_FREE( face->properties );
241     }
242
243     FT_FREE( face->toc.tables );
244     FT_FREE( pcfface->family_name );
245     FT_FREE( pcfface->style_name );
246     FT_FREE( pcfface->available_sizes );
247     FT_FREE( face->charset_encoding );
248     FT_FREE( face->charset_registry );
249
250     /* close compressed stream if any */
251     if ( pcfface->stream == &face->comp_stream )
252     {
253       FT_Stream_Close( &face->comp_stream );
254       pcfface->stream = face->comp_source;
255     }
256   }
257
258
259   FT_CALLBACK_DEF( FT_Error )
260   PCF_Face_Init( FT_Stream      stream,
261                  FT_Face        pcfface,        /* PCF_Face */
262                  FT_Int         face_index,
263                  FT_Int         num_params,
264                  FT_Parameter*  params )
265   {
266     PCF_Face  face  = (PCF_Face)pcfface;
267     FT_Error  error = PCF_Err_Ok;
268
269     FT_UNUSED( num_params );
270     FT_UNUSED( params );
271     FT_UNUSED( face_index );
272
273
274     FT_TRACE2(( "PCF driver\n" ));
275
276     error = pcf_load_font( stream, face );
277     if ( error )
278     {
279       PCF_Face_Done( pcfface );
280
281 #if defined( FT_CONFIG_OPTION_USE_ZLIB )  || \
282     defined( FT_CONFIG_OPTION_USE_LZW )   || \
283     defined( FT_CONFIG_OPTION_USE_BZIP2 )
284
285 #ifdef FT_CONFIG_OPTION_USE_ZLIB
286       {
287         FT_Error  error2;
288
289
290         /* this didn't work, try gzip support! */
291         error2 = FT_Stream_OpenGzip( &face->comp_stream, stream );
292         if ( FT_ERROR_BASE( error2 ) == FT_Err_Unimplemented_Feature )
293           goto Fail;
294
295         error = error2;
296       }
297 #endif /* FT_CONFIG_OPTION_USE_ZLIB */
298
299 #ifdef FT_CONFIG_OPTION_USE_LZW
300       if ( error )
301       {
302         FT_Error  error3;
303
304
305         /* this didn't work, try LZW support! */
306         error3 = FT_Stream_OpenLZW( &face->comp_stream, stream );
307         if ( FT_ERROR_BASE( error3 ) == FT_Err_Unimplemented_Feature )
308           goto Fail;
309
310         error = error3;
311       }
312 #endif /* FT_CONFIG_OPTION_USE_LZW */
313
314 #ifdef FT_CONFIG_OPTION_USE_BZIP2
315       if ( error )
316       {
317         FT_Error  error4;
318
319
320         /* this didn't work, try Bzip2 support! */
321         error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream );
322         if ( FT_ERROR_BASE( error4 ) == FT_Err_Unimplemented_Feature )
323           goto Fail;
324
325         error = error4;
326       }
327 #endif /* FT_CONFIG_OPTION_USE_BZIP2 */
328
329       if ( error )
330         goto Fail;
331
332       face->comp_source = stream;
333       pcfface->stream   = &face->comp_stream;
334
335       stream = pcfface->stream;
336
337       error = pcf_load_font( stream, face );
338       if ( error )
339         goto Fail;
340
341 #else /* !(FT_CONFIG_OPTION_USE_ZLIB ||
342            FT_CONFIG_OPTION_USE_LZW ||
343            FT_CONFIG_OPTION_USE_BZIP2) */
344
345       goto Fail;
346
347 #endif
348     }
349
350     /* set up charmap */
351     {
352       FT_String  *charset_registry = face->charset_registry;
353       FT_String  *charset_encoding = face->charset_encoding;
354       FT_Bool     unicode_charmap  = 0;
355
356
357       if ( charset_registry && charset_encoding )
358       {
359         char*  s = charset_registry;
360
361
362         /* Uh, oh, compare first letters manually to avoid dependency
363            on locales. */
364         if ( ( s[0] == 'i' || s[0] == 'I' ) &&
365              ( s[1] == 's' || s[1] == 'S' ) &&
366              ( s[2] == 'o' || s[2] == 'O' ) )
367         {
368           s += 3;
369           if ( !ft_strcmp( s, "10646" )                      ||
370                ( !ft_strcmp( s, "8859" ) &&
371                  !ft_strcmp( face->charset_encoding, "1" ) ) )
372           unicode_charmap = 1;
373         }
374       }
375
376       {
377         FT_CharMapRec  charmap;
378
379
380         charmap.face        = FT_FACE( face );
381         charmap.encoding    = FT_ENCODING_NONE;
382         /* initial platform/encoding should indicate unset status? */
383         charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
384         charmap.encoding_id = TT_APPLE_ID_DEFAULT;
385
386         if ( unicode_charmap )
387         {
388           charmap.encoding    = FT_ENCODING_UNICODE;
389           charmap.platform_id = TT_PLATFORM_MICROSOFT;
390           charmap.encoding_id = TT_MS_ID_UNICODE_CS;
391         }
392
393         error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );
394
395 #if 0
396         /* Select default charmap */
397         if ( pcfface->num_charmaps )
398           pcfface->charmap = pcfface->charmaps[0];
399 #endif
400       }
401     }
402
403   Exit:
404     return error;
405
406   Fail:
407     FT_TRACE2(( "  not a PCF file\n" ));
408     PCF_Face_Done( pcfface );
409     error = PCF_Err_Unknown_File_Format;  /* error */
410     goto Exit;
411   }
412
413
414   FT_CALLBACK_DEF( FT_Error )
415   PCF_Size_Select( FT_Size   size,
416                    FT_ULong  strike_index )
417   {
418     PCF_Accel  accel = &( (PCF_Face)size->face )->accel;
419
420
421     FT_Select_Metrics( size->face, strike_index );
422
423     size->metrics.ascender    =  accel->fontAscent << 6;
424     size->metrics.descender   = -accel->fontDescent << 6;
425     size->metrics.max_advance =  accel->maxbounds.characterWidth << 6;
426
427     return PCF_Err_Ok;
428   }
429
430
431   FT_CALLBACK_DEF( FT_Error )
432   PCF_Size_Request( FT_Size          size,
433                     FT_Size_Request  req )
434   {
435     PCF_Face         face  = (PCF_Face)size->face;
436     FT_Bitmap_Size*  bsize = size->face->available_sizes;
437     FT_Error         error = PCF_Err_Invalid_Pixel_Size;
438     FT_Long          height;
439
440
441     height = FT_REQUEST_HEIGHT( req );
442     height = ( height + 32 ) >> 6;
443
444     switch ( req->type )
445     {
446     case FT_SIZE_REQUEST_TYPE_NOMINAL:
447       if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
448         error = PCF_Err_Ok;
449       break;
450
451     case FT_SIZE_REQUEST_TYPE_REAL_DIM:
452       if ( height == ( face->accel.fontAscent +
453                        face->accel.fontDescent ) )
454         error = PCF_Err_Ok;
455       break;
456
457     default:
458       error = PCF_Err_Unimplemented_Feature;
459       break;
460     }
461
462     if ( error )
463       return error;
464     else
465       return PCF_Size_Select( size, 0 );
466   }
467
468
469   FT_CALLBACK_DEF( FT_Error )
470   PCF_Glyph_Load( FT_GlyphSlot  slot,
471                   FT_Size       size,
472                   FT_UInt       glyph_index,
473                   FT_Int32      load_flags )
474   {
475     PCF_Face    face   = (PCF_Face)FT_SIZE_FACE( size );
476     FT_Stream   stream;
477     FT_Error    error  = PCF_Err_Ok;
478     FT_Bitmap*  bitmap = &slot->bitmap;
479     PCF_Metric  metric;
480     FT_Offset   bytes;
481
482     FT_UNUSED( load_flags );
483
484
485     FT_TRACE4(( "load_glyph %d ---", glyph_index ));
486
487     if ( !face || glyph_index >= (FT_UInt)face->root.num_glyphs )
488     {
489       error = PCF_Err_Invalid_Argument;
490       goto Exit;
491     }
492
493     stream = face->root.stream;
494
495     if ( glyph_index > 0 )
496       glyph_index--;
497
498     metric = face->metrics + glyph_index;
499
500     bitmap->rows       = metric->ascent + metric->descent;
501     bitmap->width      = metric->rightSideBearing - metric->leftSideBearing;
502     bitmap->num_grays  = 1;
503     bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
504
505     FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
506                   PCF_BIT_ORDER( face->bitmapsFormat ),
507                   PCF_BYTE_ORDER( face->bitmapsFormat ),
508                   PCF_GLYPH_PAD( face->bitmapsFormat ) ));
509
510     switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
511     {
512     case 1:
513       bitmap->pitch = ( bitmap->width + 7 ) >> 3;
514       break;
515
516     case 2:
517       bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
518       break;
519
520     case 4:
521       bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
522       break;
523
524     case 8:
525       bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3;
526       break;
527
528     default:
529       return PCF_Err_Invalid_File_Format;
530     }
531
532     /* XXX: to do: are there cases that need repadding the bitmap? */
533     bytes = bitmap->pitch * bitmap->rows;
534
535     error = ft_glyphslot_alloc_bitmap( slot, bytes );
536     if ( error )
537       goto Exit;
538
539     if ( FT_STREAM_SEEK( metric->bits )          ||
540          FT_STREAM_READ( bitmap->buffer, bytes ) )
541       goto Exit;
542
543     if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
544       BitOrderInvert( bitmap->buffer, bytes );
545
546     if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) !=
547            PCF_BIT_ORDER( face->bitmapsFormat )  ) )
548     {
549       switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
550       {
551       case 1:
552         break;
553
554       case 2:
555         TwoByteSwap( bitmap->buffer, bytes );
556         break;
557
558       case 4:
559         FourByteSwap( bitmap->buffer, bytes );
560         break;
561       }
562     }
563
564     slot->format      = FT_GLYPH_FORMAT_BITMAP;
565     slot->bitmap_left = metric->leftSideBearing;
566     slot->bitmap_top  = metric->ascent;
567
568     slot->metrics.horiAdvance  = metric->characterWidth << 6;
569     slot->metrics.horiBearingX = metric->leftSideBearing << 6;
570     slot->metrics.horiBearingY = metric->ascent << 6;
571     slot->metrics.width        = ( metric->rightSideBearing -
572                                    metric->leftSideBearing ) << 6;
573     slot->metrics.height       = bitmap->rows << 6;
574
575     ft_synthesize_vertical_metrics( &slot->metrics,
576                                     ( face->accel.fontAscent +
577                                       face->accel.fontDescent ) << 6 );
578
579     FT_TRACE4(( " --- ok\n" ));
580
581   Exit:
582     return error;
583   }
584
585
586  /*
587   *
588   *  BDF SERVICE
589   *
590   */
591
592   static FT_Error
593   pcf_get_bdf_property( PCF_Face          face,
594                         const char*       prop_name,
595                         BDF_PropertyRec  *aproperty )
596   {
597     PCF_Property  prop;
598
599
600     prop = pcf_find_property( face, prop_name );
601     if ( prop != NULL )
602     {
603       if ( prop->isString )
604       {
605         aproperty->type   = BDF_PROPERTY_TYPE_ATOM;
606         aproperty->u.atom = prop->value.atom;
607       }
608       else
609       {
610         if ( prop->value.l > 0x7FFFFFFFL || prop->value.l < ( -1 - 0x7FFFFFFFL ) )
611         {
612           FT_TRACE1(( "pcf_get_bdf_property: " ));
613           FT_TRACE1(( "too large integer 0x%x is truncated\n" ));
614         }
615         /* Apparently, the PCF driver loads all properties as signed integers!
616          * This really doesn't seem to be a problem, because this is
617          * sufficient for any meaningful values.
618          */
619         aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;
620         aproperty->u.integer = (FT_Int32)prop->value.l;
621       }
622       return 0;
623     }
624
625     return PCF_Err_Invalid_Argument;
626   }
627
628
629   static FT_Error
630   pcf_get_charset_id( PCF_Face      face,
631                       const char*  *acharset_encoding,
632                       const char*  *acharset_registry )
633   {
634     *acharset_encoding = face->charset_encoding;
635     *acharset_registry = face->charset_registry;
636
637     return 0;
638   }
639
640
641   static const FT_Service_BDFRec  pcf_service_bdf =
642   {
643     (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,
644     (FT_BDF_GetPropertyFunc) pcf_get_bdf_property
645   };
646
647
648  /*
649   *
650   *  SERVICE LIST
651   *
652   */
653
654   static const FT_ServiceDescRec  pcf_services[] =
655   {
656     { FT_SERVICE_ID_BDF,       &pcf_service_bdf },
657     { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF },
658     { NULL, NULL }
659   };
660
661
662   FT_CALLBACK_DEF( FT_Module_Interface )
663   pcf_driver_requester( FT_Module    module,
664                         const char*  name )
665   {
666     FT_UNUSED( module );
667
668     return ft_service_list_lookup( pcf_services, name );
669   }
670
671
672   FT_CALLBACK_TABLE_DEF
673   const FT_Driver_ClassRec  pcf_driver_class =
674   {
675     {
676       FT_MODULE_FONT_DRIVER        |
677       FT_MODULE_DRIVER_NO_OUTLINES,
678       sizeof ( FT_DriverRec ),
679
680       "pcf",
681       0x10000L,
682       0x20000L,
683
684       0,
685
686       0,                    /* FT_Module_Constructor */
687       0,                    /* FT_Module_Destructor  */
688       pcf_driver_requester
689     },
690
691     sizeof ( PCF_FaceRec ),
692     sizeof ( FT_SizeRec ),
693     sizeof ( FT_GlyphSlotRec ),
694
695     PCF_Face_Init,
696     PCF_Face_Done,
697     0,                      /* FT_Size_InitFunc */
698     0,                      /* FT_Size_DoneFunc */
699     0,                      /* FT_Slot_InitFunc */
700     0,                      /* FT_Slot_DoneFunc */
701
702 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
703     ft_stub_set_char_sizes,
704     ft_stub_set_pixel_sizes,
705 #endif
706     PCF_Glyph_Load,
707
708     0,                      /* FT_Face_GetKerningFunc  */
709     0,                      /* FT_Face_AttachFunc      */
710     0,                      /* FT_Face_GetAdvancesFunc */
711
712     PCF_Size_Request,
713     PCF_Size_Select
714   };
715
716
717 /* END */